Commit cfd102d6 authored by Vikram Kanigiri's avatar Vikram Kanigiri
Browse files

Extend SPSR definitions for full use of ELx modes

Extended SPSR definitions with all the fields to allow full use
of EL2/EL1 execution modes for entry points
Replaced make_spsr() with SPSR_64 macro and added SPSR_32 macro
for generating AARCH32 mode SPSR

Change-Id: I9425dda0923e8d5f03d03ddb8fa0e28392c4c61e
parent ec786cbc
Showing with 69 additions and 49 deletions
+69 -49
...@@ -95,7 +95,7 @@ void bl1_main(void) ...@@ -95,7 +95,7 @@ void bl1_main(void)
if (bl2_base) { if (bl2_base) {
bl1_arch_next_el_setup(); bl1_arch_next_el_setup();
spsr = make_spsr(MODE_EL1, MODE_SP_ELX, MODE_RW_64); spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
printf("Booting trusted firmware boot loader stage 2\n\r"); printf("Booting trusted firmware boot loader stage 2\n\r");
#if DEBUG #if DEBUG
printf("BL2 address = 0x%llx \n\r", (unsigned long long) bl2_base); printf("BL2 address = 0x%llx \n\r", (unsigned long long) bl2_base);
......
...@@ -140,7 +140,7 @@ void bl2_main(void) ...@@ -140,7 +140,7 @@ void bl2_main(void)
* well. * well.
*/ */
bl2_to_bl31_args->bl33_image_info.spsr = bl2_to_bl31_args->bl33_image_info.spsr =
make_spsr(mode, MODE_SP_ELX, MODE_RW_64); SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
bl2_to_bl31_args->bl33_image_info.security_state = NON_SECURE; bl2_to_bl31_args->bl33_image_info.security_state = NON_SECURE;
if (bl32_base) { if (bl32_base) {
...@@ -165,7 +165,7 @@ void bl2_main(void) ...@@ -165,7 +165,7 @@ void bl2_main(void)
* BL31 as an argument. * BL31 as an argument.
*/ */
run_image(bl31_base, run_image(bl31_base,
make_spsr(MODE_EL3, MODE_SP_ELX, MODE_RW_64), SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
SECURE, SECURE,
(void *) bl2_to_bl31_args, (void *) bl2_to_bl31_args,
NULL); NULL);
......
...@@ -122,20 +122,6 @@ void __dead2 change_el(el_change_info_t *info) ...@@ -122,20 +122,6 @@ void __dead2 change_el(el_change_info_t *info)
raise_el(&info->args); raise_el(&info->args);
} }
/* TODO: add a parameter for DAIF. not needed right now */
unsigned long make_spsr(unsigned long target_el,
unsigned long target_sp,
unsigned long target_rw)
{
unsigned long spsr;
/* Disable all exceptions & setup the EL */
spsr = (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
<< PSR_DAIF_SHIFT;
spsr |= PSR_MODE(target_rw, target_el, target_sp);
return spsr;
}
/******************************************************************************* /*******************************************************************************
* The next two functions are the weak definitions. Platform specific * The next two functions are the weak definitions. Platform specific
......
...@@ -118,7 +118,6 @@ extern void change_security_state(unsigned int); ...@@ -118,7 +118,6 @@ extern void change_security_state(unsigned int);
extern void __dead2 drop_el(aapcs64_params_t *, unsigned long, unsigned long); extern void __dead2 drop_el(aapcs64_params_t *, unsigned long, unsigned long);
extern void __dead2 raise_el(aapcs64_params_t *); extern void __dead2 raise_el(aapcs64_params_t *);
extern void __dead2 change_el(el_change_info_t *); extern void __dead2 change_el(el_change_info_t *);
extern unsigned long make_spsr(unsigned long, unsigned long, unsigned long);
extern void init_bl2_mem_layout(meminfo_t *, extern void init_bl2_mem_layout(meminfo_t *,
meminfo_t *, meminfo_t *,
unsigned int, unsigned int,
......
...@@ -175,7 +175,25 @@ ...@@ -175,7 +175,25 @@
#define DAIF_IRQ_BIT (1 << 1) #define DAIF_IRQ_BIT (1 << 1)
#define DAIF_ABT_BIT (1 << 2) #define DAIF_ABT_BIT (1 << 2)
#define DAIF_DBG_BIT (1 << 3) #define DAIF_DBG_BIT (1 << 3)
#define PSR_DAIF_SHIFT 0x6 #define SPSR_DAIF_SHIFT 6
#define SPSR_DAIF_MASK 0xf
#define SPSR_AIF_SHIFT 6
#define SPSR_AIF_MASK 0x7
#define SPSR_E_SHIFT 9
#define SPSR_E_MASK 0x1
#define SPSR_E_LITTLE 0x0
#define SPSR_E_BIG 0x1
#define SPSR_T_SHIFT 5
#define SPSR_T_MASK 0x1
#define SPSR_T_ARM 0x0
#define SPSR_T_THUMB 0x1
#define DISABLE_ALL_EXCEPTIONS \
(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
/* /*
* TCR defintions * TCR defintions
...@@ -198,29 +216,53 @@ ...@@ -198,29 +216,53 @@
#define TCR_SH_OUTER_SHAREABLE (0x2 << 12) #define TCR_SH_OUTER_SHAREABLE (0x2 << 12)
#define TCR_SH_INNER_SHAREABLE (0x3 << 12) #define TCR_SH_INNER_SHAREABLE (0x3 << 12)
#define MODE_RW_64 0x0 #define MODE_SP_SHIFT 0x0
#define MODE_RW_32 0x1 #define MODE_SP_MASK 0x1
#define MODE_SP_EL0 0x0 #define MODE_SP_EL0 0x0
#define MODE_SP_ELX 0x1 #define MODE_SP_ELX 0x1
#define MODE_RW_SHIFT 0x4
#define MODE_RW_MASK 0x1
#define MODE_RW_64 0x0
#define MODE_RW_32 0x1
#define MODE_EL_SHIFT 0x2
#define MODE_EL_MASK 0x3
#define MODE_EL3 0x3 #define MODE_EL3 0x3
#define MODE_EL2 0x2 #define MODE_EL2 0x2
#define MODE_EL1 0x1 #define MODE_EL1 0x1
#define MODE_EL0 0x0 #define MODE_EL0 0x0
#define MODE_RW_SHIFT 0x4 #define MODE32_SHIFT 0
#define MODE_EL_SHIFT 0x2 #define MODE32_MASK 0xf
#define MODE_SP_SHIFT 0x0 #define MODE32_usr 0x0
#define MODE32_fiq 0x1
#define GET_RW(mode) ((mode >> MODE_RW_SHIFT) & 0x1) #define MODE32_irq 0x2
#define GET_EL(mode) ((mode >> MODE_EL_SHIFT) & 0x3) #define MODE32_svc 0x3
#define PSR_MODE(rw, el, sp) (rw << MODE_RW_SHIFT | el << MODE_EL_SHIFT \ #define MODE32_mon 0x6
| sp << MODE_SP_SHIFT) #define MODE32_abt 0x7
#define MODE32_hyp 0xa
#define SPSR32_EE_BIT (1 << 9) #define MODE32_und 0xb
#define SPSR32_T_BIT (1 << 5) #define MODE32_sys 0xf
#define GET_RW(mode) (((mode) >> MODE_RW_SHIFT) & MODE_RW_MASK)
#define GET_EL(mode) (((mode) >> MODE_EL_SHIFT) & MODE_EL_MASK)
#define GET_SP(mode) (((mode) >> MODE_SP_SHIFT) & MODE_SP_MASK)
#define GET_M32(mode) (((mode) >> MODE32_SHIFT) & MODE32_MASK)
#define SPSR_64(el, sp, daif) \
(MODE_RW_64 << MODE_RW_SHIFT | \
((el) & MODE_EL_MASK) << MODE_EL_SHIFT | \
((sp) & MODE_SP_MASK) << MODE_SP_SHIFT | \
((daif) & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT)
#define SPSR_MODE32(mode, isa, endian, aif) \
(MODE_RW_32 << MODE_RW_SHIFT | \
((mode) & MODE32_MASK) << MODE32_SHIFT | \
((isa) & SPSR_T_MASK) << SPSR_T_SHIFT | \
((endian) & SPSR_E_MASK) << SPSR_E_SHIFT | \
((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT)
#define AARCH32_MODE_SVC 0x13
#define AARCH32_MODE_HYP 0x1a
/* Miscellaneous MMU related constants */ /* Miscellaneous MMU related constants */
#define NUM_2MB_IN_GB (1 << 9) #define NUM_2MB_IN_GB (1 << 9)
......
...@@ -91,7 +91,7 @@ int32_t tspd_init_secure_context(uint64_t entrypoint, ...@@ -91,7 +91,7 @@ int32_t tspd_init_secure_context(uint64_t entrypoint,
tsp_ctx->mpidr = mpidr; tsp_ctx->mpidr = mpidr;
cm_set_context(mpidr, &tsp_ctx->cpu_ctx, SECURE); cm_set_context(mpidr, &tsp_ctx->cpu_ctx, SECURE);
spsr = make_spsr(MODE_EL1, MODE_SP_ELX, rw); spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
cm_set_el3_eret_context(SECURE, entrypoint, spsr, scr); cm_set_el3_eret_context(SECURE, entrypoint, spsr, scr);
return 0; return 0;
......
...@@ -303,6 +303,7 @@ int psci_set_ns_entry_info(unsigned int index, ...@@ -303,6 +303,7 @@ int psci_set_ns_entry_info(unsigned int index,
unsigned int rw, mode, ee, spsr = 0; unsigned int rw, mode, ee, spsr = 0;
unsigned long id_aa64pfr0 = read_id_aa64pfr0_el1(), scr = read_scr(); unsigned long id_aa64pfr0 = read_id_aa64pfr0_el1(), scr = read_scr();
unsigned long el_status; unsigned long el_status;
unsigned long daif;
/* Figure out what mode do we enter the non-secure world in */ /* Figure out what mode do we enter the non-secure world in */
el_status = (id_aa64pfr0 >> ID_AA64PFR0_EL2_SHIFT) & el_status = (id_aa64pfr0 >> ID_AA64PFR0_EL2_SHIFT) &
...@@ -330,24 +331,18 @@ int psci_set_ns_entry_info(unsigned int index, ...@@ -330,24 +331,18 @@ int psci_set_ns_entry_info(unsigned int index,
ee = read_sctlr_el1() & SCTLR_EE_BIT; ee = read_sctlr_el1() & SCTLR_EE_BIT;
} }
spsr = DAIF_DBG_BIT | DAIF_ABT_BIT; spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
spsr |= DAIF_IRQ_BIT | DAIF_FIQ_BIT;
spsr <<= PSR_DAIF_SHIFT;
spsr |= make_spsr(mode, MODE_SP_ELX, !rw);
psci_ns_entry_info[index].sctlr |= ee; psci_ns_entry_info[index].sctlr |= ee;
psci_ns_entry_info[index].scr |= SCR_RW_BIT; psci_ns_entry_info[index].scr |= SCR_RW_BIT;
} else { } else {
/* Check whether aarch32 has to be entered in Thumb mode */
if (entrypoint & 0x1)
spsr = SPSR32_T_BIT;
if (el_status && (scr & SCR_HCE_BIT)) { if (el_status && (scr & SCR_HCE_BIT)) {
mode = AARCH32_MODE_HYP; mode = MODE32_hyp;
ee = read_sctlr_el2() & SCTLR_EE_BIT; ee = read_sctlr_el2() & SCTLR_EE_BIT;
} else { } else {
mode = AARCH32_MODE_SVC; mode = MODE32_svc;
ee = read_sctlr_el1() & SCTLR_EE_BIT; ee = read_sctlr_el1() & SCTLR_EE_BIT;
} }
...@@ -355,11 +350,9 @@ int psci_set_ns_entry_info(unsigned int index, ...@@ -355,11 +350,9 @@ int psci_set_ns_entry_info(unsigned int index,
* TODO: Choose async. exception bits if HYP mode is not * TODO: Choose async. exception bits if HYP mode is not
* implemented according to the values of SCR.{AW, FW} bits * implemented according to the values of SCR.{AW, FW} bits
*/ */
spsr |= DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT; daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
spsr <<= PSR_DAIF_SHIFT;
if (ee) spsr = SPSR_MODE32(mode, entrypoint & 0x1, ee, daif);
spsr |= SPSR32_EE_BIT;
spsr |= mode;
/* Ensure that the CSPR.E and SCTLR.EE bits match */ /* Ensure that the CSPR.E and SCTLR.EE bits match */
psci_ns_entry_info[index].sctlr |= ee; psci_ns_entry_info[index].sctlr |= ee;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment