# Linux Kernel Module Cheat

#### 30.5.3. ARM system register instructions

Examples of using them can be found at: dump_regs

aarch64 only uses exactly 2 instructions:

- MRS: reads a system register to a regular register

- MSR: writes to the system register

aarch32 is a bit more messy due to older setups, we have both:

- MRS and MSR which are much like in aarch64

- coprocessor accesses:

  - MRC: reads a system register, C means coprocessor, which is how system registers were previously known as

  - MCR: write to the system register

  - MRRC: like MRC, but used for the system registers that are marked as 64-bit, and reads to two general purpose register

  - MCRR: write version of MCRR

TODO why both? For example, as mentioned at https://stackoverflow.com/questions/62920281/cross-compilng-c-program-for-armv8-a-in-linux-x86-64-system/62922677#62922677 a register that was accessed with MRC in armv7 can move to MRS in aarch64, as is the case for:

    mrs r0, ctr     /* aarch32 */
    mrc x0, ctr_el0 /* aarch64 */

Other functionality has moved away from coprocessors into actual instructions, e.g. cache invalidation:

    /* aarch32: DCISW, Data Cache line Invalidate by Set/Way. */
    mcr     p15, 0, r5, c7, c6, 2

    /* aarch64: moved to one of the DC instruction variants. */
    dc isw

ARMv8 architecture reference manual db G1.19.4 "Background to the System register interface" says that only CP14 and CP15 are specified by the ISA:

> The interface to the System registers was originally defined as part of a generic coprocessor interface, that gave access to 15 coprocessors, CP0 - CP15. Of these, CP8 - CP15 were reserved for use by Arm, while CP0 - CP7 were available for IMPLEMENTATION DEFINED coprocessors.

and the actual coprocessor registers are specified in Chapter G7 "AArch32 System Register Encoding" at:

- CP14: Table G7-1 "Mapping of (coproc ==0b1110) MCR, MRC, and MRRC instruction arguments to System registers"

- CP15: Table G7-3 "VMSAv8-32 (coproc==0b1111) register summary, in MCR/MRC parameter order."

The actual MRC assembly does not exactly match the order of that table, this is how you can decode it, sample MCR:

    mcr     p15, 0, r5, c7, c6, 2

what each part means:

    mcr     p<coproc>, <opc1>, <src-dest-reg>, <CRn>, <CRm>, <opc2>

- ARM system register encodings