Merge pull request #131 from athoelke/at/cm_get_context

Provide cm_get/set_context() for current CPU
This commit is contained in:
danh-arm 2014-06-16 12:41:58 +01:00
commit 30e3b312f2
9 changed files with 68 additions and 48 deletions

View File

@ -71,9 +71,6 @@ void bl31_lib_init()
******************************************************************************/ ******************************************************************************/
void bl31_main(void) void bl31_main(void)
{ {
#if DEBUG
unsigned long mpidr = read_mpidr();
#endif
/* Perform remaining generic architectural setup from EL3 */ /* Perform remaining generic architectural setup from EL3 */
bl31_arch_setup(); bl31_arch_setup();
@ -98,7 +95,7 @@ void bl31_main(void)
* structure which has an exception stack allocated. The PSCI * structure which has an exception stack allocated. The PSCI
* service should have set the context. * service should have set the context.
*/ */
assert(cm_get_context(mpidr, NON_SECURE)); assert(cm_get_context(NON_SECURE));
cm_set_next_eret_context(NON_SECURE); cm_set_next_eret_context(NON_SECURE);
cm_init_pcpu_ptr_cache(); cm_init_pcpu_ptr_cache();
write_vbar_el3((uint64_t) runtime_exceptions); write_vbar_el3((uint64_t) runtime_exceptions);
@ -195,7 +192,7 @@ void bl31_prepare_next_image_entry()
* Save the args generated in BL2 for the image in the right context * Save the args generated in BL2 for the image in the right context
* used on its entry * used on its entry
*/ */
ctx = cm_get_context(read_mpidr(), image_type); ctx = cm_get_context(image_type);
gp_regs = get_gpregs_ctx(ctx); gp_regs = get_gpregs_ctx(ctx);
memcpy(gp_regs, (void *)&next_image_info->args, sizeof(aapcs64_params_t)); memcpy(gp_regs, (void *)&next_image_info->args, sizeof(aapcs64_params_t));

View File

@ -77,10 +77,10 @@ void cm_init()
/******************************************************************************* /*******************************************************************************
* This function returns a pointer to the most recent 'cpu_context' structure * This function returns a pointer to the most recent 'cpu_context' structure
* that was set as the context for the specified security state. NULL is * for the CPU identified by MPIDR that was set as the context for the specified
* returned if no such structure has been specified. * security state. NULL is returned if no such structure has been specified.
******************************************************************************/ ******************************************************************************/
void *cm_get_context(uint64_t mpidr, uint32_t security_state) void *cm_get_context_by_mpidr(uint64_t mpidr, uint32_t security_state)
{ {
uint32_t linear_id = platform_get_core_pos(mpidr); uint32_t linear_id = platform_get_core_pos(mpidr);
@ -90,10 +90,24 @@ void *cm_get_context(uint64_t mpidr, uint32_t security_state)
} }
/******************************************************************************* /*******************************************************************************
* This function sets the pointer to the current 'cpu_context' structure for the * This function returns a pointer to the most recent 'cpu_context' structure
* specified security state. * for the calling CPU that was set as the context for the specified security
* state. NULL is returned if no such structure has been specified.
******************************************************************************/ ******************************************************************************/
void cm_set_context(uint64_t mpidr, void *context, uint32_t security_state) void *cm_get_context(uint32_t security_state)
{
uint32_t linear_id = platform_get_core_pos(read_mpidr());
assert(security_state <= NON_SECURE);
return cm_context_info[linear_id].ptr[security_state];
}
/*******************************************************************************
* This function sets the pointer to the current 'cpu_context' structure for the
* specified security state for the CPU identified by MPIDR
******************************************************************************/
void cm_set_context_by_mpidr(uint64_t mpidr, void *context, uint32_t security_state)
{ {
uint32_t linear_id = platform_get_core_pos(mpidr); uint32_t linear_id = platform_get_core_pos(mpidr);
@ -102,6 +116,15 @@ void cm_set_context(uint64_t mpidr, void *context, uint32_t security_state)
cm_context_info[linear_id].ptr[security_state] = context; cm_context_info[linear_id].ptr[security_state] = context;
} }
/*******************************************************************************
* This function sets the pointer to the current 'cpu_context' structure for the
* specified security state for the calling CPU
******************************************************************************/
void cm_set_context(void *context, uint32_t security_state)
{
cm_set_context_by_mpidr(read_mpidr(), context, security_state);
}
/******************************************************************************* /*******************************************************************************
* The next four functions are used by runtime services to save and restore EL3 * The next four functions are used by runtime services to save and restore EL3
* and EL1 contexts on the 'cpu_context' structure for the specified security * and EL1 contexts on the 'cpu_context' structure for the specified security
@ -111,7 +134,7 @@ void cm_el3_sysregs_context_save(uint32_t security_state)
{ {
cpu_context_t *ctx; cpu_context_t *ctx;
ctx = cm_get_context(read_mpidr(), security_state); ctx = cm_get_context(security_state);
assert(ctx); assert(ctx);
el3_sysregs_context_save(get_el3state_ctx(ctx)); el3_sysregs_context_save(get_el3state_ctx(ctx));
@ -121,7 +144,7 @@ void cm_el3_sysregs_context_restore(uint32_t security_state)
{ {
cpu_context_t *ctx; cpu_context_t *ctx;
ctx = cm_get_context(read_mpidr(), security_state); ctx = cm_get_context(security_state);
assert(ctx); assert(ctx);
el3_sysregs_context_restore(get_el3state_ctx(ctx)); el3_sysregs_context_restore(get_el3state_ctx(ctx));
@ -131,7 +154,7 @@ void cm_el1_sysregs_context_save(uint32_t security_state)
{ {
cpu_context_t *ctx; cpu_context_t *ctx;
ctx = cm_get_context(read_mpidr(), security_state); ctx = cm_get_context(security_state);
assert(ctx); assert(ctx);
el1_sysregs_context_save(get_sysregs_ctx(ctx)); el1_sysregs_context_save(get_sysregs_ctx(ctx));
@ -141,7 +164,7 @@ void cm_el1_sysregs_context_restore(uint32_t security_state)
{ {
cpu_context_t *ctx; cpu_context_t *ctx;
ctx = cm_get_context(read_mpidr(), security_state); ctx = cm_get_context(security_state);
assert(ctx); assert(ctx);
el1_sysregs_context_restore(get_sysregs_ctx(ctx)); el1_sysregs_context_restore(get_sysregs_ctx(ctx));
@ -159,7 +182,7 @@ void cm_set_el3_eret_context(uint32_t security_state, uint64_t entrypoint,
cpu_context_t *ctx; cpu_context_t *ctx;
el3_state_t *state; el3_state_t *state;
ctx = cm_get_context(read_mpidr(), security_state); ctx = cm_get_context(security_state);
assert(ctx); assert(ctx);
/* Program the interrupt routing model for this security state */ /* Program the interrupt routing model for this security state */
@ -183,7 +206,7 @@ void cm_set_elr_el3(uint32_t security_state, uint64_t entrypoint)
cpu_context_t *ctx; cpu_context_t *ctx;
el3_state_t *state; el3_state_t *state;
ctx = cm_get_context(read_mpidr(), security_state); ctx = cm_get_context(security_state);
assert(ctx); assert(ctx);
/* Populate EL3 state so that ERET jumps to the correct entry */ /* Populate EL3 state so that ERET jumps to the correct entry */
@ -204,7 +227,7 @@ void cm_write_scr_el3_bit(uint32_t security_state,
el3_state_t *state; el3_state_t *state;
uint32_t scr_el3; uint32_t scr_el3;
ctx = cm_get_context(read_mpidr(), security_state); ctx = cm_get_context(security_state);
assert(ctx); assert(ctx);
/* Ensure that the bit position is a valid one */ /* Ensure that the bit position is a valid one */
@ -233,7 +256,7 @@ uint32_t cm_get_scr_el3(uint32_t security_state)
cpu_context_t *ctx; cpu_context_t *ctx;
el3_state_t *state; el3_state_t *state;
ctx = cm_get_context(read_mpidr(), security_state); ctx = cm_get_context(security_state);
assert(ctx); assert(ctx);
/* Populate EL3 state so that ERET jumps to the correct entry */ /* Populate EL3 state so that ERET jumps to the correct entry */
@ -253,7 +276,7 @@ void cm_set_next_eret_context(uint32_t security_state)
uint64_t sp_mode; uint64_t sp_mode;
#endif #endif
ctx = cm_get_context(read_mpidr(), security_state); ctx = cm_get_context(security_state);
assert(ctx); assert(ctx);
#if DEBUG #if DEBUG

View File

@ -37,10 +37,12 @@
* Function & variable prototypes * Function & variable prototypes
******************************************************************************/ ******************************************************************************/
void cm_init(void); void cm_init(void);
void *cm_get_context(uint64_t mpidr, uint32_t security_state); void *cm_get_context_by_mpidr(uint64_t mpidr, uint32_t security_state);
void cm_set_context(uint64_t mpidr, void *cm_get_context(uint32_t security_state);
void *context, void cm_set_context_by_mpidr(uint64_t mpidr,
uint32_t security_state); void *context,
uint32_t security_state);
void cm_set_context(void *context, uint32_t security_state);
void cm_el3_sysregs_context_save(uint32_t security_state); void cm_el3_sysregs_context_save(uint32_t security_state);
void cm_el3_sysregs_context_restore(uint32_t security_state); void cm_el3_sysregs_context_restore(uint32_t security_state);
void cm_el1_sysregs_context_save(uint32_t security_state); void cm_el1_sysregs_context_save(uint32_t security_state);

View File

@ -100,7 +100,7 @@ int32_t tspd_init_secure_context(uint64_t entrypoint,
/* Associate this context with the cpu specified */ /* Associate this context with the cpu specified */
tsp_ctx->mpidr = mpidr; tsp_ctx->mpidr = mpidr;
cm_set_context(mpidr, &tsp_ctx->cpu_ctx, SECURE); cm_set_context(&tsp_ctx->cpu_ctx, SECURE);
spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
cm_set_el3_eret_context(SECURE, entrypoint, spsr, scr); cm_set_el3_eret_context(SECURE, entrypoint, spsr, scr);
@ -122,7 +122,7 @@ uint64_t tspd_synchronous_sp_entry(tsp_context_t *tsp_ctx)
assert(tsp_ctx->c_rt_ctx == 0); assert(tsp_ctx->c_rt_ctx == 0);
/* Apply the Secure EL1 system register context and switch to it */ /* Apply the Secure EL1 system register context and switch to it */
assert(cm_get_context(read_mpidr(), SECURE) == &tsp_ctx->cpu_ctx); assert(cm_get_context(SECURE) == &tsp_ctx->cpu_ctx);
cm_el1_sysregs_context_restore(SECURE); cm_el1_sysregs_context_restore(SECURE);
cm_set_next_eret_context(SECURE); cm_set_next_eret_context(SECURE);
@ -146,7 +146,7 @@ uint64_t tspd_synchronous_sp_entry(tsp_context_t *tsp_ctx)
void tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret) void tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret)
{ {
/* Save the Secure EL1 system register context */ /* Save the Secure EL1 system register context */
assert(cm_get_context(read_mpidr(), SECURE) == &tsp_ctx->cpu_ctx); assert(cm_get_context(SECURE) == &tsp_ctx->cpu_ctx);
cm_el1_sysregs_context_save(SECURE); cm_el1_sysregs_context_save(SECURE);
assert(tsp_ctx->c_rt_ctx != 0); assert(tsp_ctx->c_rt_ctx != 0);

View File

@ -95,7 +95,7 @@ static uint64_t tspd_sel1_interrupt_handler(uint32_t id,
/* Sanity check the pointer to this cpu's context */ /* Sanity check the pointer to this cpu's context */
mpidr = read_mpidr(); mpidr = read_mpidr();
assert(handle == cm_get_context(mpidr, NON_SECURE)); assert(handle == cm_get_context(NON_SECURE));
/* Save the non-secure context before entering the TSP */ /* Save the non-secure context before entering the TSP */
cm_el1_sysregs_context_save(NON_SECURE); cm_el1_sysregs_context_save(NON_SECURE);
@ -103,7 +103,7 @@ static uint64_t tspd_sel1_interrupt_handler(uint32_t id,
/* Get a reference to this cpu's TSP context */ /* Get a reference to this cpu's TSP context */
linear_id = platform_get_core_pos(mpidr); linear_id = platform_get_core_pos(mpidr);
tsp_ctx = &tspd_sp_context[linear_id]; tsp_ctx = &tspd_sp_context[linear_id];
assert(&tsp_ctx->cpu_ctx == cm_get_context(mpidr, SECURE)); assert(&tsp_ctx->cpu_ctx == cm_get_context(SECURE));
/* /*
* Determine if the TSP was previously preempted. Its last known * Determine if the TSP was previously preempted. Its last known
@ -275,10 +275,10 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
if (ns) if (ns)
SMC_RET1(handle, SMC_UNK); SMC_RET1(handle, SMC_UNK);
assert(handle == cm_get_context(mpidr, SECURE)); assert(handle == cm_get_context(SECURE));
cm_el1_sysregs_context_save(SECURE); cm_el1_sysregs_context_save(SECURE);
/* Get a reference to the non-secure context */ /* Get a reference to the non-secure context */
ns_cpu_context = cm_get_context(mpidr, NON_SECURE); ns_cpu_context = cm_get_context(NON_SECURE);
assert(ns_cpu_context); assert(ns_cpu_context);
/* /*
@ -300,7 +300,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
if (ns) if (ns)
SMC_RET1(handle, SMC_UNK); SMC_RET1(handle, SMC_UNK);
assert(handle == cm_get_context(mpidr, SECURE)); assert(handle == cm_get_context(SECURE));
/* /*
* Restore the relevant EL3 state which saved to service * Restore the relevant EL3 state which saved to service
@ -316,7 +316,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
} }
/* Get a reference to the non-secure context */ /* Get a reference to the non-secure context */
ns_cpu_context = cm_get_context(mpidr, NON_SECURE); ns_cpu_context = cm_get_context(NON_SECURE);
assert(ns_cpu_context); assert(ns_cpu_context);
/* /*
@ -339,7 +339,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
if (ns) if (ns)
SMC_RET1(handle, SMC_UNK); SMC_RET1(handle, SMC_UNK);
assert(handle == cm_get_context(mpidr, SECURE)); assert(handle == cm_get_context(SECURE));
/* Assert that standard SMC execution has been preempted */ /* Assert that standard SMC execution has been preempted */
assert(get_std_smc_active_flag(tsp_ctx->state)); assert(get_std_smc_active_flag(tsp_ctx->state));
@ -348,7 +348,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
cm_el1_sysregs_context_save(SECURE); cm_el1_sysregs_context_save(SECURE);
/* Get a reference to the non-secure context */ /* Get a reference to the non-secure context */
ns_cpu_context = cm_get_context(mpidr, NON_SECURE); ns_cpu_context = cm_get_context(NON_SECURE);
assert(ns_cpu_context); assert(ns_cpu_context);
/* Restore non-secure state */ /* Restore non-secure state */
@ -434,7 +434,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
* registers need to be preserved, save the non-secure * registers need to be preserved, save the non-secure
* state and send the request to the secure payload. * state and send the request to the secure payload.
*/ */
assert(handle == cm_get_context(mpidr, NON_SECURE)); assert(handle == cm_get_context(NON_SECURE));
/* Check if we are already preempted */ /* Check if we are already preempted */
if (get_std_smc_active_flag(tsp_ctx->state)) if (get_std_smc_active_flag(tsp_ctx->state))
@ -457,7 +457,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
* payload. Entry into S-EL1 will take place upon exit * payload. Entry into S-EL1 will take place upon exit
* from this function. * from this function.
*/ */
assert(&tsp_ctx->cpu_ctx == cm_get_context(mpidr, SECURE)); assert(&tsp_ctx->cpu_ctx == cm_get_context(SECURE));
/* Set appropriate entry for SMC. /* Set appropriate entry for SMC.
* We expect the TSP to manage the PSTATE.I and PSTATE.F * We expect the TSP to manage the PSTATE.I and PSTATE.F
@ -482,11 +482,11 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
* into the non-secure context, save the secure state * into the non-secure context, save the secure state
* and return to the non-secure state. * and return to the non-secure state.
*/ */
assert(handle == cm_get_context(mpidr, SECURE)); assert(handle == cm_get_context(SECURE));
cm_el1_sysregs_context_save(SECURE); cm_el1_sysregs_context_save(SECURE);
/* Get a reference to the non-secure context */ /* Get a reference to the non-secure context */
ns_cpu_context = cm_get_context(mpidr, NON_SECURE); ns_cpu_context = cm_get_context(NON_SECURE);
assert(ns_cpu_context); assert(ns_cpu_context);
/* Restore non-secure state */ /* Restore non-secure state */
@ -515,7 +515,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
* save the non-secure state and send the request to * save the non-secure state and send the request to
* the secure payload. * the secure payload.
*/ */
assert(handle == cm_get_context(mpidr, NON_SECURE)); assert(handle == cm_get_context(NON_SECURE));
/* Check if we are already preempted before resume */ /* Check if we are already preempted before resume */
if (!get_std_smc_active_flag(tsp_ctx->state)) if (!get_std_smc_active_flag(tsp_ctx->state))

View File

@ -378,7 +378,7 @@ static unsigned int psci_afflvl0_on_finish(unsigned long mpidr,
* structure. The calling cpu should have set the * structure. The calling cpu should have set the
* context already * context already
*/ */
assert(cm_get_context(mpidr, NON_SECURE)); assert(cm_get_context(NON_SECURE));
cm_set_next_eret_context(NON_SECURE); cm_set_next_eret_context(NON_SECURE);
cm_init_pcpu_ptr_cache(); cm_init_pcpu_ptr_cache();
write_vbar_el3((uint64_t) runtime_exceptions); write_vbar_el3((uint64_t) runtime_exceptions);

View File

@ -180,7 +180,7 @@ static int psci_afflvl0_suspend(unsigned long mpidr,
* The EL3 state to PoC since it will be accessed after a * The EL3 state to PoC since it will be accessed after a
* reset with the caches turned off * reset with the caches turned off
*/ */
saved_el3_state = get_el3state_ctx(cm_get_context(mpidr, NON_SECURE)); saved_el3_state = get_el3state_ctx(cm_get_context(NON_SECURE));
flush_dcache_range((uint64_t) saved_el3_state, sizeof(*saved_el3_state)); flush_dcache_range((uint64_t) saved_el3_state, sizeof(*saved_el3_state));
/* Set the secure world (EL3) re-entry point after BL1 */ /* Set the secure world (EL3) re-entry point after BL1 */
@ -496,7 +496,6 @@ static unsigned int psci_afflvl0_suspend_finish(unsigned long mpidr,
* structure. The non-secure context should have been * structure. The non-secure context should have been
* set on this cpu prior to suspension. * set on this cpu prior to suspension.
*/ */
assert(cm_get_context(mpidr, NON_SECURE));
cm_set_next_eret_context(NON_SECURE); cm_set_next_eret_context(NON_SECURE);
cm_init_pcpu_ptr_cache(); cm_init_pcpu_ptr_cache();
write_vbar_el3((uint64_t) runtime_exceptions); write_vbar_el3((uint64_t) runtime_exceptions);

View File

@ -219,7 +219,6 @@ int psci_validate_mpidr(unsigned long mpidr, int level)
void psci_get_ns_entry_info(unsigned int index) void psci_get_ns_entry_info(unsigned int index)
{ {
unsigned long sctlr = 0, scr, el_status, id_aa64pfr0; unsigned long sctlr = 0, scr, el_status, id_aa64pfr0;
uint64_t mpidr = read_mpidr();
cpu_context_t *ns_entry_context; cpu_context_t *ns_entry_context;
gp_regs_t *ns_entry_gpregs; gp_regs_t *ns_entry_gpregs;
@ -253,7 +252,7 @@ void psci_get_ns_entry_info(unsigned int index)
write_sctlr_el1(sctlr); write_sctlr_el1(sctlr);
/* Fulfill the cpu_on entry reqs. as per the psci spec */ /* Fulfill the cpu_on entry reqs. as per the psci spec */
ns_entry_context = (cpu_context_t *) cm_get_context(mpidr, NON_SECURE); ns_entry_context = (cpu_context_t *) cm_get_context(NON_SECURE);
assert(ns_entry_context); assert(ns_entry_context);
/* /*

View File

@ -210,9 +210,9 @@ static void psci_init_aff_map_node(unsigned long mpidr,
linear_id = platform_get_core_pos(mpidr); linear_id = platform_get_core_pos(mpidr);
assert(linear_id < PLATFORM_CORE_COUNT); assert(linear_id < PLATFORM_CORE_COUNT);
cm_set_context(mpidr, cm_set_context_by_mpidr(mpidr,
(void *) &psci_ns_context[linear_id], (void *) &psci_ns_context[linear_id],
NON_SECURE); NON_SECURE);
} }