qemu/qemu_sbsa: topology is different from qemu so add handling

sbsa-ref in QEMU creates clusers of 8 cores, it may create up to 512
cores in upto 64 clusters. Implement a qemu_sbsa specific topology file
and increase the BL31_SIZE to accommodate the bigger table sizes. Change
platform_def.h for new topology. Correct PLATFORM_CPU_PER_CLUSTER_SHIFT so
plat_helpers.S calculates correct result.

Signed-off-by: Graeme Gregory <graeme@nuviainc.com>
Change-Id: Idc5d70394c0956b759ad2c86f9fda8f293f2cfa7
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index 8471024..94bf0d1 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -16,20 +16,17 @@
 
 #define PLATFORM_STACK_SIZE		0x1000
 
-#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(4)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(8)
 /*
  * Define the number of cores per cluster used in calculating core position.
  * The cluster number is shifted by this value and added to the core ID,
  * so its value represents log2(cores/cluster).
- * Default is 2**(2) = 4 cores per cluster.
+ * Default is 2**(3) = 8 cores per cluster.
  */
-#define PLATFORM_CPU_PER_CLUSTER_SHIFT	U(2)
-#define PLATFORM_CLUSTER_COUNT		U(2)
-#define PLATFORM_CLUSTER0_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
-#define PLATFORM_CLUSTER1_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
-#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER0_CORE_COUNT + \
-					 PLATFORM_CLUSTER1_CORE_COUNT)
-
+#define PLATFORM_CPU_PER_CLUSTER_SHIFT	U(3)
+#define PLATFORM_CLUSTER_COUNT		U(64)
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
+					PLATFORM_MAX_CPUS_PER_CLUSTER)
 #define QEMU_PRIMARY_CPU		U(0)
 
 #define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CLUSTER_COUNT + \
@@ -137,7 +134,7 @@
  * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
  * current BL3-1 debug size plus a little space for growth.
  */
-#define BL31_SIZE			0x50000
+#define BL31_SIZE			0x300000
 #define BL31_BASE			(BL31_LIMIT - BL31_SIZE)
 #define BL31_LIMIT			(BL1_RW_BASE)
 #define BL31_PROGBITS_LIMIT		BL1_RW_BASE
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 98d1347..ece700c 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -80,7 +80,7 @@
 				lib/semihosting/${ARCH}/semihosting_call.S	\
 				plat/common/plat_psci_common.c			\
 				${PLAT_QEMU_COMMON_PATH}/qemu_pm.c		\
-				${PLAT_QEMU_COMMON_PATH}/topology.c		\
+				${PLAT_QEMU_PATH}/sbsa_topology.c		\
 				${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S	\
 				${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c	\
 				common/fdt_fixup.c				\
diff --git a/plat/qemu/qemu_sbsa/sbsa_private.h b/plat/qemu/qemu_sbsa/sbsa_private.h
new file mode 100644
index 0000000..29ee1d0
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_private.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2020, Nuvia Inc
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SBSA_PRIVATE_H
+#define SBSA_PRIVATE_H
+
+#include <stdint.h>
+
+unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);
+
+#endif /* SBSA_PRIVATE_H */
diff --git a/plat/qemu/qemu_sbsa/sbsa_topology.c b/plat/qemu/qemu_sbsa/sbsa_topology.c
new file mode 100644
index 0000000..bd8d16b
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_topology.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2020, Nuvia Inc
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <common/debug.h>
+
+#include <platform_def.h>
+#include "sbsa_private.h"
+
+/* The power domain tree descriptor */
+static unsigned char power_domain_tree_desc[PLATFORM_CLUSTER_COUNT + 1];
+
+/*******************************************************************************
+ * This function returns the sbsa-ref default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	unsigned int i;
+
+	power_domain_tree_desc[0] = PLATFORM_CLUSTER_COUNT;
+
+	for (i = 0U; i < PLATFORM_CLUSTER_COUNT; i++) {
+		power_domain_tree_desc[i + 1] = PLATFORM_MAX_CPUS_PER_CLUSTER;
+	}
+
+	return power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+	if ((mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) {
+		ERROR("Invalid MPIDR\n");
+		return -1;
+	}
+
+	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		ERROR("cluster_id >= PLATFORM_CLUSTER_COUNT define\n");
+		return -1;
+	}
+
+	if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
+		ERROR("cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER define\n");
+		return -1;
+	}
+
+	return plat_qemu_calc_core_pos(mpidr);
+}