Add DR specific device tree entries for CPU. Signed-off-by: Bharata B Rao <bhar...@linux.vnet.ibm.com> --- hw/ppc/spapr.c | 122 ++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 2 + target-ppc/translate_init.c | 5 ++ 3 files changed, 129 insertions(+)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index de65370..fc6b923 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -312,6 +312,19 @@ sPAPRDrcEntry *spapr_phb_to_drc_entry(uint64_t buid) return NULL; } +sPAPRDrcEntry *spapr_cpu_to_drc_entry(uint64_t cpuid) +{ + int i; + + for (i = SPAPR_DRC_PHB_TABLE_SIZE; i < SPAPR_DRC_TABLE_SIZE; i++) { + if (spapr->drc_table[i].id == cpuid) { + return &spapr->drc_table[i]; + } + } + + return NULL; +} + sPAPRDrcEntry *spapr_find_drc_entry(int drc_index) { int i, j; @@ -412,6 +425,11 @@ sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state) return spapr_add_to_drc_table(SPAPR_DRC_ENTRY_TYPE_PHB, buid, state); } +sPAPRDrcEntry *spapr_add_cpu_to_drc_table(uint64_t buid, uint32_t state) +{ + return spapr_add_to_drc_table(SPAPR_DRC_ENTRY_TYPE_CPU, buid, state); +} + static void spapr_create_drc_dt_entries(void *fdt) { char char_buf[1024]; @@ -494,6 +512,97 @@ static void spapr_create_drc_dt_entries(void *fdt) } } +/* cpus DR configuration */ +static int spapr_create_drc_cpu_dt_entries(void *fdt) +{ + int i, ret, offset; + uint32_t int_buf[max_cpus + 1]; + int smt = kvmppc_smt_threads(); + int fdt_offset = fdt_path_offset(fdt, "/cpus"); + char char_buf[1024]; + uint32_t *entries; + + /* ibm,drc-indexes */ + memset(int_buf, 0, sizeof(int_buf)); + int_buf[0] = cpu_to_be32(max_cpus/smp_threads); + + for (i = 1; i <= max_cpus/smp_threads; i++) { + int_buf[i] = cpu_to_be32(SPAPR_DRC_CPU_ID_BASE + (i - 1) * smt); + } + ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes", int_buf, + sizeof(int_buf)); + if (ret) { + g_warning("error adding 'ibm,drc-indexes' field for CPU FDT"); + } + + /* ibm,drc-names */ + memset(char_buf, 0, sizeof(char_buf)); + entries = (uint32_t *)&char_buf[0]; + *entries = cpu_to_be32(max_cpus/smp_threads); + offset = sizeof(*entries); + + for (i = 1; i <= max_cpus/smp_threads; i++) { + offset += sprintf(char_buf + offset, "CPU %d", (i - 1) * smt); + char_buf[offset++] = '\0'; + } + + ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names", char_buf, offset); + if (ret) { + g_warning("error adding 'ibm,drc-names' field for CPU FDT"); + } + + /* ibm,drc-power-domains */ + memset(int_buf, 0, sizeof(int_buf)); + int_buf[0] = cpu_to_be32(max_cpus/smp_threads); + + for (i = 1; i <= max_cpus/smp_threads; i++) { + int_buf[i] = cpu_to_be32(0xffffffff); + } + + ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains", int_buf, + sizeof(int_buf)); + if (ret) { + g_warning("error adding 'ibm,drc-power-domains' field for CPU FDT"); + } + + /* ibm,drc-types */ + memset(char_buf, 0, sizeof(char_buf)); + entries = (uint32_t *)&char_buf[0]; + *entries = cpu_to_be32(max_cpus/smp_threads); + offset = sizeof(*entries); + + for (i = 1; i < max_cpus/smp_threads; i++) { + offset += sprintf(char_buf + offset, "CPU"); + char_buf[offset++] = '\0'; + } + + ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types", char_buf, offset); + if (ret) { + g_warning("error adding 'ibm,drc-types' field for CPU FDT"); + } + + /* ibm,indicator-9003 */ + memset(int_buf, 0, sizeof(int_buf)); + int_buf[0] = cpu_to_be32(max_cpus/smp_threads); + + ret = fdt_setprop(fdt, fdt_offset, "ibm,indicator-9003", int_buf, + sizeof(int_buf)); + if (ret) { + g_warning("error adding 'ibm,indicator-9003' field for CPU FDT"); + } + + /* ibm,sensor-9003 */ + memset(int_buf, 0, sizeof(int_buf)); + int_buf[0] = cpu_to_be32(max_cpus/smp_threads); + + ret = fdt_setprop(fdt, fdt_offset, "ibm,sensor-9003", int_buf, + sizeof(int_buf)); + if (ret) { + g_warning("error adding 'ibm,sensor-9003' field for CPU FDT"); + } + return ret; +} + #define _FDT(exp) \ do { \ int ret = (exp); \ @@ -641,6 +750,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000; uint32_t page_sizes_prop[64]; size_t page_sizes_prop_size; + sPAPRDrcEntry *drc_entry; if ((index % smt) != 0) { continue; @@ -717,6 +827,12 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, _FDT((fdt_property_cell(fdt, "ibm,chip-id", cs->cpu_index / cpus_per_socket))); + drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id + + SPAPR_DRC_CPU_ID_BASE); + g_assert(drc_entry); + _FDT((fdt_property_cell(fdt, "ibm,my-drc-index", + drc_entry->drc_index))); + _FDT((fdt_end_node(fdt))); } @@ -961,6 +1077,12 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, exit(1); } + ret = spapr_create_drc_cpu_dt_entries(fdt); + if (ret < 0) { + fprintf(stderr, "couldn't setup CPU DR entries in fdt\n"); + exit(1); + } + /* RTAS */ ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size); if (ret < 0) { diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index cb45175..07f3af2 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -527,7 +527,9 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname, int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, sPAPRTCETable *tcet); sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state); +sPAPRDrcEntry *spapr_add_cpu_to_drc_table(uint64_t buid, uint32_t state); sPAPRDrcEntry *spapr_phb_to_drc_entry(uint64_t buid); +sPAPRDrcEntry *spapr_cpu_to_drc_entry(uint64_t cpuid); sPAPRDrcEntry *spapr_find_drc_entry(int drc_index); void spapr_pci_hotplug_add_event(DeviceState *qdev, int slot); void spapr_pci_hotplug_remove_event(DeviceState *qdev, int slot); diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 48177ed..1398f1b 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -30,6 +30,7 @@ #include "qemu/error-report.h" #include "qapi/visitor.h" #include "hw/qdev-properties.h" +#include "hw/ppc/spapr.h" //#define PPC_DUMP_CPU //#define PPC_DEBUG_SPR @@ -8879,6 +8880,10 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt + (cs->cpu_index % smp_threads); + + if (!(cpu->cpu_dt_id % max_smt)) { + spapr_add_cpu_to_drc_table(cpu->cpu_dt_id + SPAPR_DRC_CPU_ID_BASE, 2); + } #endif if (tcg_enabled()) { -- 1.7.11.7