On Wed, Jul 8, 2015 at 1:14 PM, Liviu Ionescu <i...@livius.net> 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 > > > > > > >