[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC] peripheral/register/bitfield objects - new MCU mo
From: |
Peter Crosthwaite |
Subject: |
Re: [Qemu-devel] [RFC] peripheral/register/bitfield objects - new MCU model |
Date: |
Wed, 8 Jul 2015 13:22:30 -0700 |
On Wed, Jul 8, 2015 at 1:14 PM, Liviu Ionescu <address@hidden> wrote:
> as anyone who did it knows, describing memory mapped peripherals is tedious.
> as far as I know, qemu support ends at defining memory regions and
> implementing the read/write callbacks for all accesses in this region.
>
> while implementing several Cortex-M devices (currently STM32F103, F107, F407,
> F429 are functional for blinky projects), I experimented with some solutions
> to automate this.
>
> the model that I stopped at uses a hierarchy of objects that goes down to
> register bitfield level (peripheral/register/bitfield).
>
> the central object in this hierarchy is the peripheral register, which holds
> a value (up to 64-bits), and its content is automatically retrieved/updated
> by read/writes, based on accurate vendor bitmasks.
>
> in addition, each register may have two user actions defined, a pre-read
> action, to load the register with an external value, and a post-write action,
> to forward the value to an external device, or to implement register
> interdependencies.
>
I have an RFC on list for something very similar, if you want to weigh
in or find it useful, let me know! This is a real problem.
https://lists.nongnu.org/archive/html/qemu-devel/2015-04/msg03612.html
Regards,
Peter
> these actions are obviously user functions, registered as callbacks.
>
> the other objects, the peripheral and bitfield, are more or less helpers.
>
> the bitfield is a simple object, that stores a mask and a shift value, to
> retrieve a bitfield value; it is always a register child.
>
> the peripheral is more or less a container of registers; it implements the
> logic to forward read/writes to the appropriate register.
>
> registers and bitfields are defined with arrays of Info structures; special
> functions traverse these structures and create the objects.
>
> an example of a read only 32-bit word register:
>
> {
> .desc = "Port input data register (GPIOx_IDR)",
> .name = "idr",
> .offset_bytes = 0x08,
> .reset_value = 0x00000000,
> .reset_mask = 0xFFFF0000,
> .access_flags = PERIPHERAL_REGISTER_32BITS_WORD,
> .readable_bits = 0x0000FFFF,
> .rw_mode = REGISTER_RW_MODE_READ,
> },
>
>
> an example of a register with bitfields defined:
>
> {
> .desc = "RCC PLL configuration register (RCC_PLLCFGR)",
> .name = "pllcfgr",
> .offset_bytes = 0x04,
> .reset_value = 0x24003010,
> .bitfields = (RegisterBitfieldInfo[] ) {
> {
> .name = "pllm",
> .desc = "PLL division factor",
> .first_bit = 0,
> .width_bits = 6,
> },
> {
> .name = "plln",
> .desc = "PLL multiplication factor",
> .first_bit = 6,
> .width_bits = 9,
> },
> {
> .name = "pllp",
> .desc = "Main PLL (PLL) division factor",
> .first_bit = 16,
> .width_bits = 2,
> },
> {
> .name = "pllsrc",
> .desc = "Main PLL (PLL) clock source",
> .first_bit = 22,
> },
> {
> .name = "pllq",
> .desc = "Main PLL (PLL) division factor",
> .first_bit = 24,
> .width_bits = 4,
> },
> { },
> },
> },
>
>
>
> accessing registers and reading bitfields is straightforward:
>
> peripheral_register_write_value(odr, new_value);
>
> ....
>
> pllm = register_bitfield_read_value(state->f4.fld.pllcfgr.pllm);
>
>
>
> this model has several advantages:
>
> - increased emulation accuracy; the functionality is fully and uniformly
> implemented for all objects, for example byte and unaligned accesses are
> implemented for all registers; read/write masks allow to affect only the
> desired bits; etc
> - increased readability; the definitions are descriptive, not hidden inside
> code
> - opens the door to automatically generate the MCU definitions
>
> possible disadvantages:
>
> - a small overhead, hopefully not impacting general performances
>
>
> this model is currently implemented and functional in my branch, and it was
> used to implement the needed STM32 peripherals (RCC, GPIO, FLASH, PWR) for
> the STM32F1 and STM32F4 families, and will probably be part of the new GNU
> ARM Eclipse QEMU release, scheduled in 2-3 weeks.
>
> however I would consider it still experimental, since I already have new
> ideas that I would like to experiment in future versions.
>
>
> regards,
>
> Liviu
>
>
>
>
>
>
>