The syntax I would like to end up with is something like:
Expand|Select|Wrap|Line Numbers
- foo = handle.vendor_id.get();
To add complexity, some registers are a set of bits or bit fields. The command register in PCI config space is a good example. So I would like to be able to also say
Expand|Select|Wrap|Line Numbers
- dog = handle.IO_enable.get();
The dream is to be able to define sets of classes. One type of class would provide the basic access method to the bus. Another set of classes would provide full register access but the registers come in 1, 2, 4, and 8 byte sizes. The third set would provide bit access for a particular register where the bit fields would require a bit offset and a size in bits of the field.
Once these classes are defined, then I could do things like:
Expand|Select|Wrap|Line Numbers
- class pcicfg {
- pcicfg_access acc;
- field<acc, uint16_t, 0> vendor_id;
- field<acc, uint16_t, 2> device_id;
- field<acc, uint16_t, 4> command;
- bitfield<command, 0, 1> IO_enable;
- };
I've attempted to use some metaprogramming concepts but I never got anything useful. It sounds really complex but the key that I'd like to keep is all of the information after the access method is constant. And, sometimes, the access method will simply be traversing a pointer. So I'd like to get the access to a bit field to able to compile down to what you would normally get from straight C.
For example, for the case that the PCI bus is mapped, then this:
Expand|Select|Wrap|Line Numbers
- foo = other_handle.some_bitfield.get();
Expand|Select|Wrap|Line Numbers
- foo = ((*(uint16_t *)(other_handle.c_ptr + offset)) >> shift) & mask;
I hope all this makes some sense. Any help or guidence would greatly be appreciated.