From 11c2fd3e01835fe8562a7dae4842a645c9fe8bb5 Mon Sep 17 00:00:00 2001 From: aliguori Date: Tue, 21 Apr 2009 22:31:41 +0000 Subject: sending NUMA topology to BIOS (Andre Przywara) uses the QEMU firmware configuration interfacce to send the NUMA topology to the BIOS, which has to setup the tables. Only one firmware configuration channel is used. Signed-off-by: Andre Przywara Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7212 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/fw_cfg.h | 1 + hw/pc.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'hw') diff --git a/hw/fw_cfg.h b/hw/fw_cfg.h index 41a3dd0..f616ed2 100644 --- a/hw/fw_cfg.h +++ b/hw/fw_cfg.h @@ -14,6 +14,7 @@ #define FW_CFG_INITRD_ADDR 0x0a #define FW_CFG_INITRD_SIZE 0x0b #define FW_CFG_BOOT_DEVICE 0x0c +#define FW_CFG_NUMA 0x0d #define FW_CFG_MAX_ENTRY 0x10 #define FW_CFG_WRITE_CHANNEL 0x4000 diff --git a/hw/pc.c b/hw/pc.c index cac6fb1..07b75f3 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -424,11 +424,15 @@ static void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val) } } +extern uint64_t node_cpumask[MAX_NODES]; + static void bochs_bios_init(void) { void *fw_cfg; uint8_t *smbios_table; size_t smbios_len; + uint64_t *numa_fw_cfg; + int i, j; register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL); register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL); @@ -451,6 +455,26 @@ static void bochs_bios_init(void) if (smbios_table) fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, smbios_table, smbios_len); + + /* allocate memory for the NUMA channel: one (64bit) word for the number + * of nodes, one word for each VCPU->node and one word for each node to + * hold the amount of memory. + */ + numa_fw_cfg = qemu_mallocz((1 + smp_cpus + nb_numa_nodes) * 8); + numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes); + for (i = 0; i < smp_cpus; i++) { + for (j = 0; j < nb_numa_nodes; j++) { + if (node_cpumask[j] & (1 << i)) { + numa_fw_cfg[i + 1] = cpu_to_le64(j); + break; + } + } + } + for (i = 0; i < nb_numa_nodes; i++) { + numa_fw_cfg[smp_cpus + 1 + i] = cpu_to_le64(node_mem[i]); + } + fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, (uint8_t *)numa_fw_cfg, + (1 + smp_cpus + nb_numa_nodes) * 8); } /* Generate an initial boot sector which sets state and jump to -- cgit v1.1