qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH v0 08/15] ppc: Add CPU dynamic reconfiguration (


From: Bharata B Rao
Subject: [Qemu-devel] [RFC PATCH v0 08/15] ppc: Add CPU dynamic reconfiguration (DR) support
Date: Thu, 4 Sep 2014 11:36:18 +0530

Add DR specific device tree entries for CPU.

Signed-off-by: Bharata B Rao <address@hidden>
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]