Hardware devices expose their registers to CPU side using MMIO. And there are so many types of registers (written in some hardware manuals/device drivers) which are used for different usages. How do these hardware devices check the register access permissions?
I tested on a Development Board using busybox devmem
, there are some MMIO registers (DEVICE_ID
, DEVICE_FEATURE
, etc.) which are not writable from CPU side. I wonder how does hardware implement read-only/write-only permissions on this registers?
These design rules would be implemented at the peripheral. The cpu has no clue what a peripheral is much less any details of any peripheral or registers or bits within a register.
Take a timer for example and let's say I design it such that the register you use to read the current count is read only (manipulating the start or rollover count, etc I have implemented through some other register/mechanism).
I have a control register that enables or disables the counter. Once the address is decoded down to the specific peripheral the offsets are.
0x00 bit[0] = 0 for disable 1 for enable
0x04 read only current count
From the programmers side these might be
0x40010300 control
0x40010304 timer count
Some registers in a pseudo language (8 bit interface)
reg timer_count[7:0]
reg enable[1]
Then the logic implements, for each clock cycle:
if(enable) timer_count = timer_count + 1
//assume processor side bus decodes the full address and aims it ultimately
//at this peripheral through other buses
if(bus_enable)
{
if(bus_cycle_write)
{
if(address == 0x00)
enable = bus_write_data[0]
}
else //read
{
if(address == 0x00)
bus_read_data = {7b0,enable}
if(address == 0x04)
bus_read_data = timer_count
}
}
but using real syntax for a real HDL. No magic, no mystery. I could do your whole question and make one WO and one RO
if(bus_enable)
{
if(bus_cycle_write)
{
if(address == 0x00)
enable = bus_write_data[0]
}
else //read
{
if(address == 0x04)
bus_read_data = timer_count
}
}
The control register is write only the timer count register is read only. There is no read path to the control register and no write path to the timer count register.