aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2016-10-22 11:46:41 +0200
committerDavid Gibson <david@gibson.dropbear.id.au>2016-10-28 09:38:25 +1100
commit24ece072504b8c8b03861168d601d174a7948099 (patch)
tree1863bdf931a1db9c8d424202c73f36bda248ffd9 /hw
parent967b75230b9720ea2b3ae49f38f8287026125f9f (diff)
downloadqemu-24ece072504b8c8b03861168d601d174a7948099.zip
qemu-24ece072504b8c8b03861168d601d174a7948099.tar.gz
qemu-24ece072504b8c8b03861168d601d174a7948099.tar.bz2
ppc/pnv: add XSCOM handlers to PnvCore
Now that we are using real HW ids for the cores in PowerNV chips, we can route the XSCOM accesses to them. We just need to attach a specific XSCOM memory region to each core in the appropriate window for the core number. To start with, let's install the DTS (Digital Thermal Sensor) handlers which should return 38°C for each core. Signed-off-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw')
-rw-r--r--hw/ppc/pnv.c4
-rw-r--r--hw/ppc/pnv_core.c50
2 files changed, 54 insertions, 0 deletions
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 96ba36c..df55a89 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -625,6 +625,10 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
object_property_set_bool(OBJECT(pnv_core), true, "realized",
&error_fatal);
object_unref(OBJECT(pnv_core));
+
+ /* Each core has an XSCOM MMIO region */
+ pnv_xscom_add_subregion(chip, PNV_XSCOM_EX_CORE_BASE(core_hwid),
+ &PNV_CORE(pnv_core)->xscom_regs);
i++;
}
g_free(typename);
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 04713ca..2acda96 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
#include "qapi/error.h"
+#include "qemu/log.h"
#include "target-ppc/cpu.h"
#include "hw/ppc/ppc.h"
#include "hw/ppc/pnv.h"
@@ -63,6 +64,51 @@ static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp)
qemu_register_reset(powernv_cpu_reset, cpu);
}
+/*
+ * These values are read by the PowerNV HW monitors under Linux
+ */
+#define PNV_XSCOM_EX_DTS_RESULT0 0x50000
+#define PNV_XSCOM_EX_DTS_RESULT1 0x50001
+
+static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
+ unsigned int width)
+{
+ uint32_t offset = addr >> 3;
+ uint64_t val = 0;
+
+ /* The result should be 38 C */
+ switch (offset) {
+ case PNV_XSCOM_EX_DTS_RESULT0:
+ val = 0x26f024f023f0000ull;
+ break;
+ case PNV_XSCOM_EX_DTS_RESULT1:
+ val = 0x24f000000000000ull;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx,
+ addr);
+ }
+
+ return val;
+}
+
+static void pnv_core_xscom_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned int width)
+{
+ qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx,
+ addr);
+}
+
+static const MemoryRegionOps pnv_core_xscom_ops = {
+ .read = pnv_core_xscom_read,
+ .write = pnv_core_xscom_write,
+ .valid.min_access_size = 8,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 8,
+ .impl.max_access_size = 8,
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
static void pnv_core_realize_child(Object *child, Error **errp)
{
Error *local_err = NULL;
@@ -118,6 +164,10 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
goto err;
}
}
+
+ snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
+ pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), &pnv_core_xscom_ops,
+ pc, name, PNV_XSCOM_EX_CORE_SIZE);
return;
err: