Merge "feat(qemu-sbsa): handle memory information" into integration

This commit is contained in:
Sandrine Bailleux 2024-01-24 07:57:49 +01:00 committed by TrustedFirmware Code Review
commit fc26a0fcac
2 changed files with 103 additions and 0 deletions

View file

@ -61,6 +61,11 @@
#define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
/*
* Define the max number of memory nodes.
*/
#define PLAT_MAX_MEM_NODES 128
/*
* Partition memory into secure ROM, non-secure DRAM, secure "SRAM",
* and secure DRAM.

View file

@ -30,6 +30,8 @@ static int platform_version_minor;
#define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101)
#define SIP_SVC_GET_CPU_COUNT SIP_FUNCTION_ID(200)
#define SIP_SVC_GET_CPU_NODE SIP_FUNCTION_ID(201)
#define SIP_SVC_GET_MEMORY_NODE_COUNT SIP_FUNCTION_ID(300)
#define SIP_SVC_GET_MEMORY_NODE SIP_FUNCTION_ID(301)
static uint64_t gic_its_addr;
@ -38,9 +40,17 @@ typedef struct {
uint32_t mpidr;
} cpu_data;
typedef struct{
uint32_t nodeid;
uint64_t addr_base;
uint64_t addr_size;
} memory_data;
static struct {
uint32_t num_cpus;
uint32_t num_memnodes;
cpu_data cpu[PLATFORM_CORE_COUNT];
memory_data memory[PLAT_MAX_MEM_NODES];
} dynamic_platform_info;
void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base);
@ -127,6 +137,79 @@ void read_cpuinfo_from_dt(void *dtb)
INFO("Found %d cpus\n", dynamic_platform_info.num_cpus);
}
void read_meminfo_from_dt(void *dtb)
{
const fdt32_t *prop;
const char *type;
int prev, node;
int len;
uint32_t nodeid = 0;
uint32_t memnode = 0;
uint32_t higher_value, lower_value;
uint64_t cur_base, cur_size;
/*
* QEMU gives us this DeviceTree node:
*
* memory@100c0000000 {
* numa-node-id = <0x01>;
* reg = <0x100 0xc0000000 0x00 0x40000000>;
* device_type = "memory";
* };
*
* memory@10000000000 {
* numa-node-id = <0x00>;
* reg = <0x100 0x00 0x00 0xc0000000>;
* device_type = "memory";
* }
*/
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) {
if (fdt_getprop(dtb, node, "numa-node-id", NULL)) {
fdt_read_uint32(dtb, node, "numa-node-id", &nodeid);
}
dynamic_platform_info.memory[memnode].nodeid = nodeid;
/*
* 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);
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);
dynamic_platform_info.memory[memnode].addr_base = cur_base;
dynamic_platform_info.memory[memnode].addr_size = cur_size;
INFO("RAM %d: node-id: %d, address: 0x%lx - 0x%lx\n",
memnode,
dynamic_platform_info.memory[memnode].nodeid,
dynamic_platform_info.memory[memnode].addr_base,
dynamic_platform_info.memory[memnode].addr_base +
dynamic_platform_info.memory[memnode].addr_size - 1);
}
memnode++;
}
}
dynamic_platform_info.num_memnodes = memnode;
}
void read_platform_config_from_dt(void *dtb)
{
int node;
@ -222,6 +305,7 @@ void sip_svc_init(void)
read_platform_config_from_dt(dtb);
read_cpuinfo_from_dt(dtb);
read_meminfo_from_dt(dtb);
}
/*
@ -270,6 +354,20 @@ uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid,
SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
}
case SIP_SVC_GET_MEMORY_NODE_COUNT:
SMC_RET2(handle, NULL, dynamic_platform_info.num_memnodes);
case SIP_SVC_GET_MEMORY_NODE:
index = x1;
if (index < PLAT_MAX_MEM_NODES) {
SMC_RET4(handle, NULL,
dynamic_platform_info.memory[index].nodeid,
dynamic_platform_info.memory[index].addr_base,
dynamic_platform_info.memory[index].addr_size);
} else {
SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
}
default:
ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid,
smc_fid - SIP_FUNCTION);