From 381da090e4502124a1753a0947574b830f4ef154 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 23 Feb 2016 14:44:59 +0000 Subject: sun50i: introduce get_highest_el() functionality Add a function to get the highest implemented exception level and use that for entering BL3-3 in. Also we make the bit-size we enter non-secure world a parameter, so that we can easily switch between AArch32 and AArch64. (HACK: Keep entering U-Boot still in AArch32 SVC for now.) Signed-off-by: Andre Przywara --- plat/sun50iw1p1/aarch64/sunxi_common.c | 56 ++++++++++++++++++++++------------ plat/sun50iw1p1/bl31_sunxi_setup.c | 4 +-- plat/sun50iw1p1/sunxi_private.h | 2 +- 3 files changed, 40 insertions(+), 22 deletions(-) (limited to 'plat/sun50iw1p1') diff --git a/plat/sun50iw1p1/aarch64/sunxi_common.c b/plat/sun50iw1p1/aarch64/sunxi_common.c index efa24d4..1e4dd3c 100644 --- a/plat/sun50iw1p1/aarch64/sunxi_common.c +++ b/plat/sun50iw1p1/aarch64/sunxi_common.c @@ -95,31 +95,49 @@ uint64_t plat_get_syscnt_freq(void) return 24 * 1000 * 1000; } +static unsigned int get_highest_el(int aarch) +{ + unsigned int el_status; + + /* Figure out whether we have the HYP/EL2 mode implemented */ + if (aarch == 32) { + el_status = (read_id_pfr1_el1() >> ID_PFR1_VIRTEXT_SHIFT); + el_status &= ID_PFR1_VIRTEXT_MASK; + + return el_status ? MODE32_hyp : MODE32_svc; + } else if (aarch == 64) { + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + return el_status ? MODE_EL2 : MODE_EL1; + } else { + return -1; + } +} + /******************************************************************************* * Gets SPSR for BL33 entry ******************************************************************************/ -uint32_t sunxi_get_spsr_for_bl33_entry(void) +uint32_t sunxi_get_spsr_for_bl33_entry(int aarch) { - unsigned long el_status; unsigned int mode; uint32_t spsr; - /* Figure out what mode we enter the non-secure world in */ - el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; - el_status &= ID_AA64PFR0_ELX_MASK; - - if (el_status) - mode = MODE_EL2; - else - mode = MODE_EL1; - - /* - * TODO: Consider the possibility of specifying the SPSR in - * the FIP ToC and allowing the platform to have a say as - * well. - */ - spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); - spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, - DISABLE_ALL_EXCEPTIONS); + mode = get_highest_el(aarch); + + switch (aarch) { + case 32: + /* HACK: keep entering U-Boot in SVC for now */ + mode = MODE32_svc; + + spsr = SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS); + break; + case 64: + default: + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + break; + } + return spsr; } diff --git a/plat/sun50iw1p1/bl31_sunxi_setup.c b/plat/sun50iw1p1/bl31_sunxi_setup.c index c39db14..ed33797 100644 --- a/plat/sun50iw1p1/bl31_sunxi_setup.c +++ b/plat/sun50iw1p1/bl31_sunxi_setup.c @@ -155,7 +155,7 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, * is located and the entry state information */ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); - bl33_image_ep_info.spsr = sunxi_get_spsr_for_bl33_entry(); + bl33_image_ep_info.spsr = sunxi_get_spsr_for_bl33_entry(32); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); #else @@ -183,7 +183,7 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, * is located and the entry state information */ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); - bl33_image_ep_info.spsr = sunxi_get_spsr_for_bl33_entry(); + bl33_image_ep_info.spsr = sunxi_get_spsr_for_bl33_entry(32); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); diff --git a/plat/sun50iw1p1/sunxi_private.h b/plat/sun50iw1p1/sunxi_private.h index 928bcea..3dc5ced 100644 --- a/plat/sun50iw1p1/sunxi_private.h +++ b/plat/sun50iw1p1/sunxi_private.h @@ -78,7 +78,7 @@ void sunxi_io_setup(void); void sunxi_security_setup(void); /* Gets the SPSR for BL33 entry */ -uint32_t sunxi_get_spsr_for_bl33_entry(void); +uint32_t sunxi_get_spsr_for_bl33_entry(int aarch); #endif /* __SUNXI_PRIVATE_H__ */ -- cgit v1.2.3