aboutsummaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/std_svc/psci/psci_common.c30
-rw-r--r--services/std_svc/psci/psci_main.c49
-rw-r--r--services/std_svc/psci/psci_private.h2
3 files changed, 34 insertions, 47 deletions
diff --git a/services/std_svc/psci/psci_common.c b/services/std_svc/psci/psci_common.c
index 7f1a5fd0..f810ddfa 100644
--- a/services/std_svc/psci/psci_common.c
+++ b/services/std_svc/psci/psci_common.c
@@ -589,7 +589,7 @@ int psci_validate_mpidr(unsigned long mpidr)
* This function determines the full entrypoint information for the requested
* PSCI entrypoint on power on/resume and returns it.
******************************************************************************/
-int psci_get_ns_ep_info(entry_point_info_t *ep,
+static int psci_get_ns_ep_info(entry_point_info_t *ep,
uint64_t entrypoint, uint64_t context_id)
{
uint32_t ep_attr, mode, sctlr, daif, ee;
@@ -621,7 +621,7 @@ int psci_get_ns_ep_info(entry_point_info_t *ep,
* aarch64 EL
*/
if (entrypoint & 0x1)
- return PSCI_E_INVALID_PARAMS;
+ return PSCI_E_INVALID_ADDRESS;
mode = ns_scr_el3 & SCR_HCE_BIT ? MODE_EL2 : MODE_EL1;
@@ -643,6 +643,32 @@ int psci_get_ns_ep_info(entry_point_info_t *ep,
}
/*******************************************************************************
+ * This function validates the entrypoint with the platform layer if the
+ * appropriate pm_ops hook is exported by the platform and returns the
+ * 'entry_point_info'.
+ ******************************************************************************/
+int psci_validate_entry_point(entry_point_info_t *ep,
+ uint64_t entrypoint, uint64_t context_id)
+{
+ int rc;
+
+ /* Validate the entrypoint using platform psci_ops */
+ if (psci_plat_pm_ops->validate_ns_entrypoint) {
+ rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
+ if (rc != PSCI_E_SUCCESS)
+ return PSCI_E_INVALID_ADDRESS;
+ }
+
+ /*
+ * Verify and derive the re-entry information for
+ * the non-secure world from the non-secure state from
+ * where this call originated.
+ */
+ rc = psci_get_ns_ep_info(ep, entrypoint, context_id);
+ return rc;
+}
+
+/*******************************************************************************
* Generic handler which is called when a cpu is physically powered on. It
* traverses the node information and finds the highest power level powered
* off and performs generic, architectural, platform setup and state management
diff --git a/services/std_svc/psci/psci_main.c b/services/std_svc/psci/psci_main.c
index f0242910..6d3af204 100644
--- a/services/std_svc/psci/psci_main.c
+++ b/services/std_svc/psci/psci_main.c
@@ -55,21 +55,8 @@ int psci_cpu_on(unsigned long target_cpu,
if (rc != PSCI_E_SUCCESS)
return PSCI_E_INVALID_PARAMS;
- /* Validate the entrypoint using platform pm_ops */
- if (psci_plat_pm_ops->validate_ns_entrypoint) {
- rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
- if (rc != PSCI_E_SUCCESS) {
- assert(rc == PSCI_E_INVALID_PARAMS);
- return PSCI_E_INVALID_PARAMS;
- }
- }
-
- /*
- * Verify and derive the re-entry information for
- * the non-secure world from the non-secure state from
- * where this call originated.
- */
- rc = psci_get_ns_ep_info(&ep, entrypoint, context_id);
+ /* Validate the entry point and get the entry_point_info */
+ rc = psci_validate_entry_point(&ep, entrypoint, context_id);
if (rc != PSCI_E_SUCCESS)
return rc;
@@ -141,20 +128,7 @@ int psci_cpu_suspend(unsigned int power_state,
* point and program entry information.
*/
if (is_power_down_state) {
- if (psci_plat_pm_ops->validate_ns_entrypoint) {
- rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
- if (rc != PSCI_E_SUCCESS) {
- assert(rc == PSCI_E_INVALID_PARAMS);
- return rc;
- }
- }
-
- /*
- * Verify and derive the re-entry information for
- * the non-secure world from the non-secure state from
- * where this call originated.
- */
- rc = psci_get_ns_ep_info(&ep, entrypoint, context_id);
+ rc = psci_validate_entry_point(&ep, entrypoint, context_id);
if (rc != PSCI_E_SUCCESS)
return rc;
}
@@ -180,25 +154,12 @@ int psci_system_suspend(unsigned long entrypoint,
psci_power_state_t state_info;
entry_point_info_t ep;
- /* Validate the entrypoint using platform pm_ops */
- if (psci_plat_pm_ops->validate_ns_entrypoint) {
- rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
- if (rc != PSCI_E_SUCCESS) {
- assert(rc == PSCI_E_INVALID_PARAMS);
- return rc;
- }
- }
-
/* Check if the current CPU is the last ON CPU in the system */
if (!psci_is_last_on_cpu())
return PSCI_E_DENIED;
- /*
- * Verify and derive the re-entry information for
- * the non-secure world from the non-secure state from
- * where this call originated.
- */
- rc = psci_get_ns_ep_info(&ep, entrypoint, context_id);
+ /* Validate the entry point and get the entry_point_info */
+ rc = psci_validate_entry_point(&ep, entrypoint, context_id);
if (rc != PSCI_E_SUCCESS)
return rc;
diff --git a/services/std_svc/psci/psci_private.h b/services/std_svc/psci/psci_private.h
index e2e32c79..5345ee30 100644
--- a/services/std_svc/psci/psci_private.h
+++ b/services/std_svc/psci/psci_private.h
@@ -189,7 +189,7 @@ void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info);
int psci_validate_mpidr(unsigned long mpidr);
void psci_init_req_local_pwr_states(void);
void psci_power_up_finish(void);
-int psci_get_ns_ep_info(entry_point_info_t *ep,
+int psci_validate_entry_point(entry_point_info_t *ep,
uint64_t entrypoint, uint64_t context_id);
void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
int end_lvl,