* [Qemu-devel] [RFC] peripheral/register/bitfield objects - new MCU model
@ 2015-07-08 20:14 Liviu Ionescu
2015-07-08 20:22 ` Peter Crosthwaite
0 siblings, 1 reply; 5+ messages in thread
From: Liviu Ionescu @ 2015-07-08 20:14 UTC (permalink / raw)
To: QEMU Developers
Cc: Peter Maydell, Peter Crosthwaite, Aurelio C. Remonda,
Paolo Bonzini
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.
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
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [Qemu-devel] [RFC] peripheral/register/bitfield objects - new MCU model
2015-07-08 20:14 [Qemu-devel] [RFC] peripheral/register/bitfield objects - new MCU model Liviu Ionescu
@ 2015-07-08 20:22 ` Peter Crosthwaite
2015-07-09 1:50 ` Liviu Ionescu
2015-07-09 6:47 ` Liviu Ionescu
0 siblings, 2 replies; 5+ messages in thread
From: Peter Crosthwaite @ 2015-07-08 20:22 UTC (permalink / raw)
To: Liviu Ionescu
Cc: Peter Maydell, Aurelio C. Remonda, QEMU Developers, Paolo Bonzini
On Wed, Jul 8, 2015 at 1:14 PM, Liviu Ionescu <ilg@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
>
>
>
>
>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [Qemu-devel] [RFC] peripheral/register/bitfield objects - new MCU model
2015-07-08 20:22 ` Peter Crosthwaite
@ 2015-07-09 1:50 ` Liviu Ionescu
2015-07-09 2:42 ` Peter Crosthwaite
2015-07-09 6:47 ` Liviu Ionescu
1 sibling, 1 reply; 5+ messages in thread
From: Liviu Ionescu @ 2015-07-09 1:50 UTC (permalink / raw)
To: Peter Crosthwaite
Cc: Peter Maydell, Aurelio C. Remonda, QEMU Developers, Paolo Bonzini
> On 08 Jul 2015, at 23:22, Peter Crosthwaite <peter.crosthwaite@xilinx.com> wrote:
>
> 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
ok, so the problem is real.
as I said in the other message, my interest is to generate the entire MCU description from the CMSIS .pdsc and .svd files, not to define the bitfields manually, so I would model everything to be CMSIS centric.
regards,
Liviu
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [RFC] peripheral/register/bitfield objects - new MCU model
2015-07-09 1:50 ` Liviu Ionescu
@ 2015-07-09 2:42 ` Peter Crosthwaite
0 siblings, 0 replies; 5+ messages in thread
From: Peter Crosthwaite @ 2015-07-09 2:42 UTC (permalink / raw)
To: Liviu Ionescu
Cc: Peter Maydell, Aurelio C. Remonda, QEMU Developers, Paolo Bonzini
On Wed, Jul 8, 2015 at 6:50 PM, Liviu Ionescu <ilg@livius.net> wrote:
>
>> On 08 Jul 2015, at 23:22, Peter Crosthwaite <peter.crosthwaite@xilinx.com> wrote:
>>
>> 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
>
> ok, so the problem is real.
>
> as I said in the other message, my interest is to generate the entire MCU description from the CMSIS .pdsc and .svd files, not to define the bitfields manually, so I would model everything to be CMSIS centric.
>
Are these files text and can I get a pointer to an example?
Regards,
Peter
>
> regards,
>
> Liviu
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [RFC] peripheral/register/bitfield objects - new MCU model
2015-07-08 20:22 ` Peter Crosthwaite
2015-07-09 1:50 ` Liviu Ionescu
@ 2015-07-09 6:47 ` Liviu Ionescu
1 sibling, 0 replies; 5+ messages in thread
From: Liviu Ionescu @ 2015-07-09 6:47 UTC (permalink / raw)
To: Peter Crosthwaite
Cc: Peter Maydell, Aurelio C. Remonda, QEMU Developers, Paolo Bonzini
> On 08 Jul 2015, at 23:22, Peter Crosthwaite <peter.crosthwaite@xilinx.com> wrote:
>
> ... an RFC on list for something very similar, if you want to weigh
> in or find it useful, let me know!
yes, if you are not in a hurry to commit your patches, I guess together we can find a suitable solution.
as already mentioned, my goal is to automate as much as possible the MCU definition.
for example, in addition to the bitfield definitions that will be generated from the svd files, I identified and implemented bitfields that are automatically updated when other bitfields change, like READY bits automatically following ENABLE bits.
this is implemented with some bitfield properties, like:
cm_object_property_set_str(state->f1.cr.pllrdy, "pllon", "follows");
or
cm_object_property_set_str(state->f1.cir.lsirdyf, "lsirdyc",
"cleared-by");
such definitions greatly simplify the post-write callbacks.
regards,
Liviu
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-07-09 6:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-08 20:14 [Qemu-devel] [RFC] peripheral/register/bitfield objects - new MCU model Liviu Ionescu
2015-07-08 20:22 ` Peter Crosthwaite
2015-07-09 1:50 ` Liviu Ionescu
2015-07-09 2:42 ` Peter Crosthwaite
2015-07-09 6:47 ` Liviu Ionescu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).