I’m currently working on a device driver (written in C, targeting multiple OSs – wish I could use Rust
, but I digress). One recurring pattern is mapping memory layouts imposed by a device into structures accissible to the programming language.
An often found method for this are packed structs into which padding elements are added. However repr(packed) seems to be broken at the moment. However one has to acknowledge that for interfacing with explicit, preexisting memory layouts it’s actually not the packing we’re after, but being able to explicitly specify the offset of structure elements.
Also sometimes one may want to overlap certain elements (because there is weird hardware out there which overloads address mappings and sometimes does crazy things).
Furthermore often hardware demands certain fixed values / bit patterns to appear at specific locations.
And last but not least often hardware registers consist of several values packed into a single bitfield. It would be great if that could be represented as well.
I thus propose a way to explicitly specify the layout of structures. There are three aspects that should be controllable:
- the size of the struct
- the offset of each element down to the bit offset
- and often also fixed bit patterns
So my idea on how to tackle this is to introduce syntax that allows to explicitly specify offset, bit shifts and masks inside a struct. Something along the lines of this
struct foo_registers @(FOO_SIZE) {
a: i32 @(0x00); // a plain 32 bit register at offset 0
b: u32 @(0x04), <<(5), &(0xfff); // a value with mask 0xfff (12 bits) located at offset 0x04 + 5 bits
c: i32 @(0x06); // ←note the overlap of c with b here
0xcafed0de: u32 @(0x20); // the fixed pattern of value `0xcafedode` that must appear at offset 0x20
m: u16 @(0x28), &(0xf00f); // a 16 bit value where certain bits are masked
0x0a50: u16 @(0x28), &(0x0ff0); // fixed pattern that shall appear inside the masked portions of m
};
Of course the syntax should be chosen so that parsing is easy but also programmer friendly. Also maybe things like element overlapping could go with a “yes, I am aware of the overlap” syntax, so that it doesn’t happen accidently (and the compiler can warn about that).
Any thoughts on that?