summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm64/cpu.c39
-rw-r--r--src/arch/arm64/include/armv8/arch/lib_helpers.h37
2 files changed, 75 insertions, 1 deletions
diff --git a/src/arch/arm64/cpu.c b/src/arch/arm64/cpu.c
index 0f9e874a3f..396c5b7ce9 100644
--- a/src/arch/arm64/cpu.c
+++ b/src/arch/arm64/cpu.c
@@ -84,6 +84,43 @@ static int cpu_set_device_operations(device_t dev)
return 0;
}
+/* Set up default SCR values. */
+static void el3_init(void)
+{
+ uint32_t scr;
+
+ if (get_current_el() != EL3)
+ return;
+
+ scr = raw_read_scr_el3();
+ /* Default to non-secure EL1 and EL0. */
+ scr &= ~(SCR_NS_MASK);
+ scr |= SCR_NS_ENABLE;
+ /* Disable IRQ, FIQ, and external abort interrupt routing. */
+ scr &= ~(SCR_IRQ_MASK | SCR_FIQ_MASK | SCR_EA_MASK);
+ scr |= SCR_IRQ_DISABLE | SCR_FIQ_DISABLE | SCR_EA_DISABLE;
+ /* Enable HVC */
+ scr &= ~(SCR_HVC_MASK);
+ scr |= SCR_HVC_ENABLE;
+ /* Disable SMC */
+ scr &= ~(SCR_SMC_MASK);
+ scr |= SCR_SMC_DISABLE;
+ /* Disable secure instruction fetches. */
+ scr &= ~(SCR_SIF_MASK);
+ scr |= SCR_SIF_DISABLE;
+ /* All lower exception levels 64-bit by default. */
+ scr &= ~(SCR_RW_MASK);
+ scr |= SCR_LOWER_AARCH64;
+ /* Disable secure EL1 access to secure timer. */
+ scr &= ~(SCR_ST_MASK);
+ scr |= SCR_ST_DISABLE;
+ /* Don't trap on WFE or WFI instructions. */
+ scr &= ~(SCR_TWI_MASK | SCR_TWE_MASK);
+ scr |= SCR_TWI_DISABLE | SCR_TWE_DISABLE;
+ raw_write_scr_el3(scr);
+ isb();
+}
+
static void init_this_cpu(void *arg)
{
struct cpu_info *ci = arg;
@@ -91,6 +128,8 @@ static void init_this_cpu(void *arg)
cpu_set_device_operations(dev);
+ el3_init();
+
/* Initialize the GIC. */
gic_init();
diff --git a/src/arch/arm64/include/armv8/arch/lib_helpers.h b/src/arch/arm64/include/armv8/arch/lib_helpers.h
index ee41716b41..248a1ea90c 100644
--- a/src/arch/arm64/include/armv8/arch/lib_helpers.h
+++ b/src/arch/arm64/include/armv8/arch/lib_helpers.h
@@ -52,17 +52,52 @@
#define SPSR_DEBUG_MASK (0 << SPSR_DEBUG_SHIFT)
#define SPSR_DEBUG_ENABLE (1 << SPSR_DEBUG_SHIFT)
-#define SCR_NS 1
+#define SCR_NS_SHIFT 0
+#define SCR_NS_MASK (1 << SCR_NS_SHIFT)
+#define SCR_NS_ENABLE (1 << SCR_NS_SHIFT)
+#define SCR_NS_DISABLE (0 << SCR_NS_SHIFT)
+#define SCR_NS SCR_NS_ENABLE
#define SCR_RES1 (0x3 << 4)
+#define SCR_IRQ_SHIFT 2
+#define SCR_IRQ_MASK (1 << SCR_IRQ_SHIFT)
+#define SCR_IRQ_ENABLE (1 << SCR_IRQ_SHIFT)
+#define SCR_IRQ_DISABLE (0 << SCR_IRQ_SHIFT)
+#define SCR_FIQ_SHIFT 2
+#define SCR_FIQ_MASK (1 << SCR_FIQ_SHIFT)
+#define SCR_FIQ_ENABLE (1 << SCR_FIQ_SHIFT)
+#define SCR_FIQ_DISABLE (0 << SCR_FIQ_SHIFT)
+#define SCR_EA_SHIFT 3
+#define SCR_EA_MASK (1 << SCR_EA_SHIFT)
+#define SCR_EA_ENABLE (1 << SCR_EA_SHIFT)
+#define SCR_EA_DISABLE (0 << SCR_EA_SHIFT)
#define SCR_SMC_SHIFT 7
+#define SCR_SMC_MASK (1 << SCR_SMC_SHIFT)
#define SCR_SMC_DISABLE (1 << SCR_SMC_SHIFT)
#define SCR_SMC_ENABLE (0 << SCR_SMC_SHIFT)
#define SCR_HVC_SHIFT 8
+#define SCR_HVC_MASK (1 << SCR_HVC_SHIFT)
#define SCR_HVC_DISABLE (0 << SCR_HVC_SHIFT)
#define SCR_HVC_ENABLE (1 << SCR_HVC_SHIFT)
+#define SCR_SIF_SHIFT 9
+#define SCR_SIF_MASK (1 << SCR_SIF_SHIFT)
+#define SCR_SIF_ENABLE (1 << SCR_SIF_SHIFT)
+#define SCR_SIF_DISABLE (0 << SCR_SIF_SHIFT)
#define SCR_RW_SHIFT 10
+#define SCR_RW_MASK (1 << SCR_RW_SHIFT)
#define SCR_LOWER_AARCH64 (1 << SCR_RW_SHIFT)
#define SCR_LOWER_AARCH32 (0 << SCR_RW_SHIFT)
+#define SCR_ST_SHIFT 11
+#define SCR_ST_MASK (1 << SCR_ST_SHIFT)
+#define SCR_ST_ENABLE (1 << SCR_ST_SHIFT)
+#define SCR_ST_DISABLE (0 << SCR_ST_SHIFT)
+#define SCR_TWI_SHIFT 12
+#define SCR_TWI_MASK (1 << SCR_TWI_SHIFT)
+#define SCR_TWI_ENABLE (1 << SCR_TWI_SHIFT)
+#define SCR_TWI_DISABLE (0 << SCR_TWI_SHIFT)
+#define SCR_TWE_SHIFT 13
+#define SCR_TWE_MASK (1 << SCR_TWE_SHIFT)
+#define SCR_TWE_ENABLE (1 << SCR_TWE_SHIFT)
+#define SCR_TWE_DISABLE (0 << SCR_TWE_SHIFT)
#define HCR_RW_SHIFT 31
#define HCR_LOWER_AARCH64 (1 << HCR_RW_SHIFT)