summaryrefslogtreecommitdiff
path: root/plat
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2016-02-23 14:44:59 +0000
committerAndre Przywara <andre.przywara@arm.com>2016-06-02 01:28:14 +0100
commit381da090e4502124a1753a0947574b830f4ef154 (patch)
tree2b8f2801d6c4ce6f2511e9aadce8e13316dc916a /plat
parentcccc0efed321582e3605e38c9b4f352569262ee1 (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.c56
-rw-r--r--plat/sun50iw1p1/bl31_sunxi_setup.c4
-rw-r--r--plat/sun50iw1p1/sunxi_private.h2
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__ */