aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/pnv_occ.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-03-12 10:15:00 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-03-12 10:15:00 +0000
commitbc76b7148993269608c19fd3f2fc6ed3e22bf838 (patch)
treef395ace7347fba72d7d1a09bcee50142571a9724 /hw/ppc/pnv_occ.c
parent377b155bde451d5ac545fbdcdfbf6ca17a4228f5 (diff)
parent013002f0fbf62545c0f5ea4c5c2d554a85919647 (diff)
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.0-20190312' into staging
ppc patch queue for 2019-03-10 This pull requests supersedes ppc-for-4.0-20190310. Changes are: * Fixed a bunch of minor style problems * Suppressed warnings about Spectre/Meltdown mitigations with TCG * Added one more patch, a preliminary fix towards the not-quite-ready support for NVLink VFIO passthrough. This is a final pull request before the 4.0 soft freeze. Changes include: * A Great Renaming to use camel case properly in spapr code * Optimization of some vector instructions * Support for POWER9 cpus in the powernv machine * Fixes a regression from the last pull request in handling VSX instructions with mixed operands from the FPR and VMX parts of the register array * Optimization hack to avoid scanning all the (empty) entries on a new IOMMU window * Add FSL I2C controller model for E500 * Support for KVM acceleration of the H_PAGE_INIT hypercall on spapr * Update u-boot image for E500 * Enable Specre/Meltdown mitigations by default on the new machine type * Enable large decrementer support for POWER9 # gpg: Signature made Tue 12 Mar 2019 08:14:51 GMT # gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full] # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full] # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full] # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown] # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-4.0-20190312: (62 commits) vfio: Make vfio_get_region_info_cap public Suppress test warnings about missing Spectre/Meltdown mitigations with TCG spapr: Use CamelCase properly target/ppc: Optimize x[sv]xsigdp using deposit_i64() target/ppc: Optimize xviexpdp() using deposit_i64() target/ppc: add HV support for POWER9 ppc/pnv: add a "ibm,opal/power-mgt" device tree node on POWER9 ppc/pnv: add more dummy XSCOM addresses ppc/pnv: activate XSCOM tests for POWER9 ppc/pnv: POWER9 XSCOM quad support ppc/pnv: extend XSCOM core support for POWER9 ppc/pnv: add a OCC model for POWER9 ppc/pnv: add a OCC model class ppc/pnv: add SerIRQ routing registers ppc/pnv: add a LPC Controller model for POWER9 ppc/pnv: add a 'dt_isa_nodename' to the chip ppc/pnv: add a LPC Controller class model ppc/pnv: lpc: fix OPB address ranges ppc/pnv: add a PSI bridge model for POWER9 ppc/pnv: add a PSI bridge class model ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ppc/pnv_occ.c')
-rw-r--r--hw/ppc/pnv_occ.c127
1 files changed, 110 insertions, 17 deletions
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
index 04880f26d6..fdd9296e1b 100644
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@ -34,15 +34,17 @@
static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
{
bool irq_state;
+ PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
val &= 0xffff000000000000ull;
occ->occmisc = val;
irq_state = !!(val >> 63);
- pnv_psi_irq_set(occ->psi, PSIHB_IRQ_OCC, irq_state);
+ pnv_psi_irq_set(occ->psi, poc->psi_irq, irq_state);
}
-static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
+static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr,
+ unsigned size)
{
PnvOCC *occ = PNV_OCC(opaque);
uint32_t offset = addr >> 3;
@@ -54,13 +56,13 @@ static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
break;
default:
qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
- HWADDR_PRIx "\n", addr);
+ HWADDR_PRIx "\n", addr >> 3);
}
return val;
}
-static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
+static void pnv_occ_power8_xscom_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
{
PnvOCC *occ = PNV_OCC(opaque);
uint32_t offset = addr >> 3;
@@ -77,13 +79,13 @@ static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
break;
default:
qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
- HWADDR_PRIx "\n", addr);
+ HWADDR_PRIx "\n", addr >> 3);
}
}
-static const MemoryRegionOps pnv_occ_xscom_ops = {
- .read = pnv_occ_xscom_read,
- .write = pnv_occ_xscom_write,
+static const MemoryRegionOps pnv_occ_power8_xscom_ops = {
+ .read = pnv_occ_power8_xscom_read,
+ .write = pnv_occ_power8_xscom_write,
.valid.min_access_size = 8,
.valid.max_access_size = 8,
.impl.min_access_size = 8,
@@ -91,27 +93,113 @@ static const MemoryRegionOps pnv_occ_xscom_ops = {
.endianness = DEVICE_BIG_ENDIAN,
};
+static void pnv_occ_power8_class_init(ObjectClass *klass, void *data)
+{
+ PnvOCCClass *poc = PNV_OCC_CLASS(klass);
+
+ poc->xscom_size = PNV_XSCOM_OCC_SIZE;
+ poc->xscom_ops = &pnv_occ_power8_xscom_ops;
+ poc->psi_irq = PSIHB_IRQ_OCC;
+}
+
+static const TypeInfo pnv_occ_power8_type_info = {
+ .name = TYPE_PNV8_OCC,
+ .parent = TYPE_PNV_OCC,
+ .instance_size = sizeof(PnvOCC),
+ .class_init = pnv_occ_power8_class_init,
+};
+
+#define P9_OCB_OCI_OCCMISC 0x6080
+#define P9_OCB_OCI_OCCMISC_CLEAR 0x6081
+#define P9_OCB_OCI_OCCMISC_OR 0x6082
+
+
+static uint64_t pnv_occ_power9_xscom_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ PnvOCC *occ = PNV_OCC(opaque);
+ uint32_t offset = addr >> 3;
+ uint64_t val = 0;
+
+ switch (offset) {
+ case P9_OCB_OCI_OCCMISC:
+ val = occ->occmisc;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
+ HWADDR_PRIx "\n", addr >> 3);
+ }
+ return val;
+}
+
+static void pnv_occ_power9_xscom_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ PnvOCC *occ = PNV_OCC(opaque);
+ uint32_t offset = addr >> 3;
+
+ switch (offset) {
+ case P9_OCB_OCI_OCCMISC_CLEAR:
+ pnv_occ_set_misc(occ, 0);
+ break;
+ case P9_OCB_OCI_OCCMISC_OR:
+ pnv_occ_set_misc(occ, occ->occmisc | val);
+ break;
+ case P9_OCB_OCI_OCCMISC:
+ pnv_occ_set_misc(occ, val);
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
+ HWADDR_PRIx "\n", addr >> 3);
+ }
+}
+
+static const MemoryRegionOps pnv_occ_power9_xscom_ops = {
+ .read = pnv_occ_power9_xscom_read,
+ .write = pnv_occ_power9_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_occ_power9_class_init(ObjectClass *klass, void *data)
+{
+ PnvOCCClass *poc = PNV_OCC_CLASS(klass);
+
+ poc->xscom_size = PNV9_XSCOM_OCC_SIZE;
+ poc->xscom_ops = &pnv_occ_power9_xscom_ops;
+ poc->psi_irq = PSIHB9_IRQ_OCC;
+}
+
+static const TypeInfo pnv_occ_power9_type_info = {
+ .name = TYPE_PNV9_OCC,
+ .parent = TYPE_PNV_OCC,
+ .instance_size = sizeof(PnvOCC),
+ .class_init = pnv_occ_power9_class_init,
+};
static void pnv_occ_realize(DeviceState *dev, Error **errp)
{
PnvOCC *occ = PNV_OCC(dev);
+ PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
Object *obj;
- Error *error = NULL;
+ Error *local_err = NULL;
occ->occmisc = 0;
- /* get PSI object from chip */
- obj = object_property_get_link(OBJECT(dev), "psi", &error);
+ obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
if (!obj) {
- error_setg(errp, "%s: required link 'psi' not found: %s",
- __func__, error_get_pretty(error));
+ error_propagate(errp, local_err);
+ error_prepend(errp, "required link 'psi' not found: ");
return;
}
occ->psi = PNV_PSI(obj);
/* XScom region for OCC registers */
- pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), &pnv_occ_xscom_ops,
- occ, "xscom-occ", PNV_XSCOM_OCC_SIZE);
+ pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), poc->xscom_ops,
+ occ, "xscom-occ", poc->xscom_size);
}
static void pnv_occ_class_init(ObjectClass *klass, void *data)
@@ -119,6 +207,7 @@ static void pnv_occ_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = pnv_occ_realize;
+ dc->desc = "PowerNV OCC Controller";
}
static const TypeInfo pnv_occ_type_info = {
@@ -126,11 +215,15 @@ static const TypeInfo pnv_occ_type_info = {
.parent = TYPE_DEVICE,
.instance_size = sizeof(PnvOCC),
.class_init = pnv_occ_class_init,
+ .class_size = sizeof(PnvOCCClass),
+ .abstract = true,
};
static void pnv_occ_register_types(void)
{
type_register_static(&pnv_occ_type_info);
+ type_register_static(&pnv_occ_power8_type_info);
+ type_register_static(&pnv_occ_power9_type_info);
}
-type_init(pnv_occ_register_types)
+type_init(pnv_occ_register_types);