Register 0: ID code register
mrc p15, 0, Rd, c0, c0, 0
mrc p15, 0, Rd, c0, c0, 3
mrc p15, 0, Rd, c0, c0, 4
mrc p15, 0, Rd, c0, c0, 5
mrc p15, 0, Rd, c0, c0, 6
mrc p15, 0, Rd, c0, c0, 7
| [31:24] | Implementor | 0x41 |
| [23:20] | Variant (reserved) | 0x0 |
| [19:16] | ARM Architecture 5TE | 0x5 |
| [15:4] | Primary part number | 0x946 |
| [3:0] | Revision (major product revision) | 0x1 |
Register 0: Cache type register
mrc p15, 0, Rd, c0, c0, 1
| 31..29 | Reserved | b000 |
| 28..25 | Cache type | b0111 |
| 24 | Harvard/unified | b1 (Harvard) |
| 23..22 | Reserved | b00 |
| 21..18 | Data cache size | read |
| 17..15 | Data cache associativity | read |
| 14 | Data cache absent | read |
| 13..12 | Data cache words/line | b10 (8 words/line) |
| 11..10 | Reserved | b00 |
| 9..6 | Instruction cache size | read |
| 5..3 | Instruction cache associativity | read |
| 2] | Instruction cache absent | read |
| 1..0 | Instruction cache words/line | b10 (8 words/line) |
Actual cache size = (512 << cacheSizeField), unless cacheSizeField = 0 (i.e. cache size = 0 KB)
Register 0: Tightly coupled memory size register
mrc p15, 0, Rd, c0, c0, 2
| 31..22 | Reserved | 0's |
| 21..18 | DTCM size | read |
| 17..15 | Reserved | 0's |
| 14 | DTCM absent | read |
| 13..10 | Reserved | 0's |
| 9..6 | ITCM size | read |
| 5..3 | Reserved | 0's |
| 2 | ITCM absent | read |
| 1..0 | Reserved | 0's |
Actual TCM size = (512 << sizeField), unless sizeField = 0 (i.e. size = 0 KB)
Register 1: Control register
mrc p15, 0, Rd, c1, c0, 0 @ read control register
mcr p15, 0, Rd, c1, c0, 0 @ write control register
| 31..20 | Reserved (SBZ) |
| 19 | ITCM load mode |
| 18 | ITCM enabled |
| 17 | DTCM load mode |
| 16 | DTCM enabled |
| 15 | Disable loading TBIT |
| 14 | Round-robin replacement |
| 13 | Alternate vector select |
| 12 | Instruction cache enable |
| 11..8 | Reserved (SBZ) |
| 7 | Big endian |
| 6..3 | Reserved (SBO) |
| 2 | Data cache enable |
| 1 | Reserved (SBZ) |
| 0 | Protection unit enable |
Register 2: Cache Configuration Registers
mrc p15, 0, Rd, c2, c0, 0 @ read data cacheable bits
mcr p15, 0, Rd, c2, c0, 0 @ write data cacheable bits
mrc p15, 0, Rd, c2, c0, 1 @ read instruction cacheable bits
mcr p15, 0, Rd, c2, c0, 1 @ write instruction cacheable bits
Each bit in the low byte of Rd corresponds to an individual region, specifying whether or not it is cacheable.
Register 3: Write Buffer Control Registers
mrc p15, 0, Rd, c3, c0, 0 @ read data bufferable bits
mcr p15, 0, Rd, c3, c0, 0 @ write data bufferable bits
Each bit in the low byte of Rd corresponds to an individual region, specifying whether or not writes to that region are bufferable.
Register 5: Access permission registers (compatible)
mrc p15, 0, Rd, c5, c0, 0 @ read data access permission bits
mcr p15, 0, Rd, c5, c0, 0 @ write data access permission bits
mrc p15, 0, Rd, c5, c0, 1 @ read instruction access permission bits
mcr p15, 0, Rd, c5, c0, 1 @ write instruction access permission bits
Each area has 2 permission bits (area7 = b15..b14, area0 = b1..b0), where:
| Bits | Privileged | User |
| 00 | no | no |
| 01 | R/W | no |
| 10 | R/W | R |
| 11 | R/W | R/W |
Register 5: Access permission registers (extended)
mrc p15, 0, Rd, c5, c0, 2 @ read data access permission bits
mcr p15, 0, Rd, c5, c0, 2 @ write data access permission bits
mrc p15, 0, Rd, c5, c0, 3 @ read instruction access permission bits
mcr p15, 0, Rd, c5, c0, 3 @ write instruction access permission bits
Each area has 4 permission bits (area7 = b31..b28, area0 = b3..b0), where:
| Bits | Privileged | User |
| 0000 | no | no |
| 0001 | R/W | no |
| 0010 | R/W | R |
| 0011 | R/W | R/W |
| 0100 | UNP | UNP |
| 0101 | R | no |
| 0110 | R | R |
| 0111 | UNP | UNP |
| 1xxx | UNP | UNP |
Standard forms (supported for backwards compatibility only):
mrc p15, 0, Rd, c5, c0, 0 @ read data access permission bits
mcr p15, 0, Rd, c5, c0, 0 @ write data access permission bits
mrc p15, 0, Rd, c5, c0, 1 @ read instruction access permission bits
mcr p15, 0, Rd, c5, c0, 1 @ write instruction access permission bits
The encoding for the old format only contain 16 bits, 2 per region. Same order as the 32-bit registers, but the two bits now specify:
| Bits | Privileged | User |
| 00 | no | no |
| 01 | R/W | no |
| 10 | R/W | R |
| 11 | R/W | R/W |
Register 6: Protection Region Base and Size Registers
mrc/mrc p15, 0, Rd, c6, c7, 0 @ Memory region 7
mrc/mrc p15, 0, Rd, c6, c6, 0 @ Memory region 6
mrc/mrc p15, 0, Rd, c6, c5, 0 @ Memory region 5
mrc/mrc p15, 0, Rd, c6, c4, 0 @ Memory region 4
mrc/mrc p15, 0, Rd, c6, c3, 0 @ Memory region 3
mrc/mrc p15, 0, Rd, c6, c2, 0 @ Memory region 2
mrc/mrc p15, 0, Rd, c6, c1, 0 @ Memory region 1
mrc/mrc p15, 0, Rd, c6, c0, 0 @ Memory region 0
Each register has the following format:
| Bits | Purpose |
| 31..12 | Region base address |
| 5..1 | Region size |
| 0 | Region enabled (1: enabled, 0: disabled) |
The region base address is granular to 4 KB (i.e. the base is just this register with the low 12 bits masked off). In addition, the base must be aligned to a region sized boundary, otherwise you get a dreaded Unpredictable behavior.
The region size field represents the size as 1<<(field+1), with values smaller than 11 being invalid (i.e. a region must be at least 4 KB large).
Register 7: Cache Operations Register
mcr p15, 0, Rd, c7, c5, 0 @ Flush ICache (Rd = 0)
mcr p15, 0, Rd, c7, c5, 1 @ Flush one ICache entry (Rd = address)
mcr p15, 0, Rd, c7, c13, 1 @ Prefetch ICache line (Rd = address)
mcr p15, 0, Rd, c7, c6, 0 @ Flush DCache (Rd = 0)
mcr p15, 0, Rd, c7, c6, 1 @ Flush one DCache entry (Rd = address)
mcr p15, 0, Rd, c7, c10, 1 @ Clean DCache entry (Rd = address)
mcr p15, 0, Rd, c7, c14, 1 @ Clean and flush DCache entry (Rd = address)
mcr p15, 0, Rd, c7, c10, 2 @ Clean DCache entry (Rd = index/segment)
mcr p15, 0, Rd, c7, c14, 2 @ Clean and flush DCache entry (Rd = index/segment)
mcr p15, 0, Rd, c7, c10, 4 @ Drain write buffer (stalls CPU until completion)
Addresses for the instruction cache prefix should have the low 5 bits as zero.
Data format for index/segment operations:
| Bits | Purpose |
| 31..30 | Segment |
| 29..N+1 | 0 |
| N..5 | Index |
| 4..0 | 0 |
Where N depends on the implemented cache size (N=9 for 4 KB, 10 for 8 KB, etc...)
Register 7/15, Interrupt related behavior
mcr p15, 0, Rd, c7, c0, 4 @ Wait for interrupt (preferred method)
mcr p15, 0, Rd, c15, c8, 2 @ Wait for interrupt (old method, don't use)
These stall the CPU until an irq or fiq occurs. These also ignore the setting of the I and F bits in the CPU (i.e. if those bits are set, execution will continue after this opcode, but if they're cleared, then the interrupt will be taken first).
Register 9, Cache Lockdown Registers
mcr p15, 0, Rd, c9, c0, 0 @ Write DCache lockdown control
mrc p15, 0, Rd, c9, c0, 0 @ Read DCache lockdown control
mcr p15, 0, Rd, c9, c0, 1 @ Write ICache lockdown control
mrc p15, 0, Rd, c9, c0, 1 @ Read ICache lockdown control
Data format for the lockdown control registers:
| Bits | Purpose |
| 31 | Load bit, DL/IL |
| 30..2 | 0 |
| 1..0 | Cache segment, Dindex, Iindex |
Register 9, TCM control
mcr p15, 0, Rd, c9, c1, 0 @ Write DTCM control
mrc p15, 0, Rd, c9, c1, 0 @ Read DTCM control
mcr p15, 0, Rd, c9, c1, 1 @ Write ITCM control
mrc p15, 0, Rd, c9, c1, 1 @ Read ITCM control
Data format for the lockdown control registers:
| Bits | Purpose |
| 31..12 | Region base |
| 5..1 | Region size |
| 0 | 0 |
Same format as the protection region registers, except the bottom bit is ignored. You still need to align the region to a boundary of the region size.
Register 13, 15
Look in the ARM946 datasheet for these