Move FPEXC32_EL2 to FP Context
authorDavid Cunado <david.cunado@arm.com>
Fri, 20 Oct 2017 10:30:57 +0000 (11:30 +0100)
committerDavid Cunado <david.cunado@arm.com>
Wed, 15 Nov 2017 22:42:05 +0000 (22:42 +0000)
The FPEXC32_EL2 register controls SIMD and FP functionality when the
lower ELs are executing in AArch32 mode. It is architecturally mapped
to AArch32 system register FPEXC.

This patch removes FPEXC32_EL2 register from the System Register context
and adds it to the floating-point context. EL3 only saves / restores the
floating-point context if the build option CTX_INCLUDE_FPREGS is set to 1.

The rationale for this change is that if the Secure world is using FP
functionality and EL3 is not managing the FP context, then the Secure
world will save / restore the appropriate FP registers.

NOTE - this is a break in behaviour in the unlikely case that
CTX_INCLUDE_FPREGS is set to 0 and the platform contains an AArch32
Secure Payload that modifies FPEXC, but does not save and restore
this register

Change-Id: Iab80abcbfe302752d52b323b4abcc334b585c184
Signed-off-by: David Cunado <david.cunado@arm.com>
bl31/aarch64/crash_reporting.S
docs/firmware-design.rst
include/lib/el3_runtime/aarch64/context.h
lib/el3_runtime/aarch64/context.S

index 34e4dcddbeb0c12405fe657058b675e9185fd58a..cf32b31d76ed92883bd7561d4f82a1463b4edea1 100644 (file)
@@ -46,8 +46,7 @@ non_el3_sys_regs:
                "tpidrro_el0", "dacr32_el2", "ifsr32_el2", "par_el1",\
                "mpidr_el1", "afsr0_el1", "afsr1_el1", "contextidr_el1",\
                "vbar_el1", "cntp_ctl_el0", "cntp_cval_el0", "cntv_ctl_el0",\
-               "cntv_cval_el0", "cntkctl_el1", "fpexc32_el2", "sp_el0",\
-               "isr_el1", ""
+               "cntv_cval_el0", "cntkctl_el1", "sp_el0", "isr_el1", ""
 
 panic_msg:
        .asciz "PANIC in EL3 at x30 = 0x"
@@ -313,9 +312,8 @@ func do_crash_reporting
        mrs     x15, cntv_cval_el0
        bl      str_in_crash_buf_print
        mrs     x8, cntkctl_el1
-       mrs     x9, fpexc32_el2
-       mrs     x10, sp_el0
-       mrs     x11, isr_el1
+       mrs     x9, sp_el0
+       mrs     x10, isr_el1
        bl      str_in_crash_buf_print
 
        /* Get the cpu specific registers to report */
index 7cc197096b932f02f06582878eadaa8b30ac8a89..c0ece0ba801d635b25f7fb6843d944620c320b0c 100644 (file)
@@ -1144,7 +1144,6 @@ The sample crash output is shown below.
     cntv_ctl_el0    :0x0000000000000000
     cntv_cval_el0   :0x0000000000000000
     cntkctl_el1 :0x0000000000000000
-    fpexc32_el2 :0x0000000004000700
     sp_el0  :0x0000000004010780
 
 Guidelines for Reset Handlers
index a89468d49acd68402fa4cfddf99cf568b06f0bc1..cf06a64cdff7318e2f9e98c0161992a36a78f7a4 100644 (file)
 #define CTX_SPSR_FIQ           U(0xd8)
 #define CTX_DACR32_EL2         U(0xe0)
 #define CTX_IFSR32_EL2         U(0xe8)
-#define CTX_FP_FPEXC32_EL2     U(0xf0)
-#define CTX_TIMER_SYSREGS_OFF  U(0x100) /* Align to the next 16 byte boundary */
+#define CTX_TIMER_SYSREGS_OFF  U(0xf0) /* Align to the next 16 byte boundary */
 #else
 #define CTX_TIMER_SYSREGS_OFF  U(0xc0)  /* Align to the next 16 byte boundary */
 #endif /* __CTX_INCLUDE_AARCH32_REGS__ */
 #define CTX_FP_Q31             U(0x1f0)
 #define CTX_FP_FPSR            U(0x200)
 #define CTX_FP_FPCR            U(0x208)
-#define CTX_FPREGS_END         U(0x210)
+#if CTX_INCLUDE_AARCH32_REGS
+#define CTX_FP_FPEXC32_EL2     U(0x210)
+#define CTX_FPREGS_END         U(0x220) /* Align to the next 16 byte boundary */
+#else
+#define CTX_FPREGS_END         U(0x210) /* Align to the next 16 byte boundary */
+#endif
 #endif
 
 #ifndef __ASSEMBLY__
index db16a9f0e82d0c61bf9d7e0e9afffa86f651d979..143da956815bd45d675ddb4aea9de886a63c0b88 100644 (file)
@@ -90,9 +90,6 @@ func el1_sysregs_context_save
        mrs     x15, dacr32_el2
        mrs     x16, ifsr32_el2
        stp     x15, x16, [x0, #CTX_DACR32_EL2]
-
-       mrs     x17, fpexc32_el2
-       str     x17, [x0, #CTX_FP_FPEXC32_EL2]
 #endif
 
        /* Save NS timer registers if the build has instructed so */
@@ -212,9 +209,6 @@ func el1_sysregs_context_restore
        ldp     x15, x16, [x0, #CTX_DACR32_EL2]
        msr     dacr32_el2, x15
        msr     ifsr32_el2, x16
-
-       ldr     x17, [x0, #CTX_FP_FPEXC32_EL2]
-       msr     fpexc32_el2, x17
 #endif
        /* Restore NS timer registers if the build has instructed so */
 #if NS_TIMER_SWITCH
@@ -275,6 +269,10 @@ func fpregs_context_save
        mrs     x10, fpcr
        str     x10, [x0, #CTX_FP_FPCR]
 
+#if CTX_INCLUDE_AARCH32_REGS
+       mrs     x11, fpexc32_el2
+       str     x11, [x0, #CTX_FP_FPEXC32_EL2]
+#endif
        ret
 endfunc fpregs_context_save
 
@@ -318,6 +316,10 @@ func fpregs_context_restore
        ldr     x10, [x0, #CTX_FP_FPCR]
        msr     fpcr, x10
 
+#if CTX_INCLUDE_AARCH32_REGS
+       ldr     x11, [x0, #CTX_FP_FPEXC32_EL2]
+       msr     fpexc32_el2, x11
+#endif
        /*
         * No explict ISB required here as ERET to
         * switch to secure EL1 or non-secure world