"vscode:/vscode.git/clone" did not exist on "63b8d652f251f2b7e22ee80dbeaba8ecf6b9b535"
Commit 8991eed7 authored by Soby Mathew's avatar Soby Mathew Committed by Dan Handley
Browse files

Rework the PSCI migrate APIs

This patch reworks the PSCI MIGRATE, MIGRATE_INFO_TYPE and
MIGRATE_INFO_UP_CPU support for Trusted Firmware. The
implementation does the appropriate validation of parameters
and invokes the appropriate hook exported by the SPD.

The TSP is a MP Trusted OS. Hence the ability to actually
migrate a Trusted OS has not been implemented. The
corresponding function is not populated in the spd_pm_hooks
structure for the TSPD.

The `spd_pm_ops_t` has undergone changes with this patch.
SPD PORTS MAY NEED TO BE UPDATED.

Fixes ARM-software/tf-issues#249

Change-Id: Iabd87521bf7c530a5e4506b6d3bfd4f1bf87604f
parent 860331aa
...@@ -191,8 +191,8 @@ typedef struct spd_pm_ops { ...@@ -191,8 +191,8 @@ typedef struct spd_pm_ops {
void (*svc_suspend)(uint64_t __unused); void (*svc_suspend)(uint64_t __unused);
void (*svc_on_finish)(uint64_t __unused); void (*svc_on_finish)(uint64_t __unused);
void (*svc_suspend_finish)(uint64_t suspend_level); void (*svc_suspend_finish)(uint64_t suspend_level);
void (*svc_migrate)(uint64_t __unused1, uint64_t __unused2); int32_t (*svc_migrate)(uint64_t from_cpu, uint64_t to_cpu);
int32_t (*svc_migrate_info)(uint64_t *__unused); int32_t (*svc_migrate_info)(uint64_t *resident_cpu);
void (*svc_system_off)(void); void (*svc_system_off)(void);
void (*svc_system_reset)(void); void (*svc_system_reset)(void);
} spd_pm_ops_t; } spd_pm_ops_t;
...@@ -202,9 +202,9 @@ typedef struct spd_pm_ops { ...@@ -202,9 +202,9 @@ typedef struct spd_pm_ops {
******************************************************************************/ ******************************************************************************/
unsigned int psci_version(void); unsigned int psci_version(void);
int psci_affinity_info(unsigned long, unsigned int); int psci_affinity_info(unsigned long, unsigned int);
int psci_migrate(unsigned int); int psci_migrate(unsigned long);
unsigned int psci_migrate_info_type(void); int psci_migrate_info_type(void);
unsigned long psci_migrate_info_up_cpu(void); long psci_migrate_info_up_cpu(void);
int psci_cpu_on(unsigned long, int psci_cpu_on(unsigned long,
unsigned long, unsigned long,
unsigned long); unsigned long);
......
...@@ -561,6 +561,29 @@ void psci_register_spd_pm_hook(const spd_pm_ops_t *pm) ...@@ -561,6 +561,29 @@ void psci_register_spd_pm_hook(const spd_pm_ops_t *pm)
psci_spd_pm = pm; psci_spd_pm = pm;
} }
/*******************************************************************************
* This function invokes the migrate info hook in the spd_pm_ops. It performs
* the necessary return value validation. If the Secure Payload is UP and
* migrate capable, it returns the mpidr of the CPU on which the Secure payload
* is resident through the mpidr parameter. Else the value of the parameter on
* return is undefined.
******************************************************************************/
int psci_spd_migrate_info(uint64_t *mpidr)
{
int rc;
if (!psci_spd_pm || !psci_spd_pm->svc_migrate_info)
return PSCI_E_NOT_SUPPORTED;
rc = psci_spd_pm->svc_migrate_info(mpidr);
assert(rc == PSCI_TOS_UP_MIG_CAP || rc == PSCI_TOS_NOT_UP_MIG_CAP \
|| rc == PSCI_TOS_NOT_PRESENT_MP || rc == PSCI_E_NOT_SUPPORTED);
return rc;
}
/******************************************************************************* /*******************************************************************************
* This function prints the state of all affinity instances present in the * This function prints the state of all affinity instances present in the
* system * system
......
...@@ -219,25 +219,57 @@ int psci_affinity_info(unsigned long target_affinity, ...@@ -219,25 +219,57 @@ int psci_affinity_info(unsigned long target_affinity,
return rc; return rc;
} }
/* Unimplemented */ int psci_migrate(unsigned long target_cpu)
int psci_migrate(unsigned int target_cpu)
{ {
return PSCI_E_NOT_SUPPORTED; int rc;
unsigned long resident_cpu_mpidr;
rc = psci_spd_migrate_info(&resident_cpu_mpidr);
if (rc != PSCI_TOS_UP_MIG_CAP)
return (rc == PSCI_TOS_NOT_UP_MIG_CAP) ?
PSCI_E_DENIED : PSCI_E_NOT_SUPPORTED;
/*
* Migrate should only be invoked on the CPU where
* the Secure OS is resident.
*/
if (resident_cpu_mpidr != read_mpidr_el1())
return PSCI_E_NOT_PRESENT;
/* Check the validity of the specified target cpu */
rc = psci_validate_mpidr(target_cpu, MPIDR_AFFLVL0);
if (rc != PSCI_E_SUCCESS)
return PSCI_E_INVALID_PARAMS;
assert(psci_spd_pm && psci_spd_pm->svc_migrate);
rc = psci_spd_pm->svc_migrate(read_mpidr_el1(), target_cpu);
assert(rc == PSCI_E_SUCCESS || rc == PSCI_E_INTERN_FAIL);
return rc;
} }
/* Unimplemented */ int psci_migrate_info_type(void)
unsigned int psci_migrate_info_type(void)
{ {
return PSCI_TOS_NOT_PRESENT_MP; unsigned long resident_cpu_mpidr;
return psci_spd_migrate_info(&resident_cpu_mpidr);
} }
unsigned long psci_migrate_info_up_cpu(void) long psci_migrate_info_up_cpu(void)
{ {
unsigned long resident_cpu_mpidr;
int rc;
/* /*
* Return value of this currently unsupported call depends upon * Return value of this depends upon what
* what psci_migrate_info_type() returns. * psci_spd_migrate_info() returns.
*/ */
return PSCI_E_SUCCESS; rc = psci_spd_migrate_info(&resident_cpu_mpidr);
if (rc != PSCI_TOS_NOT_UP_MIG_CAP && rc != PSCI_TOS_UP_MIG_CAP)
return PSCI_E_INVALID_PARAMS;
return resident_cpu_mpidr;
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -120,6 +120,7 @@ void psci_set_max_phys_off_afflvl(uint32_t afflvl); ...@@ -120,6 +120,7 @@ void psci_set_max_phys_off_afflvl(uint32_t afflvl);
uint32_t psci_find_max_phys_off_afflvl(uint32_t start_afflvl, uint32_t psci_find_max_phys_off_afflvl(uint32_t start_afflvl,
uint32_t end_afflvl, uint32_t end_afflvl,
aff_map_node_t *mpidr_nodes[]); aff_map_node_t *mpidr_nodes[]);
int psci_spd_migrate_info(uint64_t *mpidr);
/* Private exported functions from psci_setup.c */ /* Private exported functions from psci_setup.c */
int psci_get_aff_map_nodes(unsigned long mpidr, int psci_get_aff_map_nodes(unsigned long mpidr,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment