diff options
Diffstat (limited to 'lib/psci/psci_setup.c')
-rw-r--r-- | lib/psci/psci_setup.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c index fac0edec..d35e0001 100644 --- a/lib/psci/psci_setup.c +++ b/lib/psci/psci_setup.c @@ -184,15 +184,17 @@ static void populate_power_domain_tree(const unsigned char *topology) } /******************************************************************************* - * This function initializes the power domain topology tree by querying the - * platform. The power domain nodes higher than the CPU are populated in the - * array psci_non_cpu_pd_nodes[] and the CPU power domains are populated in - * psci_cpu_pd_nodes[]. The platform exports its static topology map through the + * This function does the architectural setup and takes the warm boot + * entry-point `mailbox_ep` as an argument. The function also initializes the + * power domain topology tree by querying the platform. The power domain nodes + * higher than the CPU are populated in the array psci_non_cpu_pd_nodes[] and + * the CPU power domains are populated in psci_cpu_pd_nodes[]. The platform + * exports its static topology map through the * populate_power_domain_topology_tree() API. The algorithm populates the * psci_non_cpu_pd_nodes and psci_cpu_pd_nodes iteratively by using this - * topology map. On a platform that implements two clusters of 2 cpus each, and - * supporting 3 domain levels, the populated psci_non_cpu_pd_nodes would look - * like this: + * topology map. On a platform that implements two clusters of 2 cpus each, + * and supporting 3 domain levels, the populated psci_non_cpu_pd_nodes would + * look like this: * * --------------------------------------------------- * | system node | cluster 0 node | cluster 1 node | @@ -204,10 +206,13 @@ static void populate_power_domain_tree(const unsigned char *topology) * | CPU 0 | CPU 1 | CPU 2 | CPU 3 | * ------------------------------------------------ ******************************************************************************/ -int psci_setup(void) +int psci_setup(uintptr_t mailbox_ep) { const unsigned char *topology_tree; + /* Do the Architectural initialization */ + psci_arch_setup(); + /* Query the topology map from the platform */ topology_tree = plat_get_power_domain_tree_desc(); @@ -229,8 +234,8 @@ int psci_setup(void) */ psci_set_pwr_domains_to_run(PLAT_MAX_PWR_LVL); - plat_setup_psci_ops((uintptr_t)psci_entrypoint, - &psci_plat_pm_ops); + assert(mailbox_ep); + plat_setup_psci_ops(mailbox_ep, &psci_plat_pm_ops); assert(psci_plat_pm_ops); /* Initialize the psci capability */ @@ -259,3 +264,17 @@ int psci_setup(void) return 0; } + +/******************************************************************************* + * This duplicates what the primary cpu did after a cold boot in BL1. The same + * needs to be done when a cpu is hotplugged in. This function could also over- + * ride any EL3 setup done by BL1 as this code resides in rw memory. + ******************************************************************************/ +void psci_arch_setup(void) +{ + /* Program the counter frequency */ + write_cntfrq_el0(plat_get_syscnt_freq2()); + + /* Initialize the cpu_ops pointer. */ + init_cpu_ops(); +} |