Add build configuration for timer save/restore
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>
Mon, 12 May 2014 14:28:47 +0000 (15:28 +0100)
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>
Fri, 16 May 2014 16:11:31 +0000 (17:11 +0100)
At present, non-secure timer register contents are saved and restored as
part of world switch by BL3-1. This effectively means that the
non-secure timer stops, and non-secure timer interrupts are prevented
from asserting until BL3-1 switches back, introducing latency for
non-secure services. Often, secure world might depend on alternate
sources for secure interrupts (secure timer or platform timer) instead
of non-secure timers, in which case this save and restore is
unnecessary.

This patch introduces a boolean build-time configuration NS_TIMER_SWITCH
to choose whether or not to save and restore non-secure timer registers
upon world switch. The default choice is made not to save and restore
them.

Fixes ARM-software/tf-issues#148

Change-Id: I1b9d623606acb9797c3e0b02fb5ec7c0a414f37e

Makefile
bl31/aarch64/context.S
docs/user-guide.md
include/bl31/context.h

index fc6c46914ef6135c93b796523ed00a8567ec8755..94dde7f7e82fabaf29fefa5cae82e0f7ac96b993 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,8 @@ PLAT                  := ${DEFAULT_PLAT}
 SPD                    := none
 # Base commit to perform code check on
 BASE_COMMIT            := origin/master
+# NS timer register save and restore
+NS_TIMER_SWITCH                := 0
 
 
 # Checkpatch ignores
@@ -171,6 +173,10 @@ CFLAGS                     +=      -g
 ASFLAGS                        +=      -g -Wa,--gdwarf-2
 endif
 
+# Process NS_TIMER_SWITCH flag
+$(eval $(call assert_boolean,NS_TIMER_SWITCH))
+$(eval $(call add_define,NS_TIMER_SWITCH))
+
 ASFLAGS                        +=      -nostdinc -ffreestanding -Wa,--fatal-warnings   \
                                -mgeneral-regs-only -D__ASSEMBLY__              \
                                ${DEFINES} ${INCLUDES}
index 45d4a2255d8cbbbc591a3407f00bdb89c76c5e7c..d0bca64fccad4f6a7f037c4e982c66ae476f1bf0 100644 (file)
@@ -172,6 +172,8 @@ func el1_sysregs_context_save
        mrs     x9, vbar_el1
        stp     x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
 
+       /* Save NS timer registers if the build has instructed so */
+#if NS_TIMER_SWITCH
        mrs     x10, cntp_ctl_el0
        mrs     x11, cntp_cval_el0
        stp     x10, x11, [x0, #CTX_CNTP_CTL_EL0]
@@ -181,8 +183,11 @@ func el1_sysregs_context_save
        stp     x12, x13, [x0, #CTX_CNTV_CTL_EL0]
 
        mrs     x14, cntkctl_el1
+       str     x14, [x0, #CTX_CNTKCTL_EL1]
+#endif
+
        mrs     x15, fpexc32_el2
-       stp     x14, x15, [x0, #CTX_CNTKCTL_EL1]
+       str     x15, [x0, #CTX_FP_FPEXC32_EL2]
 
        ret
 
@@ -253,6 +258,8 @@ func el1_sysregs_context_restore
        msr     contextidr_el1, x17
        msr     vbar_el1, x9
 
+       /* Restore NS timer registers if the build has instructed so */
+#if NS_TIMER_SWITCH
        ldp     x10, x11, [x0, #CTX_CNTP_CTL_EL0]
        msr     cntp_ctl_el0, x10
        msr     cntp_cval_el0, x11
@@ -261,8 +268,11 @@ func el1_sysregs_context_restore
        msr     cntv_ctl_el0, x12
        msr     cntv_cval_el0, x13
 
-       ldp     x14, x15, [x0, #CTX_CNTKCTL_EL1]
+       ldr     x14, [x0, #CTX_CNTKCTL_EL1]
        msr     cntkctl_el1, x14
+#endif
+
+       ldr     x15, [x0, #CTX_FP_FPEXC32_EL2]
        msr     fpexc32_el2, x15
 
        /* No explict ISB required here as ERET covers it */
index edf03f0a4b762f35c90bc3103b24f5e0c4b669f4..e7f0df54cea27a6a59a78dd7647c662769394b7d 100644 (file)
@@ -141,6 +141,11 @@ performed.
 *   `DEBUG`: Chooses between a debug and release build. It can take either 0
     (release) or 1 (debug) as values. 0 is the default
 
+*   `NS_TIMER_SWITCH`: Enable save and restore for non-secure timer register
+    contents upon world switch. It can take either 0 (don't save and restore) or
+    1 (do save and restore). 0 is the default. An SPD could set this to 1 if it
+    wants the timer registers to be saved and restored
+
 *   `PLAT`: Choose a platform to build ARM Trusted Firmware for. The chosen
     platform name must be the name of one of the directories under the `plat/`
     directory other than `common`
index 549fa2127553a842258fa27a02dd5468f8dea96c..b0dfec15dfc560aef51325a5b536c35e0862fc08 100644 (file)
 #define CTX_AFSR1_EL1          0xc8
 #define CTX_CONTEXTIDR_EL1     0xd0
 #define CTX_VBAR_EL1           0xd8
+/*
+ * If the timer registers aren't saved and restored, we don't have to reserve
+ * space for them in the context
+ */
+#if NS_TIMER_SWITCH
 #define CTX_CNTP_CTL_EL0       0xe0
 #define CTX_CNTP_CVAL_EL0      0xe8
 #define CTX_CNTV_CTL_EL0       0xf0
 #define CTX_CNTKCTL_EL1                0x100
 #define CTX_FP_FPEXC32_EL2     0x108
 #define CTX_SYSREGS_END                0x110
+#else
+#define CTX_FP_FPEXC32_EL2     0xe0
+#define CTX_SYSREGS_END                0xf0
+#endif
 
 /*******************************************************************************
  * Constants that allow assembler code to access members of and the 'fp_regs'