Hello, I am a firmware engineer in wireless wearable sector. In my work, I need to interface to silicon hardware designers to properly design a firmware driver. The following are some tips which are helpful to my work. Hope it is helpful to you too. Thanks for reading and let me know your comments.
Hardware module designer needs to separate command registers, control/configuration registers, status registers, and data registers such as fifo and memory. Each module has a base address and module registers use offset relative to this base address. It is preferred register allocation is contiguous without address hole to fw can use pointer or array index. But it turns out to be sub-optimal most of time since new register will either be appended to the end which will mix register type, or new register will be inserted but move existing registers. This is not backward compatible. Fw team will see their golden firmware failing on new hardware without a clue. So lots of time reserve some space for each register type is a more feasible and flexible way.
A lot of times, hardware group only deliver register mapping which includes register name, address, reset value, and function description for each bit. But what is lacking the sequence or system view of how to use these registers. It is preferred for hardware group to also deliver a programing guide which describes the sequence of read/write these registers to achieve typical functions.
Register Reset Value
When power is first applied, hardware reset (or called power on reset) put all the FFs, including firmware registers, into known state. This default firmware register value should put hardware module into known idle state since processor will take longer time to boot and be able to control hardware module. This reset default value should also be as close as possible to normal function value otherwise it will take time and energy to reprogram it. In real silicon design, hardware and firmware design are in parallel. Once hardware design enters RTL freeze state, normally it doesn’t worth the efforts to accommodate firmware request to change register reset value. For a ROM or flash based silicon, new register value can be put into ROM. So when processor is out of reset, processor can read ROM and reprogram those registers. If firmware wants to change register value after ROM freeze or after TO, it can resort to external storage like external EEPOM or flash or upstream components like application processor which holds patches (including new register values). So hw group maintains hw reset reg mapping or fw group maintains reg mapping of hw reset, rom, and patch download.
Register Read and Write
Registers that can be written should be readable otherwise firmware has to use shadow register to buffer written value in memory. An exception may be command register. To command register, what is important is the event or action to write and written value is not important. Many times, command register is designed in a way that it doesn’t matter writing 0 or 1. As long as a write happens to this register, hardware start certain function. In some design that is short of address space, command register (write only) and status register (read only) are combined into one address.
Another case worth mentioning is read self-clearing. Talking profile register as an example, normal function is after read this register, you need to clear it so it can recording number of events starting with 0. Register can be self-cleared for read access from hardware point of view to save a write access. But from firmware and verification point of view, self-clearing is not preferred. Reading one register twice will get different value. This will confuse firmware and verification testing.
Don’t mix registers from multiple modules
It is a less concern in real silicon design. Less likely hardware designers will mix registers from multiple modules. Lot of shortcomings. It is not IP design friendly. The module can not be easily ported to another system. A lot of signals going back and forth between modules. It will increase module level and system level testing efforts dramatically. It is also not good from firmware point of view. Firmware normally use read-modify-write to change certain bits of a register. If two hardware modules share same register, then two firmware functions try to access the same register. There is a chance that the first read-modify-write is interrupted by the second one. Then the first one will fail since register value changes after its read.
Register bits aligning
If you have a field which consists of multiple bits, it is preferred to align the field to nibble (4 bits) boundary. It is a lab testing friendly approach. Otherwise engineers have to mentally convert the read back value. That is very painful since he may do this hundreds of times in a day.