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 XScomDevice to each core with the associated ranges in the XSCOM address space.
To start with, let's install the DTS (Digital Thermal Sensor) handlers which are easy to handle. Signed-off-by: Cédric Le Goater <c...@kaod.org> --- hw/ppc/pnv.c | 9 +++++++ hw/ppc/pnv_core.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv_core.h | 13 +++++++++ 3 files changed, 89 insertions(+) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index daf9f459ab0e..a31568415192 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -527,6 +527,7 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp) for (i = 0, core_hwid = 0; (core_hwid < sizeof(chip->cores_mask) * 8) && (i < chip->num_cores); core_hwid++) { PnvCore *pnv_core = &chip->cores[i]; + DeviceState *qdev; if (!(chip->cores_mask & (1 << core_hwid))) { continue; @@ -542,6 +543,14 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp) &error_fatal); object_unref(OBJECT(pnv_core)); i++; + + /* Attach the core to its XSCOM bus */ + qdev = qdev_create(&chip->xscom->bus, TYPE_PNV_CORE_XSCOM); + qdev_prop_set_uint32(qdev, "core-pir", + P8_PIR(chip->chip_id, core_hwid)); + qdev_init_nofail(qdev); + + pnv_core->xd = PNV_CORE_XSCOM(qdev); } g_free(typename); diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 825aea1194a1..feba374740dc 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -18,7 +18,9 @@ */ #include "qemu/osdep.h" #include "sysemu/sysemu.h" +#include "qemu/error-report.h" #include "qapi/error.h" +#include "qemu/log.h" #include "target-ppc/cpu.h" #include "hw/ppc/ppc.h" #include "hw/ppc/pnv.h" @@ -144,10 +146,75 @@ static const TypeInfo pnv_core_info = { .abstract = true, }; + +#define DTS_RESULT0 0x50000 +#define DTS_RESULT1 0x50001 + +static bool pnv_core_xscom_read(XScomDevice *dev, uint32_t range, + uint32_t offset, uint64_t *out_val) +{ + switch (offset) { + case DTS_RESULT0: + *out_val = 0x26f024f023f0000ull; + break; + case DTS_RESULT1: + *out_val = 0x24f000000000000ull; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "Warning: reading reg=0x%08x", offset); + } + + return true; +} + +static bool pnv_core_xscom_write(XScomDevice *dev, uint32_t range, + uint32_t offset, uint64_t val) +{ + qemu_log_mask(LOG_GUEST_ERROR, "Warning: writing to reg=0x%08x", offset); + return true; +} + +#define EX_XSCOM_BASE 0x10000000 +#define EX_XSCOM_SIZE 0x100000 + +static void pnv_core_xscom_realize(DeviceState *dev, Error **errp) +{ + XScomDevice *xd = XSCOM_DEVICE(dev); + PnvCoreXScom *pnv_xd = PNV_CORE_XSCOM(dev); + + xd->ranges[0].addr = EX_XSCOM_BASE | P8_PIR2COREID(pnv_xd->core_pir) << 24; + xd->ranges[0].size = EX_XSCOM_SIZE; +} + +static Property pnv_core_xscom_properties[] = { + DEFINE_PROP_UINT32("core-pir", PnvCoreXScom, core_pir, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void pnv_core_xscom_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + XScomDeviceClass *xdc = XSCOM_DEVICE_CLASS(klass); + + xdc->read = pnv_core_xscom_read; + xdc->write = pnv_core_xscom_write; + + dc->realize = pnv_core_xscom_realize; + dc->props = pnv_core_xscom_properties; +} + +static const TypeInfo pnv_core_xscom_type_info = { + .name = TYPE_PNV_CORE_XSCOM, + .parent = TYPE_XSCOM_DEVICE, + .instance_size = sizeof(PnvCoreXScom), + .class_init = pnv_core_xscom_class_init, +}; + static void pnv_core_register_types(void) { int i ; + type_register_static(&pnv_core_xscom_type_info); type_register_static(&pnv_core_info); for (i = 0; i < ARRAY_SIZE(pnv_core_models); ++i) { TypeInfo ti = { diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h index 832c8756afaa..72936ccfd22f 100644 --- a/include/hw/ppc/pnv_core.h +++ b/include/hw/ppc/pnv_core.h @@ -20,6 +20,18 @@ #define _PPC_PNV_CORE_H #include "hw/cpu/core.h" +#include "hw/ppc/pnv_xscom.h" + +#define TYPE_PNV_CORE_XSCOM "powernv-cpu-core-xscom" +#define PNV_CORE_XSCOM(obj) \ + OBJECT_CHECK(PnvCoreXScom, (obj), TYPE_PNV_CORE_XSCOM) + +typedef struct PnvCoreXScom { + XScomDevice xd; + uint32_t core_pir; +} PnvCoreXScom; + +#define P8_PIR2COREID(pir) (((pir) >> 3) & 0xf) #define TYPE_PNV_CORE "powernv-cpu-core" #define PNV_CORE(obj) \ @@ -35,6 +47,7 @@ typedef struct PnvCore { /*< public >*/ void *threads; + PnvCoreXScom *xd; } PnvCore; typedef struct PnvCoreClass { -- 2.7.4