/* * register.h * * Copyright (c) 2020 Semidrive Semiconductor. * All rights reserved. * * Description: ARM cp register interface. * * Revision History: * ----------------- */ #ifndef INCLUDE_ARCH_REGISTER_H #define INCLUDE_ARCH_REGISTER_H #define REG_R0 (0) #define REG_R1 (1) #define REG_R2 (2) #define REG_R3 (3) #define REG_R4 (4) #define REG_R5 (5) #define REG_R6 (6) #define REG_R7 (7) #define REG_R8 (8) #define REG_R9 (9) #define REG_R10 (10) #define REG_R11 (11) #define REG_R12 (12) #define REG_R13 (13) #define REG_R14 (14) #define REG_R15 (15) #define REG_CPSR (16) #define ARM_CONTEXT_REGS (17) /* If the MCU supports a floating point unit, then it will be necessary * to save the state of the FPU status register and data registers on * each context switch. These registers are not saved during interrupt * level processing, however. So, as a consequence, floating point * operations may NOT be performed in interrupt handlers. * * The FPU provides an extension register file containing 32 single- * precision registers. These can be viewed as: * * - Sixteen 64-bit double word registers, D0-D15 * - Thirty-two 32-bit single-word registers, S0-S31 * S<2n> maps to the least significant half of D * S<2n+1> maps to the most significant half of D. */ #if CONFIG_ARCH_WITH_FPU # define REG_D0 (ARM_CONTEXT_REGS+0) /* D0 */ # define REG_S0 (ARM_CONTEXT_REGS+0) /* S0 */ # define REG_S1 (ARM_CONTEXT_REGS+1) /* S1 */ # define REG_D1 (ARM_CONTEXT_REGS+2) /* D1 */ # define REG_S2 (ARM_CONTEXT_REGS+2) /* S2 */ # define REG_S3 (ARM_CONTEXT_REGS+3) /* S3 */ # define REG_D2 (ARM_CONTEXT_REGS+4) /* D2 */ # define REG_S4 (ARM_CONTEXT_REGS+4) /* S4 */ # define REG_S5 (ARM_CONTEXT_REGS+5) /* S5 */ # define REG_D3 (ARM_CONTEXT_REGS+6) /* D3 */ # define REG_S6 (ARM_CONTEXT_REGS+6) /* S6 */ # define REG_S7 (ARM_CONTEXT_REGS+7) /* S7 */ # define REG_D4 (ARM_CONTEXT_REGS+8) /* D4 */ # define REG_S8 (ARM_CONTEXT_REGS+8) /* S8 */ # define REG_S9 (ARM_CONTEXT_REGS+9) /* S9 */ # define REG_D5 (ARM_CONTEXT_REGS+10) /* D5 */ # define REG_S10 (ARM_CONTEXT_REGS+10) /* S10 */ # define REG_S11 (ARM_CONTEXT_REGS+11) /* S11 */ # define REG_D6 (ARM_CONTEXT_REGS+12) /* D6 */ # define REG_S12 (ARM_CONTEXT_REGS+12) /* S12 */ # define REG_S13 (ARM_CONTEXT_REGS+13) /* S13 */ # define REG_D7 (ARM_CONTEXT_REGS+14) /* D7 */ # define REG_S14 (ARM_CONTEXT_REGS+14) /* S14 */ # define REG_S15 (ARM_CONTEXT_REGS+15) /* S15 */ # define REG_D8 (ARM_CONTEXT_REGS+16) /* D8 */ # define REG_S16 (ARM_CONTEXT_REGS+16) /* S16 */ # define REG_S17 (ARM_CONTEXT_REGS+17) /* S17 */ # define REG_D9 (ARM_CONTEXT_REGS+18) /* D9 */ # define REG_S18 (ARM_CONTEXT_REGS+18) /* S18 */ # define REG_S19 (ARM_CONTEXT_REGS+19) /* S19 */ # define REG_D10 (ARM_CONTEXT_REGS+20) /* D10 */ # define REG_S20 (ARM_CONTEXT_REGS+20) /* S20 */ # define REG_S21 (ARM_CONTEXT_REGS+21) /* S21 */ # define REG_D11 (ARM_CONTEXT_REGS+22) /* D11 */ # define REG_S22 (ARM_CONTEXT_REGS+22) /* S22 */ # define REG_S23 (ARM_CONTEXT_REGS+23) /* S23 */ # define REG_D12 (ARM_CONTEXT_REGS+24) /* D12 */ # define REG_S24 (ARM_CONTEXT_REGS+24) /* S24 */ # define REG_S25 (ARM_CONTEXT_REGS+25) /* S25 */ # define REG_D13 (ARM_CONTEXT_REGS+26) /* D13 */ # define REG_S26 (ARM_CONTEXT_REGS+26) /* S26 */ # define REG_S27 (ARM_CONTEXT_REGS+27) /* S27 */ # define REG_D14 (ARM_CONTEXT_REGS+28) /* D14 */ # define REG_S28 (ARM_CONTEXT_REGS+28) /* S28 */ # define REG_S29 (ARM_CONTEXT_REGS+29) /* S29 */ # define REG_D15 (ARM_CONTEXT_REGS+30) /* D15 */ # define REG_S30 (ARM_CONTEXT_REGS+30) /* S30 */ # define REG_S31 (ARM_CONTEXT_REGS+31) /* S31 */ # define REG_FPSCR (ARM_CONTEXT_REGS+32) /* Floating point status and control */ # define FPU_CONTEXT_REGS (33) #else # define FPU_CONTEXT_REGS (0) #endif /* The total number of registers saved by software */ #define XCPTCONTEXT_REGS (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS) #define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) #ifndef ASSEMBLY #include #include #include static inline uint32_t read_cpsr(void) { uint32_t cpsr; __ASM volatile("mrs %0, cpsr" : "=r" (cpsr)); return cpsr; } #define ARM_CP_REG_FUNCS(cp, reg, op1, c1, c2, op2) \ static inline uint32_t arm_read_##reg(void) { \ uint32_t val; \ __ASM volatile("mrc " #cp ", " #op1 ", %0, " #c1 "," #c2 "," #op2 : "=r" (val)); \ return val; \ } \ \ static inline void arm_write_##reg(uint32_t val) { \ __ASM volatile("mcr " #cp ", " #op1 ", %0, " #c1 "," #c2 "," #op2 :: "r" (val)); \ ISB; \ } #define ARM_CP15_REG_FUNCS(reg, op1, c1, c2, op2) \ ARM_CP_REG_FUNCS(p15, reg, op1, c1, c2, op2) #define ARM_CP14_REG_FUNCS(reg, op1, c1, c2, op2) \ ARM_CP_REG_FUNCS(p14, reg, op1, c1, c2, op2) #define ARM_CP10_REG_FUNCS(reg, op1, c1, c2, op2) \ ARM_CP_REG_FUNCS(p10, reg, op1, c1, c2, op2) ARM_CP15_REG_FUNCS(sctlr, 0, c1, c0, 0); ARM_CP15_REG_FUNCS(actlr, 0, c1, c0, 1); ARM_CP15_REG_FUNCS(cpacr, 0, c1, c0, 2); ARM_CP15_REG_FUNCS(ttbr, 0, c2, c0, 0); ARM_CP15_REG_FUNCS(ttbr0, 0, c2, c0, 0); ARM_CP15_REG_FUNCS(ttbr1, 0, c2, c0, 1); ARM_CP15_REG_FUNCS(ttbcr, 0, c2, c0, 2); ARM_CP15_REG_FUNCS(dacr, 0, c3, c0, 0); ARM_CP15_REG_FUNCS(dfsr, 0, c5, c0, 0); ARM_CP15_REG_FUNCS(ifsr, 0, c5, c0, 1); ARM_CP15_REG_FUNCS(dfar, 0, c6, c0, 0); ARM_CP15_REG_FUNCS(wfar, 0, c6, c0, 1); ARM_CP15_REG_FUNCS(ifar, 0, c6, c0, 2); ARM_CP15_REG_FUNCS(fcseidr, 0, c13, c0, 0); ARM_CP15_REG_FUNCS(contextidr, 0, c13, c0, 1); ARM_CP15_REG_FUNCS(tpidrurw, 0, c13, c0, 2); ARM_CP15_REG_FUNCS(tpidruro, 0, c13, c0, 3); ARM_CP15_REG_FUNCS(tpidrprw, 0, c13, c0, 4); ARM_CP15_REG_FUNCS(midr, 0, c0, c0, 0); ARM_CP15_REG_FUNCS(mpidr, 0, c0, c0, 5); ARM_CP15_REG_FUNCS(vbar, 0, c12, c0, 0); ARM_CP15_REG_FUNCS(cbar, 4, c15, c0, 0); ARM_CP15_REG_FUNCS(ats1cpr, 0, c7, c8, 0); ARM_CP15_REG_FUNCS(ats1cpw, 0, c7, c8, 1); ARM_CP15_REG_FUNCS(ats1cur, 0, c7, c8, 2); ARM_CP15_REG_FUNCS(ats1cuw, 0, c7, c8, 3); ARM_CP15_REG_FUNCS(ats12nsopr, 0, c7, c8, 4); ARM_CP15_REG_FUNCS(ats12nsopw, 0, c7, c8, 5); ARM_CP15_REG_FUNCS(ats12nsour, 0, c7, c8, 6); ARM_CP15_REG_FUNCS(ats12nsouw, 0, c7, c8, 7); ARM_CP15_REG_FUNCS(par, 0, c7, c4, 0); /* Branch predictor invalidate */ ARM_CP15_REG_FUNCS(bpiall, 0, c7, c5, 6); ARM_CP15_REG_FUNCS(bpimva, 0, c7, c5, 7); ARM_CP15_REG_FUNCS(bpiallis, 0, c7, c1, 6); /* tlb registers */ ARM_CP15_REG_FUNCS(tlbiallis, 0, c8, c3, 0); ARM_CP15_REG_FUNCS(tlbimvais, 0, c8, c3, 1); ARM_CP15_REG_FUNCS(tlbiasidis, 0, c8, c3, 2); ARM_CP15_REG_FUNCS(tlbimvaais, 0, c8, c3, 3); ARM_CP15_REG_FUNCS(itlbiall, 0, c8, c5, 0); ARM_CP15_REG_FUNCS(itlbimva, 0, c8, c5, 1); ARM_CP15_REG_FUNCS(itlbiasid, 0, c8, c5, 2); ARM_CP15_REG_FUNCS(dtlbiall, 0, c8, c6, 0); ARM_CP15_REG_FUNCS(dtlbimva, 0, c8, c6, 1); ARM_CP15_REG_FUNCS(dtlbiasid, 0, c8, c6, 2); ARM_CP15_REG_FUNCS(tlbiall, 0, c8, c7, 0); ARM_CP15_REG_FUNCS(tlbimva, 0, c8, c7, 1); ARM_CP15_REG_FUNCS(tlbiasid, 0, c8, c7, 2); ARM_CP15_REG_FUNCS(tlbimvaa, 0, c8, c7, 3); ARM_CP15_REG_FUNCS(l2ctlr, 1, c9, c0, 2); ARM_CP15_REG_FUNCS(l2ectlr, 1, c9, c0, 3); /* mpu registers (using unified memory regions) */ ARM_CP15_REG_FUNCS(mpuir, 0, c0, c0, 4); ARM_CP15_REG_FUNCS(rbar, 0, c6, c1, 0); ARM_CP15_REG_FUNCS(rsr, 0, c6, c1, 2); ARM_CP15_REG_FUNCS(racr, 0, c6, c1, 4); ARM_CP15_REG_FUNCS(rgnr, 0, c6, c2, 0); /* performance monitor registers */ ARM_CP15_REG_FUNCS(pmcr, 0, c9, c12, 0); ARM_CP15_REG_FUNCS(pmcntenset, 0, c9, c12, 1); ARM_CP15_REG_FUNCS(pmcntenclr, 0, c9, c12, 2); ARM_CP15_REG_FUNCS(pmovsr, 0, c9, c12, 3); ARM_CP15_REG_FUNCS(pmswinc, 0, c9, c12, 4); ARM_CP15_REG_FUNCS(pmselr, 0, c9, c12, 5); ARM_CP15_REG_FUNCS(pmccntr, 0, c9, c13, 0); ARM_CP15_REG_FUNCS(pmxevtyper, 0, c9, c13, 1); ARM_CP15_REG_FUNCS(pmxevcntr, 0, c9, c13, 2); /* TCM registers */ ARM_CP15_REG_FUNCS(tcmtr, 0, c0, c0, 2); ARM_CP15_REG_FUNCS(btcmrgn, 0, c9, c1, 0); ARM_CP15_REG_FUNCS(atcmrgn, 0, c9, c1, 1); /* debug registers */ ARM_CP14_REG_FUNCS(dbddidr, 0, c0, c0, 0); ARM_CP14_REG_FUNCS(dbgdrar, 0, c1, c0, 0); ARM_CP14_REG_FUNCS(dbgdsar, 0, c2, c0, 0); ARM_CP14_REG_FUNCS(dbgdscr, 0, c0, c1, 0); ARM_CP14_REG_FUNCS(dbgdtrtxint, 0, c0, c5, 0); ARM_CP14_REG_FUNCS(dbgdtrrxint, 0, c0, c5, 0); ARM_CP14_REG_FUNCS(dbgwfar, 0, c0, c6, 0); ARM_CP14_REG_FUNCS(dbgvcr, 0, c0, c7, 0); ARM_CP14_REG_FUNCS(dbgecr, 0, c0, c9, 0); ARM_CP14_REG_FUNCS(dbgdsccr, 0, c0, c10, 0); ARM_CP14_REG_FUNCS(dbgdsmcr, 0, c0, c11, 0); ARM_CP14_REG_FUNCS(dbgdtrrxext, 0, c0, c0, 2); ARM_CP14_REG_FUNCS(dbgdscrext, 0, c0, c2, 2); ARM_CP14_REG_FUNCS(dbgdtrtxext, 0, c0, c3, 2); ARM_CP14_REG_FUNCS(dbgdrcr, 0, c0, c4, 2); ARM_CP14_REG_FUNCS(dbgvr0, 0, c0, c0, 4); ARM_CP14_REG_FUNCS(dbgvr1, 0, c0, c1, 4); ARM_CP14_REG_FUNCS(dbgvr2, 0, c0, c2, 4); ARM_CP14_REG_FUNCS(dbgbcr0, 0, c0, c0, 5); ARM_CP14_REG_FUNCS(dbgbcr1, 0, c0, c1, 5); ARM_CP14_REG_FUNCS(dbgbcr2, 0, c0, c2, 5); ARM_CP14_REG_FUNCS(dbgwvr0, 0, c0, c0, 6); ARM_CP14_REG_FUNCS(dbgwvr1, 0, c0, c1, 6); ARM_CP14_REG_FUNCS(dbgwcr0, 0, c0, c0, 7); ARM_CP14_REG_FUNCS(dbgwcr1, 0, c0, c1, 7); ARM_CP14_REG_FUNCS(dbgoslar, 0, c1, c0, 4); ARM_CP14_REG_FUNCS(dbgoslsr, 0, c1, c1, 4); ARM_CP14_REG_FUNCS(dbgossrr, 0, c1, c2, 4); ARM_CP14_REG_FUNCS(dbgprcr, 0, c1, c4, 4); ARM_CP14_REG_FUNCS(dbgprsr, 0, c1, c5, 4); ARM_CP14_REG_FUNCS(dbgclaimset, 0, c7, c8, 6); ARM_CP14_REG_FUNCS(dbgclaimclr, 0, c7, c9, 6); ARM_CP14_REG_FUNCS(dbgauthstatus, 0, c7, c14, 6); ARM_CP14_REG_FUNCS(dbgdevid, 0, c7, c2, 7); /* fpu registers */ ARM_CP10_REG_FUNCS(fpexc, 7, c8, c0, 0); #endif /* ASSEMBLY */ #endif /* INCLUDE_ARCH_REGISTER_H */