hw/ppc/meson.build | 1 + hw/ppc/pnv.c | 10 ++++ hw/ppc/pnv_ocmb.c | 103 ++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv.h | 3 ++ include/hw/ppc/pnv_chip.h | 2 + include/hw/ppc/pnv_ocmb.h | 38 ++++++++++++++ 6 files changed, 157 insertions(+) create mode 100644 hw/ppc/pnv_ocmb.c create mode 100644 include/hw/ppc/pnv_ocmb.h
The Power Hypervisor for P10 expects to be able to access certain
Open CAPI Memory Buffer (OCMB) chip registers. Since QEMU does not
currently support these registers, several access errors are being
posted. The hypervisor is able to progress despite these errors,
but it does create unwanted noise on the console. Adding some
dummy MMIO support for this IO region in order to suppress the
error messages.
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Signed-off-by: Caleb Schlossin <calebs@linux.ibm.com>
---
hw/ppc/meson.build | 1 +
hw/ppc/pnv.c | 10 ++++
hw/ppc/pnv_ocmb.c | 103 ++++++++++++++++++++++++++++++++++++++
include/hw/ppc/pnv.h | 3 ++
include/hw/ppc/pnv_chip.h | 2 +
include/hw/ppc/pnv_ocmb.h | 38 ++++++++++++++
6 files changed, 157 insertions(+)
create mode 100644 hw/ppc/pnv_ocmb.c
create mode 100644 include/hw/ppc/pnv_ocmb.h
diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index f7dac87a2a..b3924119ae 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -56,6 +56,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files(
'pnv_pnor.c',
'pnv_nest_pervasive.c',
'pnv_n1_chiplet.c',
+ 'pnv_ocmb.c',
))
# PowerPC 4xx boards
ppc_ss.add(when: 'CONFIG_PPC405', if_true: files(
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 895132da91..670c28fed2 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -2187,6 +2187,7 @@ static void pnv_chip_power10_instance_init(Object *obj)
object_initialize_child(obj, "homer", &chip10->homer, TYPE_PNV10_HOMER);
object_initialize_child(obj, "n1-chiplet", &chip10->n1_chiplet,
TYPE_PNV_N1_CHIPLET);
+ object_initialize_child(obj, "ocmb", &chip10->ocmb, TYPE_PNV10_OCMB);
chip->num_pecs = pcc->num_pecs;
@@ -2409,6 +2410,15 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
pnv_xscom_add_subregion(chip, PNV10_XSCOM_N1_PB_SCOM_ES_BASE,
&chip10->n1_chiplet.xscom_pb_es_mr);
+ /* Memory Controller OCMB CFG/MMIO space */
+ object_property_set_link(OBJECT(&chip10->ocmb), "chip", OBJECT(chip),
+ &error_abort);
+ if (!qdev_realize(DEVICE(&chip10->ocmb), NULL, errp)) {
+ return;
+ }
+ memory_region_add_subregion(get_system_memory(), PNV10_OCMB_BASE(chip),
+ &chip10->ocmb.regs);
+
/* PHBs */
pnv_chip_power10_phb_realize(chip, &local_err);
if (local_err) {
diff --git a/hw/ppc/pnv_ocmb.c b/hw/ppc/pnv_ocmb.c
new file mode 100644
index 0000000000..c991ccbd54
--- /dev/null
+++ b/hw/ppc/pnv_ocmb.c
@@ -0,0 +1,103 @@
+/*
+ * QEMU PowerPC PowerNV Emulation of OCMB related registers
+ *
+ * Copyright (c) 2025, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "exec/hwaddr.h"
+#include "system/memory.h"
+#include "system/cpus.h"
+#include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_chip.h"
+#include "hw/ppc/pnv_ocmb.h"
+
+static uint64_t pnv_power10_ocmb_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ /* TODO: Add support for OCMB reads */
+ return 0;
+}
+
+static void pnv_power10_ocmb_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ /* TODO: Add support for OCMB writes */
+ return;
+}
+
+static const MemoryRegionOps pnv_power10_ocmb_ops = {
+ .read = pnv_power10_ocmb_read,
+ .write = pnv_power10_ocmb_write,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 1,
+ .impl.max_access_size = 8,
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void pnv_ocmb_power10_class_init(ObjectClass *klass, const void *data)
+{
+ PnvOcmbClass *ocmb = PNV_OCMB_CLASS(klass);
+
+ ocmb->ocmb_size = PNV10_OCMB_SIZE;
+ ocmb->ocmb_ops = &pnv_power10_ocmb_ops;
+}
+
+static const TypeInfo pnv_ocmb_power10_type_info = {
+ .name = TYPE_PNV10_OCMB,
+ .parent = TYPE_PNV_OCMB,
+ .instance_size = sizeof(PnvOcmb),
+ .class_init = pnv_ocmb_power10_class_init,
+};
+
+static void pnv_ocmb_realize(DeviceState *dev, Error **errp)
+{
+ PnvOcmb *ocmb = PNV_OCMB(dev);
+ PnvOcmbClass *ocmbc = PNV_OCMB_GET_CLASS(ocmb);
+
+ assert(ocmb->chip);
+
+ /* ocmb region */
+ memory_region_init_io(&ocmb->regs, OBJECT(dev),
+ ocmbc->ocmb_ops, ocmb, "ocmb-main-memory",
+ ocmbc->ocmb_size);
+}
+
+static const Property pnv_ocmb_properties[] = {
+ DEFINE_PROP_LINK("chip", PnvOcmb, chip, TYPE_PNV_CHIP, PnvChip *),
+};
+
+static void pnv_ocmb_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = pnv_ocmb_realize;
+ dc->desc = "PowerNV OCMB Memory";
+ device_class_set_props(dc, pnv_ocmb_properties);
+ dc->user_creatable = false;
+}
+
+static const TypeInfo pnv_ocmb_type_info = {
+ .name = TYPE_PNV_OCMB,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(PnvOcmb),
+ .class_init = pnv_ocmb_class_init,
+ .class_size = sizeof(PnvOcmbClass),
+ .abstract = true,
+};
+
+static void pnv_ocmb_register_types(void)
+{
+ type_register_static(&pnv_ocmb_type_info);
+ type_register_static(&pnv_ocmb_power10_type_info);
+}
+
+type_init(pnv_ocmb_register_types);
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index cbdddfc73c..cf28f23843 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -240,6 +240,9 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
#define PNV10_XIVE2_NVC_SIZE 0x0000000008000000ull
#define PNV10_XIVE2_NVC_BASE(chip) PNV10_CHIP_BASE(chip, 0x0006030208000000ull)
+#define PNV10_OCMB_SIZE 0x0000001000000000ull
+#define PNV10_OCMB_BASE(chip) PNV10_CHIP_BASE(chip, 0x0006030400000000ull)
+
#define PNV10_XIVE2_NVPG_SIZE 0x0000010000000000ull
#define PNV10_XIVE2_NVPG_BASE(chip) PNV10_CHIP_BASE(chip, 0x0006040000000000ull)
diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index a5b8c49680..1d7077207a 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -7,6 +7,7 @@
#include "hw/ppc/pnv_core.h"
#include "hw/ppc/pnv_homer.h"
#include "hw/ppc/pnv_n1_chiplet.h"
+#include "hw/ppc/pnv_ocmb.h"
#include "hw/ssi/pnv_spi.h"
#include "hw/ppc/pnv_lpc.h"
#include "hw/ppc/pnv_occ.h"
@@ -124,6 +125,7 @@ struct Pnv10Chip {
PnvSBE sbe;
PnvHomer homer;
PnvN1Chiplet n1_chiplet;
+ PnvOcmb ocmb;
#define PNV10_CHIP_MAX_PIB_SPIC 6
PnvSpi pib_spic[PNV10_CHIP_MAX_PIB_SPIC];
diff --git a/include/hw/ppc/pnv_ocmb.h b/include/hw/ppc/pnv_ocmb.h
new file mode 100644
index 0000000000..c16ae4e477
--- /dev/null
+++ b/include/hw/ppc/pnv_ocmb.h
@@ -0,0 +1,38 @@
+/*
+ * QEMU PowerPC PowerNV Emulation of OCMB related registers
+ *
+ * Copyright (c) 2025, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ */
+
+#ifndef PPC_PNV_OCMB_H
+#define PPC_PNV_OCMB_H
+
+#include "hw/ppc/pnv.h"
+#include "qom/object.h"
+
+#define TYPE_PNV_OCMB "pnv-ocmb"
+OBJECT_DECLARE_TYPE(PnvOcmb, PnvOcmbClass,
+ PNV_OCMB)
+#define TYPE_PNV10_OCMB TYPE_PNV_OCMB "-POWER10"
+DECLARE_INSTANCE_CHECKER(PnvOcmb, PNV10_OCMB,
+ TYPE_PNV10_OCMB)
+
+struct PnvOcmb {
+ DeviceState parent;
+
+ PnvChip *chip;
+ MemoryRegion regs;
+};
+
+
+struct PnvOcmbClass {
+ DeviceClass parent_class;
+
+ uint64_t ocmb_size;
+ const MemoryRegionOps *ocmb_ops;
+};
+
+#endif /* PPC_PNV_OCMB_H */
--
2.47.3
On 24/12/25 19:52, Caleb Schlossin wrote: > The Power Hypervisor for P10 expects to be able to access certain > Open CAPI Memory Buffer (OCMB) chip registers. Since QEMU does not > currently support these registers, several access errors are being > posted. The hypervisor is able to progress despite these errors, > but it does create unwanted noise on the console. Adding some > dummy MMIO support for this IO region in order to suppress the > error messages. Hi Caleb, If there any public document/spec available that documents these registers ? Can you please point me to it. I don't find any 'ocmb' mention in any docs here: https://computeexpresslink.org/resource/opencapi-specification-archive/ Since a new TODO is getting introduced here to implement those register accesses, it can only be done if some public information is available. Thanks, - Aditya G > Signed-off-by: Glenn Miles <milesg@linux.ibm.com> > Signed-off-by: Caleb Schlossin <calebs@linux.ibm.com> > --- > hw/ppc/meson.build | 1 + > hw/ppc/pnv.c | 10 ++++ > hw/ppc/pnv_ocmb.c | 103 ++++++++++++++++++++++++++++++++++++++ > include/hw/ppc/pnv.h | 3 ++ > include/hw/ppc/pnv_chip.h | 2 + > include/hw/ppc/pnv_ocmb.h | 38 ++++++++++++++ > 6 files changed, 157 insertions(+) > create mode 100644 hw/ppc/pnv_ocmb.c > create mode 100644 include/hw/ppc/pnv_ocmb.h >
On 1/1/26 12:45 AM, Aditya Gupta wrote: > On 24/12/25 19:52, Caleb Schlossin wrote: > >> The Power Hypervisor for P10 expects to be able to access certain >> Open CAPI Memory Buffer (OCMB) chip registers. Since QEMU does not >> currently support these registers, several access errors are being >> posted. The hypervisor is able to progress despite these errors, >> but it does create unwanted noise on the console. Adding some >> dummy MMIO support for this IO region in order to suppress the >> error messages. > > Hi Caleb, > > If there any public document/spec available that documents these registers ? Can you please point me to it. > > I don't find any 'ocmb' mention in any docs here: https://computeexpresslink.org/resource/opencapi-specification-archive/ > > Since a new TODO is getting introduced here to implement those register accesses, it can only be done if some public information is available. > > > Thanks, > - Aditya G Aditya, I did some searching and couldn't seem to find the registers used in any of the public OpenCAPI documentation. I think the registers being accessed are Vendor-specific and likely not publicly defined. If that is a new requirement, we don't have to proceed with upstreaming of this patch and can keep it private. Thanks, Caleb > > >> Signed-off-by: Glenn Miles <milesg@linux.ibm.com> >> Signed-off-by: Caleb Schlossin <calebs@linux.ibm.com> >> --- >> hw/ppc/meson.build | 1 + >> hw/ppc/pnv.c | 10 ++++ >> hw/ppc/pnv_ocmb.c | 103 ++++++++++++++++++++++++++++++++++++++ >> include/hw/ppc/pnv.h | 3 ++ >> include/hw/ppc/pnv_chip.h | 2 + >> include/hw/ppc/pnv_ocmb.h | 38 ++++++++++++++ >> 6 files changed, 157 insertions(+) >> create mode 100644 hw/ppc/pnv_ocmb.c >> create mode 100644 include/hw/ppc/pnv_ocmb.h >>
On 02/01/26 21:31, Caleb Schlossin wrote: > > On 1/1/26 12:45 AM, Aditya Gupta wrote: >> On 24/12/25 19:52, Caleb Schlossin wrote: >> >>> The Power Hypervisor for P10 expects to be able to access certain >>> Open CAPI Memory Buffer (OCMB) chip registers. Since QEMU does not >>> currently support these registers, several access errors are being >>> posted. The hypervisor is able to progress despite these errors, >>> but it does create unwanted noise on the console. Adding some >>> dummy MMIO support for this IO region in order to suppress the >>> error messages. >> Hi Caleb, >> >> If there any public document/spec available that documents these registers ? Can you please point me to it. >> >> I don't find any 'ocmb' mention in any docs here: https://computeexpresslink.org/resource/opencapi-specification-archive/ >> >> Since a new TODO is getting introduced here to implement those register accesses, it can only be done if some public information is available. >> >> >> Thanks, >> - Aditya G > Aditya, > I did some searching and couldn't seem to find the registers used in any of the public OpenCAPI documentation. I think the registers being accessed are Vendor-specific and likely not publicly defined. If that is a new requirement, we don't have to proceed with upstreaming of this patch and can keep it private. Yes makes sense. Having TODOs which cannot be implemented, until information is made public, won't be good. Thanks for clarifying Caleb. - Aditya G > > Thanks, > Caleb > >> >>> Signed-off-by: Glenn Miles <milesg@linux.ibm.com> >>> Signed-off-by: Caleb Schlossin <calebs@linux.ibm.com> >>> --- >>> hw/ppc/meson.build | 1 + >>> hw/ppc/pnv.c | 10 ++++ >>> hw/ppc/pnv_ocmb.c | 103 ++++++++++++++++++++++++++++++++++++++ >>> include/hw/ppc/pnv.h | 3 ++ >>> include/hw/ppc/pnv_chip.h | 2 + >>> include/hw/ppc/pnv_ocmb.h | 38 ++++++++++++++ >>> 6 files changed, 157 insertions(+) >>> create mode 100644 hw/ppc/pnv_ocmb.c >>> create mode 100644 include/hw/ppc/pnv_ocmb.h >>>
© 2016 - 2026 Red Hat, Inc.