[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 59/60] ppc/pnv: Add QME region for P10
From: |
Daniel Henrique Barboza |
Subject: |
[PULL 59/60] ppc/pnv: Add QME region for P10 |
Date: |
Fri, 7 Jul 2023 08:31:07 -0300 |
From: Joel Stanley <joel@jms.id.au>
The Quad Management Engine (QME) manages power related settings for its
quad. The xscom region is separate from the quad xscoms, therefore a new
region is added. The xscoms in a QME select a given core by selecting
the forth nibble.
Implement dummy reads for the stop state history (SSH) and special
wakeup (SPWU) registers. This quietens some sxcom errors when skiboot
boots on p10.
Power9 does not have a QME.
Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Message-ID: <20230707071213.9924-1-joel@jms.id.au>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
hw/ppc/pnv.c | 3 ++
hw/ppc/pnv_core.c | 78 +++++++++++++++++++++++++++++++++++++-
include/hw/ppc/pnv_core.h | 4 ++
include/hw/ppc/pnv_xscom.h | 11 ++++++
4 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 23740f9d07..eb54f93986 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1685,6 +1685,9 @@ static void pnv_chip_power10_quad_realize(Pnv10Chip
*chip10, Error **errp)
pnv_xscom_add_subregion(chip, PNV10_XSCOM_EQ_BASE(eq->quad_id),
&eq->xscom_regs);
+
+ pnv_xscom_add_subregion(chip, PNV10_XSCOM_QME_BASE(eq->quad_id),
+ &eq->xscom_qme_regs);
}
}
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 9e7cf341dc..9b39d527de 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -496,7 +496,67 @@ static const MemoryRegionOps pnv_quad_power10_xscom_ops = {
.endianness = DEVICE_BIG_ENDIAN,
};
-static void pnv_quad_realize(DeviceState *dev, Error **errp)
+#define P10_QME_SPWU_HYP 0x83c
+#define P10_QME_SSH_HYP 0x82c
+
+static uint64_t pnv_qme_power10_xscom_read(void *opaque, hwaddr addr,
+ unsigned int width)
+{
+ uint32_t offset = addr >> 3;
+ uint64_t val = -1;
+
+ /*
+ * Forth nibble selects the core within a quad, mask it to process read
+ * for any core.
+ */
+ switch (offset & ~0xf000) {
+ case P10_QME_SPWU_HYP:
+ case P10_QME_SSH_HYP:
+ return 0;
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: unimp read 0x%08x\n", __func__,
+ offset);
+ }
+
+ return val;
+}
+
+static void pnv_qme_power10_xscom_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned int width)
+{
+ uint32_t offset = addr >> 3;
+
+ switch (offset) {
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: unimp write 0x%08x\n", __func__,
+ offset);
+ }
+}
+
+static const MemoryRegionOps pnv_qme_power10_xscom_ops = {
+ .read = pnv_qme_power10_xscom_read,
+ .write = pnv_qme_power10_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_quad_power9_realize(DeviceState *dev, Error **errp)
+{
+ PnvQuad *eq = PNV_QUAD(dev);
+ PnvQuadClass *pqc = PNV_QUAD_GET_CLASS(eq);
+ char name[32];
+
+ snprintf(name, sizeof(name), "xscom-quad.%d", eq->quad_id);
+ pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev),
+ pqc->xscom_ops,
+ eq, name,
+ pqc->xscom_size);
+}
+
+static void pnv_quad_power10_realize(DeviceState *dev, Error **errp)
{
PnvQuad *eq = PNV_QUAD(dev);
PnvQuadClass *pqc = PNV_QUAD_GET_CLASS(eq);
@@ -507,6 +567,12 @@ static void pnv_quad_realize(DeviceState *dev, Error
**errp)
pqc->xscom_ops,
eq, name,
pqc->xscom_size);
+
+ snprintf(name, sizeof(name), "xscom-qme.%d", eq->quad_id);
+ pnv_xscom_region_init(&eq->xscom_qme_regs, OBJECT(dev),
+ pqc->xscom_qme_ops,
+ eq, name,
+ pqc->xscom_qme_size);
}
static Property pnv_quad_properties[] = {
@@ -517,6 +583,9 @@ static Property pnv_quad_properties[] = {
static void pnv_quad_power9_class_init(ObjectClass *oc, void *data)
{
PnvQuadClass *pqc = PNV_QUAD_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = pnv_quad_power9_realize;
pqc->xscom_ops = &pnv_quad_power9_xscom_ops;
pqc->xscom_size = PNV9_XSCOM_EQ_SIZE;
@@ -525,16 +594,21 @@ static void pnv_quad_power9_class_init(ObjectClass *oc,
void *data)
static void pnv_quad_power10_class_init(ObjectClass *oc, void *data)
{
PnvQuadClass *pqc = PNV_QUAD_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = pnv_quad_power10_realize;
pqc->xscom_ops = &pnv_quad_power10_xscom_ops;
pqc->xscom_size = PNV10_XSCOM_EQ_SIZE;
+
+ pqc->xscom_qme_ops = &pnv_qme_power10_xscom_ops;
+ pqc->xscom_qme_size = PNV10_XSCOM_QME_SIZE;
}
static void pnv_quad_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
- dc->realize = pnv_quad_realize;
device_class_set_props(dc, pnv_quad_properties);
dc->user_creatable = false;
}
diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index aa5ca281fc..4db21229a6 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -66,6 +66,9 @@ struct PnvQuadClass {
const MemoryRegionOps *xscom_ops;
uint64_t xscom_size;
+
+ const MemoryRegionOps *xscom_qme_ops;
+ uint64_t xscom_qme_size;
};
#define TYPE_PNV_QUAD "powernv-cpu-quad"
@@ -80,5 +83,6 @@ struct PnvQuad {
uint32_t quad_id;
MemoryRegion xscom_regs;
+ MemoryRegion xscom_qme_regs;
};
#endif /* PPC_PNV_CORE_H */
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index a4c9d95dc5..9bc6463547 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -127,6 +127,17 @@ struct PnvXScomInterfaceClass {
#define PNV10_XSCOM_EC(proc) \
((0x2 << 16) | ((1 << (3 - (proc))) << 12))
+#define PNV10_XSCOM_QME(chiplet) \
+ (PNV10_XSCOM_EQ(chiplet) | (0xE << 16))
+
+/*
+ * Make the region larger by 0x1000 (instead of starting at an offset) so the
+ * modelled addresses start from 0
+ */
+#define PNV10_XSCOM_QME_BASE(core) \
+ ((uint64_t) PNV10_XSCOM_QME(PNV10_XSCOM_EQ_CHIPLET(core)))
+#define PNV10_XSCOM_QME_SIZE (0x8000 + 0x1000)
+
#define PNV10_XSCOM_EQ_BASE(core) \
((uint64_t) PNV10_XSCOM_EQ(PNV10_XSCOM_EQ_CHIPLET(core)))
#define PNV10_XSCOM_EQ_SIZE 0x20000
--
2.41.0
- [PULL 50/60] ppc/pnv: Set P10 core xscom region size to match hardware, (continued)
- [PULL 50/60] ppc/pnv: Set P10 core xscom region size to match hardware, Daniel Henrique Barboza, 2023/07/07
- [PULL 49/60] ppc/pnv: Log all unimp warnings with similar message, Daniel Henrique Barboza, 2023/07/07
- [PULL 51/60] tests/qtest: Add xscom tests for powernv10 machine, Daniel Henrique Barboza, 2023/07/07
- [PULL 52/60] target/ppc: Machine check on invalid real address access on POWER9/10, Daniel Henrique Barboza, 2023/07/07
- [PULL 53/60] target/ppc: Have 'kvm_ppc.h' include 'sysemu/kvm.h', Daniel Henrique Barboza, 2023/07/07
- [PULL 54/60] target/ppc: Reorder #ifdef'ry in kvm_ppc.h, Daniel Henrique Barboza, 2023/07/07
- [PULL 55/60] target/ppc: Move CPU QOM definitions to cpu-qom.h, Daniel Henrique Barboza, 2023/07/07
- [PULL 56/60] target/ppc: Define TYPE_HOST_POWERPC_CPU in cpu-qom.h, Daniel Henrique Barboza, 2023/07/07
- [PULL 57/60] target/ppc: Restrict 'kvm_ppc.h' to sysemu in cpu_init.c, Daniel Henrique Barboza, 2023/07/07
- [PULL 58/60] target/ppc: Remove pointless checks of CONFIG_USER_ONLY in 'kvm_ppc.h', Daniel Henrique Barboza, 2023/07/07
- [PULL 59/60] ppc/pnv: Add QME region for P10,
Daniel Henrique Barboza <=
- [PULL 60/60] ppc: Enable 2nd DAWR support on p10, Daniel Henrique Barboza, 2023/07/07
- Re: [PULL 00/60] ppc queue, Daniel Henrique Barboza, 2023/07/07