DeviceTree created by QEMU contain the information of memory, We can parsed this information and pass them to EDK2 via SMC call.
Signed-off-by: Xiong Yining xiongyining1480@phytium.com.cn Signed-off-by: Chen Baozi chenbaozi@phytium.com.cn Change-Id: I054b6a26fd38ace9898d221eabc70fea09e45f25 --- plat/qemu/qemu_sbsa/sbsa_sip_svc.c | 84 +++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c index 05ebec472..9657599ae 100644 --- a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c +++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c @@ -10,6 +10,7 @@ #include <common/runtime_svc.h> #include <libfdt.h> #include <smccc_helpers.h> +#include <lib/xlat_tables/xlat_tables_v2.h>
/* default platform version is 0.0 */ static int platform_version_major; @@ -19,6 +20,7 @@ static int platform_version_minor; #define SMC64_FUNCTION (SMC_FASTCALL | 0x40000000) #define SIP_FUNCTION (SMC64_FUNCTION | 0x02000000) #define SIP_FUNCTION_ID(n) (SIP_FUNCTION | (n)) +#define MAXNODE 128
/* * We do not use SMCCC_ARCH_SOC_ID here because qemu_sbsa is virtual platform @@ -28,13 +30,81 @@ static int platform_version_minor; #define SIP_SVC_VERSION SIP_FUNCTION_ID(1) #define SIP_SVC_GET_GIC SIP_FUNCTION_ID(100) #define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101) +#define SIP_SVC_GET_MEMORY SIP_FUNCTION_ID(300) +#define SIP_SVC_GET_MEMORYNODE_COUNT SIP_FUNCTION_ID(301)
static uint64_t gic_its_addr;
+typedef struct{ + uint32_t nodeid; + uint64_t addr_base; + uint64_t addr_size; +} memory_node; + +typedef struct{ + uint32_t num_memnode; + memory_node memnode[MAXNODE]; +} memory_info; + +static memory_info sbsa_mem_info; + void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base); uintptr_t sbsa_get_gicd(void); uintptr_t sbsa_get_gicr(void);
+void read_memoryinfo_from_dt(void *dtb) +{ + const fdt32_t *prop; + int32_t prev, node; + const char *type; + int len; + uint32_t i; + uint32_t higher_value, lower_value; + uint64_t cur_base, cur_size; + + i = 0; + for (prev = 0;; prev = node) { + node = fdt_next_node(dtb, prev, NULL); + if (node < 0) { + break; + } + + type = fdt_getprop(dtb, node, "device_type", &len); + if (type && strncmp(type, "memory", len) == 0) { + prop = fdt_getprop(dtb, node, "numa-node-id", NULL); + if (prop) { + sbsa_mem_info.memnode[i].nodeid = fdt32_to_cpu(*prop); + } + + /* + * Get the 'reg' property of this node and + * assume two 8 bytes for base and size. + */ + prop = fdt_getprop(dtb, node, "reg", &len); + if (prop != 0 && len == (2 * sizeof(int64_t))) { + higher_value = fdt32_to_cpu(*prop); + lower_value = fdt32_to_cpu(*(prop + 1)); + cur_base = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32); + sbsa_mem_info.memnode[i].addr_base = cur_base; + + higher_value = fdt32_to_cpu(*(prop + 2)); + lower_value = fdt32_to_cpu(*(prop + 3)); + cur_size = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32); + sbsa_mem_info.memnode[i].addr_size = cur_size; + + INFO("System RAM@%d: 0x%lx - 0x%lx\n", + sbsa_mem_info.memnode[i].nodeid, + sbsa_mem_info.memnode[i].addr_base, + sbsa_mem_info.memnode[i].addr_base + + sbsa_mem_info.memnode[i].addr_size); + } + i++; + } + } + + sbsa_mem_info.num_memnode = i; +} + void read_platform_config_from_dt(void *dtb) { int node; @@ -91,6 +161,8 @@ void read_platform_config_from_dt(void *dtb) return; } INFO("GICI base = 0x%lx\n", gic_its_addr); + + read_memoryinfo_from_dt(dtb); }
void read_platform_version(void *dtb) @@ -144,7 +216,7 @@ uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid, u_register_t flags) { uint32_t ns; - + uint64_t index; /* Determine which security state this SMC originated from */ ns = is_caller_non_secure(flags); if (!ns) { @@ -163,6 +235,16 @@ uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid, case SIP_SVC_GET_GIC_ITS: SMC_RET2(handle, NULL, gic_its_addr);
+ case SIP_SVC_GET_MEMORY: + index = x1; + SMC_RET4(handle, NULL, + sbsa_mem_info.memnode[index].nodeid, + sbsa_mem_info.memnode[index].addr_base, + sbsa_mem_info.memnode[index].addr_size); + + case SIP_SVC_GET_MEMORYNODE_COUNT: + SMC_RET2(handle, NULL, sbsa_mem_info.num_memnode); + default: ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid, smc_fid - SIP_FUNCTION);