arm64: initialize SCR_EL3 on all CPUs

Provide SCR_EL3 initialization on all CPUs. This settings were
chosen in such a way that nothing would need to be done if EL3
is abandoned after transitioning to EL2 or EL1. If persistent
EL3 program is used those SCR policies can be updated within
that program.

BUG=chrome-os-partner:31634
BRANCH=None
TEST=Built and booted through kernel. Printed out SCR setting for
     each CPU.

Change-Id: Ib44acd8ae40dbca590740340632f5b72998e9dd8
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: f77b903afbafad7d439ec50fc48f1eaa37827d90
Original-Change-Id: Id659f0a98360fe8bbc80e5a623eba1526e81b400
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/218300
Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: http://review.coreboot.org/9078
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Aaron Durbin 2014-09-15 14:19:21 -05:00 committed by Patrick Georgi
parent 5985936411
commit f228e8d435
2 changed files with 75 additions and 1 deletions

View File

@ -84,6 +84,43 @@ static int cpu_set_device_operations(device_t dev)
return 0; 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) static void init_this_cpu(void *arg)
{ {
struct cpu_info *ci = arg; struct cpu_info *ci = arg;
@ -91,6 +128,8 @@ static void init_this_cpu(void *arg)
cpu_set_device_operations(dev); cpu_set_device_operations(dev);
el3_init();
/* Initialize the GIC. */ /* Initialize the GIC. */
gic_init(); gic_init();

View File

@ -52,17 +52,52 @@
#define SPSR_DEBUG_MASK (0 << SPSR_DEBUG_SHIFT) #define SPSR_DEBUG_MASK (0 << SPSR_DEBUG_SHIFT)
#define SPSR_DEBUG_ENABLE (1 << 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_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_SHIFT 7
#define SCR_SMC_MASK (1 << SCR_SMC_SHIFT)
#define SCR_SMC_DISABLE (1 << SCR_SMC_SHIFT) #define SCR_SMC_DISABLE (1 << SCR_SMC_SHIFT)
#define SCR_SMC_ENABLE (0 << SCR_SMC_SHIFT) #define SCR_SMC_ENABLE (0 << SCR_SMC_SHIFT)
#define SCR_HVC_SHIFT 8 #define SCR_HVC_SHIFT 8
#define SCR_HVC_MASK (1 << SCR_HVC_SHIFT)
#define SCR_HVC_DISABLE (0 << SCR_HVC_SHIFT) #define SCR_HVC_DISABLE (0 << SCR_HVC_SHIFT)
#define SCR_HVC_ENABLE (1 << 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_SHIFT 10
#define SCR_RW_MASK (1 << SCR_RW_SHIFT)
#define SCR_LOWER_AARCH64 (1 << SCR_RW_SHIFT) #define SCR_LOWER_AARCH64 (1 << SCR_RW_SHIFT)
#define SCR_LOWER_AARCH32 (0 << 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_RW_SHIFT 31
#define HCR_LOWER_AARCH64 (1 << HCR_RW_SHIFT) #define HCR_LOWER_AARCH64 (1 << HCR_RW_SHIFT)