In my recent USB series Avi mentioned he wanted to do some work with the memory API and encourage devices to use the memory API to do fine-grained register decoding, i.e. each register is its own MemoryRegion. This has the advantage of getting rid of the symmetric switch statements in the read and write handlers. The big drawback I am seeing is however is indexing into the register file. For example in a device i'm working on ATM I have this read handler for my device registers:
static uint64_t devcfg_read (void *opaque, hwaddr addr, unsigned size) { struct XilinxDevcfg *s = opaque; uint32_t ret; addr >>= 2; switch (addr) { //TODO: implement any read side effects } ret = s->regs[addr]; DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret); return ret; } For actually writing into the device registers, its just uses an array index, no need to switch (ret = s->regs[addr]). However for my side effects I will need to populate that switch. If we convert to fine grained memory regions then the switch goes away and my side effect become pretty, but my register update becomes ugly as each individual handler needs to index into s->regs with a constant index for the actual read. Is there a way we can have our cake and eat it too? Can we define two handlers for the one memory region? I have one handler that does the the read and write (or even just throw down a memory_region_init_ram) that does the load and store of register data, and a number of secondary handlers for side effects? Regards, Peter