Merge "PSCI: fix limit of 256 CPUs caused by cast to unsigned char" into integration
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index e2dcfa8..72bd6bd 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -42,6 +42,11 @@
define_psci_cap(PSCI_SYSTEM_RESET2_AARCH64) | \
define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64))
+/* Internally PSCI uses a uint16_t for various cpu indexes so
+ * define a limit to number of CPUs that can be initialised.
+ */
+#define PSCI_MAX_CPUS_INDEX 0xFFFFU
+
/*
* Helper functions to get/set the fields of PSCI per-cpu data.
*/
@@ -134,7 +139,7 @@
unsigned char level;
/* For indexing the psci_lock array*/
- unsigned char lock_index;
+ uint16_t lock_index;
} non_cpu_pd_node_t;
typedef struct cpu_pwr_domain_node {
@@ -239,7 +244,7 @@
#endif /* HW_ASSISTED_COHERENCY */
static inline void psci_lock_init(non_cpu_pd_node_t *non_cpu_pd_node,
- unsigned char idx)
+ uint16_t idx)
{
non_cpu_pd_node[idx].lock_index = idx;
}
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index d1ec998..9c37d63 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -17,6 +17,12 @@
#include "psci_private.h"
+/*
+ * Check that PLATFORM_CORE_COUNT fits into the number of cores
+ * that can be represented by PSCI_MAX_CPUS_INDEX.
+ */
+CASSERT(PLATFORM_CORE_COUNT <= (PSCI_MAX_CPUS_INDEX + 1U), assert_psci_cores_overflow);
+
/*******************************************************************************
* Per cpu non-secure contexts used to program the architectural state prior
* return to the normal world.
@@ -34,11 +40,13 @@
* Function which initializes the 'psci_non_cpu_pd_nodes' or the
* 'psci_cpu_pd_nodes' corresponding to the power level.
******************************************************************************/
-static void __init psci_init_pwr_domain_node(unsigned char node_idx,
+static void __init psci_init_pwr_domain_node(uint16_t node_idx,
unsigned int parent_idx,
unsigned char level)
{
if (level > PSCI_CPU_PWR_LVL) {
+ assert(node_idx < PSCI_NUM_NON_CPU_PWR_DOMAINS);
+
psci_non_cpu_pd_nodes[node_idx].level = level;
psci_lock_init(psci_non_cpu_pd_nodes, node_idx);
psci_non_cpu_pd_nodes[node_idx].parent_node = parent_idx;
@@ -47,6 +55,8 @@
} else {
psci_cpu_data_t *svc_cpu_data;
+ assert(node_idx < PLATFORM_CORE_COUNT);
+
psci_cpu_pd_nodes[node_idx].parent_node = parent_idx;
/* Initialize with an invalid mpidr */
@@ -144,7 +154,7 @@
for (j = node_index;
j < (node_index + num_children); j++)
- psci_init_pwr_domain_node((unsigned char)j,
+ psci_init_pwr_domain_node((uint16_t)j,
parent_node_index - 1U,
(unsigned char)level);