feat(rme): add context management changes for FEAT_RME
This patch adds a new context for realm world and realm world
awareness in context management.
Signed-off-by: Zelalem Aweke <zelalem.aweke@arm.com>
Signed-off-by: Subhasish Ghosh <subhasish.ghosh@arm.com>
Change-Id: Ic17469393603e789d7adc025880346bc3d6233d7
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 08022d4..0ec7e7e 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -93,24 +93,41 @@
scr_el3 = read_scr();
scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
SCR_ST_BIT | SCR_HCE_BIT);
+
+#if ENABLE_RME
+ /* When RME support is enabled, clear the NSE bit as well. */
+ scr_el3 &= ~SCR_NSE_BIT;
+#endif /* ENABLE_RME */
+
/*
* SCR_NS: Set the security state of the next EL.
*/
- if (security_state != SECURE)
+ if (security_state == NON_SECURE) {
scr_el3 |= SCR_NS_BIT;
+ }
+
+#if ENABLE_RME
+ /* Check for realm state if RME support enabled. */
+ if (security_state == REALM) {
+ scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT;
+ }
+#endif /* ENABLE_RME */
+
/*
* SCR_EL3.RW: Set the execution state, AArch32 or AArch64, for next
* Exception level as specified by SPSR.
*/
- if (GET_RW(ep->spsr) == MODE_RW_64)
+ if (GET_RW(ep->spsr) == MODE_RW_64) {
scr_el3 |= SCR_RW_BIT;
+ }
/*
* SCR_EL3.ST: Traps Secure EL1 accesses to the Counter-timer Physical
* Secure timer registers to EL3, from AArch64 state only, if specified
* by the entrypoint attributes.
*/
- if (EP_GET_ST(ep->h.attr) != 0U)
+ if (EP_GET_ST(ep->h.attr) != 0U) {
scr_el3 |= SCR_ST_BIT;
+ }
/*
* If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting
@@ -152,8 +169,9 @@
* If the Secure world wants to use pointer authentication,
* CTX_INCLUDE_PAUTH_REGS must be set to 1.
*/
- if (security_state == NON_SECURE)
+ if (security_state == NON_SECURE) {
scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+ }
#endif /* !CTX_INCLUDE_PAUTH_REGS */
#if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS
@@ -188,8 +206,14 @@
/*
* SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
* indicated by the interrupt routing model for BL31.
+ *
+ * TODO: The interrupt routing model code is not updated for REALM
+ * state. Use the default values of IRQ = FIQ = 0 for REALM security
+ * state for now.
*/
- scr_el3 |= get_scr_el3_from_routing_model(security_state);
+ if (security_state != REALM) {
+ scr_el3 |= get_scr_el3_from_routing_model(security_state);
+ }
#endif
/* Save the initialized value of CPTR_EL3 register */
@@ -256,9 +280,9 @@
* required by PSCI specification)
*/
sctlr_elx = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0U;
- if (GET_RW(ep->spsr) == MODE_RW_64)
+ if (GET_RW(ep->spsr) == MODE_RW_64) {
sctlr_elx |= SCTLR_EL1_RES1;
- else {
+ } else {
/*
* If the target execution state is AArch32 then the following
* fields need to be set.
@@ -413,7 +437,8 @@
}
/*******************************************************************************
- * Prepare the CPU system registers for first entry into secure or normal world
+ * Prepare the CPU system registers for first entry into realm, secure, or
+ * normal world.
*
* If execution is requested to EL2 or hyp mode, SCTLR_EL2 is initialized
* If execution is requested to non-secure EL1 or svc mode, and the CPU supports
@@ -497,7 +522,7 @@
* architecturally UNKNOWN on reset and are set to zero
* except for field(s) listed below.
*
- * CNTHCTL_EL2.EL1PCEN: Set to one to disable traps to
+ * CNTHCTL_EL2.EL1PTEN: Set to one to disable traps to
* Hyp mode of Non-secure EL0 and EL1 accesses to the
* physical timer registers.
*
@@ -645,10 +670,10 @@
u_register_t scr_el3 = read_scr();
/*
- * Always save the non-secure EL2 context, only save the
+ * Always save the non-secure and realm EL2 context, only save the
* S-EL2 context if S-EL2 is enabled.
*/
- if ((security_state == NON_SECURE) ||
+ if ((security_state != SECURE) ||
((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
cpu_context_t *ctx;
@@ -667,10 +692,10 @@
u_register_t scr_el3 = read_scr();
/*
- * Always restore the non-secure EL2 context, only restore the
+ * Always restore the non-secure and realm EL2 context, only restore the
* S-EL2 context if S-EL2 is enabled.
*/
- if ((security_state == NON_SECURE) ||
+ if ((security_state != SECURE) ||
((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
cpu_context_t *ctx;