diff options
Diffstat (limited to 'bl32/sp_min')
-rw-r--r-- | bl32/sp_min/aarch32/entrypoint.S | 70 | ||||
-rw-r--r-- | bl32/sp_min/sp_min_main.c | 13 |
2 files changed, 34 insertions, 49 deletions
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S index ebbee5ac..e145511d 100644 --- a/bl32/sp_min/aarch32/entrypoint.S +++ b/bl32/sp_min/aarch32/entrypoint.S @@ -115,21 +115,10 @@ func sp_min_entrypoint sub r1, r1, r0 bl clean_dcache_range - /* Program the registers in cpu_context and exit monitor mode */ - mov r0, #NON_SECURE - bl cm_get_context - - /* Restore the SCR */ - ldr r2, [r0, #CTX_REGS_OFFSET + CTX_SCR] - stcopr r2, SCR - isb - - /* Restore the SCTLR */ - ldr r2, [r0, #CTX_REGS_OFFSET + CTX_NS_SCTLR] - stcopr r2, SCTLR - bl smc_get_next_ctx - /* The other cpu_context registers have been copied to smc context */ + + /* r0 points to `smc_ctx_t` */ + /* The PSCI cpu_context registers have been copied to `smc_ctx_t` */ b sp_min_exit endfunc sp_min_entrypoint @@ -138,46 +127,44 @@ endfunc sp_min_entrypoint * SMC handling function for SP_MIN. */ func handle_smc - smcc_save_gp_mode_regs + /* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */ + str lr, [sp, #SMC_CTX_LR_MON] - /* r0 points to smc_context */ - mov r2, r0 /* handle */ - ldcopr r0, SCR + smcc_save_gp_mode_regs /* - * Save SCR in stack. r1 is pushed to meet the 8 byte - * stack alignment requirement. + * `sp` still points to `smc_ctx_t`. Save it to a register + * and restore the C runtime stack pointer to `sp`. */ - push {r0, r1} + mov r2, sp /* handle */ + ldr sp, [r2, #SMC_CTX_SP_MON] + + ldr r0, [r2, #SMC_CTX_SCR] and r3, r0, #SCR_NS_BIT /* flags */ /* Switch to Secure Mode*/ bic r0, #SCR_NS_BIT stcopr r0, SCR isb + ldr r0, [r2, #SMC_CTX_GPREG_R0] /* smc_fid */ /* Check whether an SMC64 is issued */ tst r0, #(FUNCID_CC_MASK << FUNCID_CC_SHIFT) - beq 1f /* SMC32 is detected */ + beq 1f + /* SMC32 is not detected. Return error back to caller */ mov r0, #SMC_UNK str r0, [r2, #SMC_CTX_GPREG_R0] mov r0, r2 - b 2f /* Skip handling the SMC */ + b sp_min_exit 1: + /* SMC32 is detected */ mov r1, #0 /* cookie */ bl handle_runtime_svc -2: - /* r0 points to smc context */ - - /* Restore SCR from stack */ - pop {r1, r2} - stcopr r1, SCR - isb + /* `r0` points to `smc_ctx_t` */ b sp_min_exit endfunc handle_smc - /* * The Warm boot entrypoint for SP_MIN. */ @@ -234,23 +221,9 @@ func sp_min_warm_entrypoint #endif bl sp_min_warm_boot - - /* Program the registers in cpu_context and exit monitor mode */ - mov r0, #NON_SECURE - bl cm_get_context - - /* Restore the SCR */ - ldr r2, [r0, #CTX_REGS_OFFSET + CTX_SCR] - stcopr r2, SCR - isb - - /* Restore the SCTLR */ - ldr r2, [r0, #CTX_REGS_OFFSET + CTX_NS_SCTLR] - stcopr r2, SCTLR - bl smc_get_next_ctx - - /* The other cpu_context registers have been copied to smc context */ + /* r0 points to `smc_ctx_t` */ + /* The PSCI cpu_context registers have been copied to `smc_ctx_t` */ b sp_min_exit endfunc sp_min_warm_entrypoint @@ -261,6 +234,5 @@ endfunc sp_min_warm_entrypoint * Arguments : r0 must point to the SMC context to restore from. */ func sp_min_exit - smcc_restore_gp_mode_regs - eret + monitor_exit endfunc sp_min_exit diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c index d47b82a0..45ad03f9 100644 --- a/bl32/sp_min/sp_min_main.c +++ b/bl32/sp_min/sp_min_main.c @@ -101,6 +101,7 @@ static void copy_cpu_ctx_to_smc_stx(const regs_t *cpu_reg_ctx, next_smc_ctx->r0 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R0); next_smc_ctx->lr_mon = read_ctx_reg(cpu_reg_ctx, CTX_LR); next_smc_ctx->spsr_mon = read_ctx_reg(cpu_reg_ctx, CTX_SPSR); + next_smc_ctx->scr = read_ctx_reg(cpu_reg_ctx, CTX_SCR); } /******************************************************************************* @@ -111,6 +112,8 @@ static void copy_cpu_ctx_to_smc_stx(const regs_t *cpu_reg_ctx, static void sp_min_prepare_next_image_entry(void) { entry_point_info_t *next_image_info; + cpu_context_t *ctx = cm_get_context(NON_SECURE); + u_register_t ns_sctlr; /* Program system registers to proceed to non-secure */ next_image_info = sp_min_plat_get_bl33_ep_info(); @@ -125,6 +128,16 @@ static void sp_min_prepare_next_image_entry(void) /* Copy r0, lr and spsr from cpu context to SMC context */ copy_cpu_ctx_to_smc_stx(get_regs_ctx(cm_get_context(NON_SECURE)), smc_get_next_ctx()); + + /* Temporarily set the NS bit to access NS SCTLR */ + write_scr(read_scr() | SCR_NS_BIT); + isb(); + ns_sctlr = read_ctx_reg(get_regs_ctx(ctx), CTX_NS_SCTLR); + write_sctlr(ns_sctlr); + isb(); + + write_scr(read_scr() & ~SCR_NS_BIT); + isb(); } /****************************************************************************** |