refactor(sdei): use common create_spsr() in SDEI library
The current SPSR updation code as part of the SDEI interrupt handler
code is outdated. This patch replaces the legacy code with a call to
an up-to-date create_spsr()
Change-Id: I1f5fdd41dd14f4b09601310fe881fa3783d7f505
Signed-off-by: Arvind Ram Prakash <arvind.ramprakash@arm.com>
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
index d14a91e..f1b1fa6 100644
--- a/bl31/bl31_traps.c
+++ b/bl31/bl31_traps.c
@@ -97,7 +97,7 @@
* NOTE: This piece of code must be reviewed every release to ensure that
* we keep up with new ARCH features which introduces a new SPSR bit.
*/
-static u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el)
+u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el)
{
u_register_t new_spsr = 0;
u_register_t sctlr;
diff --git a/include/bl31/sync_handle.h b/include/bl31/sync_handle.h
index ae61f31..394252b 100644
--- a/include/bl31/sync_handle.h
+++ b/include/bl31/sync_handle.h
@@ -58,6 +58,8 @@
/* Handler for injecting UNDEF exception to lower EL */
void inject_undef64(cpu_context_t *ctx);
+u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el);
+
/* Prototypes for system register emulation handlers provided by platforms. */
int plat_handle_impdef_trap(uint64_t esr_el3, cpu_context_t *ctx);
int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx);
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 72bc33f..c58adba 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -13,6 +13,7 @@
#include <arch_features.h>
#include <bl31/ehf.h>
#include <bl31/interrupt_mgmt.h>
+#include <bl31/sync_handle.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
@@ -237,9 +238,7 @@
/*
* Prepare for ERET:
* - Set the ELR to the registered handler address
- * - Set the SPSR register as described in the SDEI documentation and
- * the AArch64.TakeException() pseudocode function in
- * ARM DDI 0487F.c page J1-7635
+ * - Set the SPSR register by calling the common create_spsr() function
*/
static void sdei_set_elr_spsr(sdei_entry_t *se, sdei_dispatch_context_t *disp_ctx)
@@ -250,57 +249,7 @@
u_register_t interrupted_pstate = disp_ctx->spsr_el3;
- /* Check the SPAN bit in the client el SCTLR */
- u_register_t client_el_sctlr;
-
- if (client_el == MODE_EL2) {
- client_el_sctlr = read_sctlr_el2();
- } else {
- client_el_sctlr = read_sctlr_el1();
- }
-
- /*
- * Check whether to force the PAN bit or use the value in the
- * interrupted EL according to the check described in
- * TakeException. Since the client can only be Non-Secure
- * EL2 or El1 some of the conditions in ElIsInHost() we know
- * will always be True.
- * When the client_el is EL2 we know that there will be a SPAN
- * bit in SCTLR_EL2 as we have already checked for the condition
- * HCR_EL2.E2H = 1 and HCR_EL2.TGE = 1
- */
- u_register_t hcr_el2 = read_hcr();
- bool el_is_in_host = (read_feat_vhe_id_field() != 0U) &&
- (hcr_el2 & HCR_TGE_BIT) &&
- (hcr_el2 & HCR_E2H_BIT);
-
- if (is_feat_pan_supported() &&
- ((client_el == MODE_EL1) ||
- (client_el == MODE_EL2 && el_is_in_host)) &&
- ((client_el_sctlr & SCTLR_SPAN_BIT) == 0U)) {
- sdei_spsr |= SPSR_PAN_BIT;
- } else {
- sdei_spsr |= (interrupted_pstate & SPSR_PAN_BIT);
- }
-
- /* If SSBS is implemented, take the value from the client el SCTLR */
- u_register_t ssbs_enabled = (read_id_aa64pfr1_el1()
- >> ID_AA64PFR1_EL1_SSBS_SHIFT)
- & ID_AA64PFR1_EL1_SSBS_MASK;
- if (ssbs_enabled != SSBS_UNAVAILABLE) {
- u_register_t ssbs_bit = ((client_el_sctlr & SCTLR_DSSBS_BIT)
- >> SCTLR_DSSBS_SHIFT)
- << SPSR_SSBS_SHIFT_AARCH64;
- sdei_spsr |= ssbs_bit;
- }
-
- /* If MTE is implemented in the client el set the TCO bit */
- if (is_feat_mte_supported()) {
- sdei_spsr |= SPSR_TCO_BIT_AARCH64;
- }
-
- /* Take the DIT field from the pstate of the interrupted el */
- sdei_spsr |= (interrupted_pstate & SPSR_DIT_BIT);
+ sdei_spsr = create_spsr(interrupted_pstate, client_el);
cm_set_elr_spsr_el3(NON_SECURE, (uintptr_t) se->ep, sdei_spsr);
}