arm64: Generalise msr_s/mrs_s operations
authorSuzuki K. Poulose <suzuki.poulose@arm.com>
Wed, 22 Jul 2015 10:38:14 +0000 (11:38 +0100)
committerWill Deacon <will.deacon@arm.com>
Mon, 27 Jul 2015 10:08:41 +0000 (11:08 +0100)
The system register encoding generated by sys_reg() works only
for MRS/MSR(Register) operations, as we hardcode Bit20 to 1 in
mrs_s/msr_s mask. This makes it unusable for generating instructions
accessing registers with Op0 < 2(e.g, PSTATE.x with Op0=0).

As per ARMv8 ARM, (Ref: ARMv8 ARM, Section: "System instruction class
encoding overview", C5.2, version:ARM DDI 0487A.f), the instruction
encoding reserves bits [20-19] for Op0.

This patch generalises the sys_reg, mrs_s and msr_s macros, so that
we could use them to access any of the supported system register.

Cc: James Morse <james.morse@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
arch/arm64/include/asm/sysreg.h

index 56391fbae1e11625280614d6e7e75abd77111274..5295bcbcb3746a1c43f4511aa6cd427431bc341e 100644 (file)
 #define SCTLR_EL1_CP15BEN      (0x1 << 5)
 #define SCTLR_EL1_SED          (0x1 << 8)
 
+/*
+ * ARMv8 ARM reserves the following encoding for system registers:
+ * (Ref: ARMv8 ARM, Section: "System instruction class encoding overview",
+ *  C5.2, version:ARM DDI 0487A.f)
+ *     [20-19] : Op0
+ *     [18-16] : Op1
+ *     [15-12] : CRn
+ *     [11-8]  : CRm
+ *     [7-5]   : Op2
+ */
 #define sys_reg(op0, op1, crn, crm, op2) \
-       ((((op0)-2)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5))
+       ((((op0)&3)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5))
 
 #ifdef __ASSEMBLY__
 
        .equ    __reg_num_xzr, 31
 
        .macro  mrs_s, rt, sreg
-       .inst   0xd5300000|(\sreg)|(__reg_num_\rt)
+       .inst   0xd5200000|(\sreg)|(__reg_num_\rt)
        .endm
 
        .macro  msr_s, sreg, rt
-       .inst   0xd5100000|(\sreg)|(__reg_num_\rt)
+       .inst   0xd5000000|(\sreg)|(__reg_num_\rt)
        .endm
 
 #else
@@ -50,11 +60,11 @@ asm(
 "      .equ    __reg_num_xzr, 31\n"
 "\n"
 "      .macro  mrs_s, rt, sreg\n"
-"      .inst   0xd5300000|(\\sreg)|(__reg_num_\\rt)\n"
+"      .inst   0xd5200000|(\\sreg)|(__reg_num_\\rt)\n"
 "      .endm\n"
 "\n"
 "      .macro  msr_s, sreg, rt\n"
-"      .inst   0xd5100000|(\\sreg)|(__reg_num_\\rt)\n"
+"      .inst   0xd5000000|(\\sreg)|(__reg_num_\\rt)\n"
 "      .endm\n"
 );