diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/arm64/cpu.c | 39 | ||||
-rw-r--r-- | src/arch/arm64/include/armv8/arch/lib_helpers.h | 37 |
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) |