Commit 23ff9baa authored by Vikram Kanigiri's avatar Vikram Kanigiri
Browse files

Introduce macros to manipulate the SPSR

This patch introduces macros (SPSR_64 and SPSR_32) to
create a SPSR for both aarch32 and aarch64 execution
states. These macros allow the user to set fields
in the SPSR depending upon its format.
The make_spsr() function which did not allow
manipulation of all the fields in the aarch32 SPSR
has been replaced by these new macros.

Change-Id: I9425dda0923e8d5f03d03ddb8fa0e28392c4c61e
parent ec786cbc
...@@ -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