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
This commit is contained in:
parent
860331aa15
commit
8991eed743
|
@ -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 {
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
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)
|
||||||
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,
|
||||||
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;
|
||||||
|
|
||||||
/* Unimplemented */
|
rc = psci_spd_migrate_info(&resident_cpu_mpidr);
|
||||||
unsigned int psci_migrate_info_type(void)
|
if (rc != PSCI_TOS_UP_MIG_CAP)
|
||||||
{
|
return (rc == PSCI_TOS_NOT_UP_MIG_CAP) ?
|
||||||
return PSCI_TOS_NOT_PRESENT_MP;
|
PSCI_E_DENIED : PSCI_E_NOT_SUPPORTED;
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long psci_migrate_info_up_cpu(void)
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Return value of this currently unsupported call depends upon
|
* Migrate should only be invoked on the CPU where
|
||||||
* what psci_migrate_info_type() returns.
|
* the Secure OS is resident.
|
||||||
*/
|
*/
|
||||||
return PSCI_E_SUCCESS;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int psci_migrate_info_type(void)
|
||||||
|
{
|
||||||
|
unsigned long resident_cpu_mpidr;
|
||||||
|
|
||||||
|
return psci_spd_migrate_info(&resident_cpu_mpidr);
|
||||||
|
}
|
||||||
|
|
||||||
|
long psci_migrate_info_up_cpu(void)
|
||||||
|
{
|
||||||
|
unsigned long resident_cpu_mpidr;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return value of this depends upon what
|
||||||
|
* psci_spd_migrate_info() returns.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
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,
|
||||||
|
|
Loading…
Reference in New Issue