From: Cédric Le Goater Date: Sat, 22 Oct 2016 09:46:41 +0000 (+0200) Subject: ppc/pnv: add XSCOM handlers to PnvCore X-Git-Tag: TizenStudio_2.0_p2.3.2~9^2~14^2~5^2~101^2~43 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=24ece072504b8c8b03861168d601d174a7948099;p=sdk%2Femulator%2Fqemu.git 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 Signed-off-by: David Gibson --- 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: diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h index a151e28..2955a41 100644 --- a/include/hw/ppc/pnv_core.h +++ b/include/hw/ppc/pnv_core.h @@ -36,6 +36,8 @@ typedef struct PnvCore { /*< public >*/ void *threads; uint32_t pir; + + MemoryRegion xscom_regs; } PnvCore; typedef struct PnvCoreClass { diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h index ee25ec4..5da6e92 100644 --- a/include/hw/ppc/pnv_xscom.h +++ b/include/hw/ppc/pnv_xscom.h @@ -41,6 +41,25 @@ typedef struct PnvXScomInterfaceClass { int (*populate)(PnvXScomInterface *dev, void *fdt, int offset); } PnvXScomInterfaceClass; +/* + * Layout of the XSCOM PCB addresses of EX core 1 + * + * GPIO 0x1100xxxx + * SCOM 0x1101xxxx + * OHA 0x1102xxxx + * CLOCK CTL 0x1103xxxx + * FIR 0x1104xxxx + * THERM 0x1105xxxx + * 0x1106xxxx + * .. + * 0x110Exxxx + * PCB SLAVE 0x110Fxxxx + */ + +#define PNV_XSCOM_EX_BASE 0x10000000 +#define PNV_XSCOM_EX_CORE_BASE(i) (PNV_XSCOM_EX_BASE | (((uint64_t)i) << 24)) +#define PNV_XSCOM_EX_CORE_SIZE 0x100000 + extern void pnv_xscom_realize(PnvChip *chip, Error **errp); extern int pnv_xscom_populate(PnvChip *chip, void *fdt, int offset);