@@ -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) {
@@ -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);
@@ -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()) {
Add DR specific device tree entries for CPU. Signed-off-by: Bharata B Rao <bharata@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(+)