summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm64/armv8/secmon/psci.c25
-rw-r--r--src/arch/arm64/armv8/secmon/secmon_init.c2
-rw-r--r--src/arch/arm64/include/arch/psci.h5
3 files changed, 19 insertions, 13 deletions
diff --git a/src/arch/arm64/armv8/secmon/psci.c b/src/arch/arm64/armv8/secmon/psci.c
index 0051031e22..f87419dda8 100644
--- a/src/arch/arm64/armv8/secmon/psci.c
+++ b/src/arch/arm64/armv8/secmon/psci.c
@@ -170,17 +170,16 @@ static void psci_cpu_on_callback(void *arg)
memset(&state, 0, sizeof(state));
state.elx.spsr = get_eret_el(target_el, SPSR_USE_H);
- transition_with_entry(e->cpu_state.entry, e->cpu_state.arg, &state);
+ transition_with_entry(e->cpu_state.startup.run,
+ e->cpu_state.startup.arg, &state);
}
-static void psci_cpu_on_prepare(struct psci_node *e,
- void *entry, void *arg)
+static void psci_cpu_on_prepare(struct psci_node *e, const struct cpu_action *a)
{
struct psci_node *ancestor;
int state = PSCI_STATE_ON_PENDING;
- e->cpu_state.entry = entry;
- e->cpu_state.arg = arg;
+ e->cpu_state.startup = *a;
ancestor = psci_find_ancestor(e, PSCI_AFFINITY_LEVEL_HIGHEST, state);
e->cpu_state.ancestor = ancestor;
psci_set_hierarchy_state(e, ancestor, state);
@@ -188,18 +187,23 @@ static void psci_cpu_on_prepare(struct psci_node *e,
static int psci_schedule_cpu_on(struct psci_node *e)
{
+ struct cpu_info *ci;
struct cpu_action action = {
.run = &psci_cpu_on_callback,
.arg = e,
};
- if (arch_run_on_cpu_async(e->cpu_state.ci->id, &action))
+ ci = e->cpu_state.ci;
+ if (ci == NULL || arch_run_on_cpu_async(ci->id, &action)) {
+ psci_set_hierarchy_state(e, e->cpu_state.ancestor,
+ PSCI_STATE_OFF);
return PSCI_RET_INTERNAL_FAILURE;
+ }
return PSCI_RET_SUCCESS;
}
-void psci_turn_on_self(void *entry, void *arg)
+void psci_turn_on_self(const struct cpu_action *action)
{
struct psci_node *e = node_self();
@@ -210,7 +214,7 @@ void psci_turn_on_self(void *entry, void *arg)
}
psci_lock();
- psci_cpu_on_prepare(e, entry, arg);
+ psci_cpu_on_prepare(e, action);
psci_unlock();
psci_schedule_cpu_on(e);
@@ -223,6 +227,7 @@ static void psci_cpu_on(struct psci_func *pf)
uint64_t context_id;
int cpu_state;
struct psci_node *e;
+ struct cpu_action action;
target_mpidr = psci64_arg(pf, PSCI_PARAM_0);
entry = psci64_arg(pf, PSCI_PARAM_1);
@@ -248,7 +253,9 @@ static void psci_cpu_on(struct psci_func *pf)
return;
}
- psci_cpu_on_prepare(e, (void *)entry, (void *)context_id);
+ action.run = (void *)entry;
+ action.arg = (void *)context_id;
+ psci_cpu_on_prepare(e, &action);
psci_unlock();
psci32_return(pf, psci_schedule_cpu_on(e));
diff --git a/src/arch/arm64/armv8/secmon/secmon_init.c b/src/arch/arm64/armv8/secmon/secmon_init.c
index 8fd39176f8..9e104c759b 100644
--- a/src/arch/arm64/armv8/secmon/secmon_init.c
+++ b/src/arch/arm64/armv8/secmon/secmon_init.c
@@ -44,7 +44,7 @@ static void start_up_cpu(void *arg)
if (action->run == NULL)
psci_turn_off_self();
- psci_turn_on_self(action->run, action->arg);
+ psci_turn_on_self(action);
}
static void cpu_init(int bsp)
diff --git a/src/arch/arm64/include/arch/psci.h b/src/arch/arm64/include/arch/psci.h
index afa4c4209c..32a32b1345 100644
--- a/src/arch/arm64/include/arch/psci.h
+++ b/src/arch/arm64/include/arch/psci.h
@@ -63,8 +63,7 @@ struct psci_node;
struct psci_cpu_state {
struct cpu_info *ci;
- void *entry;
- void *arg;
+ struct cpu_action startup;
/* Ancestor of target to update state in CPU_ON case. */
struct psci_node *ancestor;
};
@@ -191,7 +190,7 @@ static inline void psci64_return(struct psci_func *pf, int64_t val)
void psci_init(void);
/* Turn on the current CPU within the PSCI subsystem. */
-void psci_turn_on_self(void *entry, void *arg);
+void psci_turn_on_self(const struct cpu_action *action);
int psci_turn_off_self(void);
#endif /* __ARCH_PSCI_H__ */