diff options
author | Andre Przywara <andre.przywara@arm.com> | 2016-02-23 14:44:59 +0000 |
---|---|---|
committer | Andre Przywara <andre.przywara@arm.com> | 2016-06-02 01:28:14 +0100 |
commit | 381da090e4502124a1753a0947574b830f4ef154 (patch) | |
tree | 2b8f2801d6c4ce6f2511e9aadce8e13316dc916a /plat | |
parent | cccc0efed321582e3605e38c9b4f352569262ee1 (diff) |
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 <andre.przywara@arm.com>
Diffstat (limited to 'plat')
-rw-r--r-- | plat/sun50iw1p1/aarch64/sunxi_common.c | 56 | ||||
-rw-r--r-- | plat/sun50iw1p1/bl31_sunxi_setup.c | 4 | ||||
-rw-r--r-- | plat/sun50iw1p1/sunxi_private.h | 2 |
3 files changed, 40 insertions, 22 deletions
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__ */ |