Message ID | 20231207024331.5237-3-chalapathi.v@linux.ibm.com |
---|---|
State | Superseded |
Headers | show |
Series | pnv N1 chiplet model | expand |
On 12/7/23 03:43, Chalapathi V wrote: > The N1 chiplet handle the high speed i/o traffic over PCIe and others. > The N1 chiplet consists of PowerBus Fabric controller, > nest Memory Management Unit, chiplet control unit and more. > > This commit creates a N1 chiplet model and initialize and realize the > pervasive chiplet model where chiplet control registers are implemented. > > This commit also implement the read/write method for the powerbus scom > registers > > Signed-off-by: Chalapathi V <chalapathi.v@linux.ibm.com> Reviewed-by: Cédric Le Goater <clg@kaod.org> Thanks, C. > --- > include/hw/ppc/pnv_n1_chiplet.h | 33 ++++++ > include/hw/ppc/pnv_xscom.h | 6 ++ > hw/ppc/pnv_n1_chiplet.c | 173 ++++++++++++++++++++++++++++++++ > hw/ppc/meson.build | 1 + > 4 files changed, 213 insertions(+) > create mode 100644 include/hw/ppc/pnv_n1_chiplet.h > create mode 100644 hw/ppc/pnv_n1_chiplet.c > > diff --git a/include/hw/ppc/pnv_n1_chiplet.h b/include/hw/ppc/pnv_n1_chiplet.h > new file mode 100644 > index 0000000000..d5177bebce > --- /dev/null > +++ b/include/hw/ppc/pnv_n1_chiplet.h > @@ -0,0 +1,33 @@ > +/* > + * QEMU PowerPC N1 chiplet model > + * > + * Copyright (c) 2023, IBM Corporation. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#ifndef PPC_PNV_N1_CHIPLET_H > +#define PPC_PNV_N1_CHIPLET_H > + > +#include "hw/ppc/pnv_nest_pervasive.h" > + > +#define TYPE_PNV_N1_CHIPLET "pnv-N1-chiplet" > +#define PNV_N1_CHIPLET(obj) OBJECT_CHECK(PnvN1Chiplet, (obj), TYPE_PNV_N1_CHIPLET) > + > +typedef struct PnvPbScom { > + uint64_t mode; > + uint64_t hp_mode2_curr; > +} PnvPbScom; > + > +typedef struct PnvN1Chiplet { > + DeviceState parent; > + MemoryRegion xscom_pb_eq_mr; > + MemoryRegion xscom_pb_es_mr; > + /* common pervasive chiplet unit */ > + PnvNestChipletPervasive nest_pervasive; > +#define PB_SCOM_EQ_SIZE 8 > + PnvPbScom eq[PB_SCOM_EQ_SIZE]; > +#define PB_SCOM_ES_SIZE 4 > + PnvPbScom es[PB_SCOM_ES_SIZE]; I prefer public definitions to have a PNV_ prefix. With that, Reviewed-by: Cédric Le Goater <clg@redhat.com> Thanks, C. > +} PnvN1Chiplet; > +#endif /*PPC_PNV_N1_CHIPLET_H */ > diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h > index 3e15706dec..535ae1dab0 100644 > --- a/include/hw/ppc/pnv_xscom.h > +++ b/include/hw/ppc/pnv_xscom.h > @@ -173,6 +173,12 @@ struct PnvXScomInterfaceClass { > #define PNV10_XSCOM_N1_CHIPLET_CTRL_REGS_BASE 0x3000000 > #define PNV10_XSCOM_CHIPLET_CTRL_REGS_SIZE 0x400 > > +#define PNV10_XSCOM_N1_PB_SCOM_EQ_BASE 0x3011000 > +#define PNV10_XSCOM_N1_PB_SCOM_EQ_SIZE 0x200 > + > +#define PNV10_XSCOM_N1_PB_SCOM_ES_BASE 0x3011300 > +#define PNV10_XSCOM_N1_PB_SCOM_ES_SIZE 0x100 > + > #define PNV10_XSCOM_PEC_NEST_BASE 0x3011800 /* index goes downwards ... */ > #define PNV10_XSCOM_PEC_NEST_SIZE 0x100 > > diff --git a/hw/ppc/pnv_n1_chiplet.c b/hw/ppc/pnv_n1_chiplet.c > new file mode 100644 > index 0000000000..03ff9fbad0 > --- /dev/null > +++ b/hw/ppc/pnv_n1_chiplet.c > @@ -0,0 +1,173 @@ > +/* > + * QEMU PowerPC N1 chiplet model > + * > + * Copyright (c) 2023, IBM Corporation. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "qemu/osdep.h" > +#include "qemu/log.h" > +#include "hw/qdev-properties.h" > +#include "hw/ppc/pnv.h" > +#include "hw/ppc/pnv_xscom.h" > +#include "hw/ppc/pnv_n1_chiplet.h" > +#include "hw/ppc/pnv_nest_pervasive.h" > + > +/* > + * The n1 chiplet contains chiplet control unit, > + * PowerBus/RaceTrack/Bridge logic, nest Memory Management Unit(nMMU) > + * and more. > + * > + * In this model Nest1 chiplet control registers are modelled via common > + * nest pervasive model and few PowerBus racetrack registers are modelled. > + */ > + > +#define PB_SCOM_EQ0_HP_MODE2_CURR 0xe > +#define PB_SCOM_ES3_MODE 0x8a > + > +static uint64_t pnv_n1_chiplet_pb_scom_eq_read(void *opaque, hwaddr addr, > + unsigned size) > +{ > + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); > + uint32_t reg = addr >> 3; > + uint64_t val = ~0ull; > + > + switch (reg) { > + case PB_SCOM_EQ0_HP_MODE2_CURR: > + val = n1_chiplet->eq[0].hp_mode2_curr; > + break; > + default: > + qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom read at 0x%" PRIx32 "\n", > + __func__, reg); > + } > + return val; > +} > + > +static void pnv_n1_chiplet_pb_scom_eq_write(void *opaque, hwaddr addr, > + uint64_t val, unsigned size) > +{ > + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); > + uint32_t reg = addr >> 3; > + > + switch (reg) { > + case PB_SCOM_EQ0_HP_MODE2_CURR: > + n1_chiplet->eq[0].hp_mode2_curr = val; > + break; > + default: > + qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom write at 0x%" PRIx32 "\n", > + __func__, reg); > + } > +} > + > +static const MemoryRegionOps pnv_n1_chiplet_pb_scom_eq_ops = { > + .read = pnv_n1_chiplet_pb_scom_eq_read, > + .write = pnv_n1_chiplet_pb_scom_eq_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 uint64_t pnv_n1_chiplet_pb_scom_es_read(void *opaque, hwaddr addr, > + unsigned size) > +{ > + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); > + uint32_t reg = addr >> 3; > + uint64_t val = ~0ull; > + > + switch (reg) { > + case PB_SCOM_ES3_MODE: > + val = n1_chiplet->es[3].mode; > + break; > + default: > + qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom read at 0x%" PRIx32 "\n", > + __func__, reg); > + } > + return val; > +} > + > +static void pnv_n1_chiplet_pb_scom_es_write(void *opaque, hwaddr addr, > + uint64_t val, unsigned size) > +{ > + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); > + uint32_t reg = addr >> 3; > + > + switch (reg) { > + case PB_SCOM_ES3_MODE: > + n1_chiplet->es[3].mode = val; > + break; > + default: > + qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom write at 0x%" PRIx32 "\n", > + __func__, reg); > + } > +} > + > +static const MemoryRegionOps pnv_n1_chiplet_pb_scom_es_ops = { > + .read = pnv_n1_chiplet_pb_scom_es_read, > + .write = pnv_n1_chiplet_pb_scom_es_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_n1_chiplet_realize(DeviceState *dev, Error **errp) > +{ > + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(dev); > + > + /* Realize nest pervasive common chiplet model */ > + if (!qdev_realize(DEVICE(&n1_chiplet->nest_pervasive), NULL, errp)) { > + return; > + } > + > + /* Nest1 chiplet power bus EQ xscom region */ > + pnv_xscom_region_init(&n1_chiplet->xscom_pb_eq_mr, OBJECT(n1_chiplet), > + &pnv_n1_chiplet_pb_scom_eq_ops, n1_chiplet, > + "xscom-n1-chiplet-pb-scom-eq", > + PNV10_XSCOM_N1_PB_SCOM_EQ_SIZE); > + > + /* Nest1 chiplet power bus ES xscom region */ > + pnv_xscom_region_init(&n1_chiplet->xscom_pb_es_mr, OBJECT(n1_chiplet), > + &pnv_n1_chiplet_pb_scom_es_ops, n1_chiplet, > + "xscom-n1-chiplet-pb-scom-es", > + PNV10_XSCOM_N1_PB_SCOM_ES_SIZE); > +} > + > +static void pnv_n1_chiplet_class_init(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + > + dc->desc = "PowerNV n1 chiplet"; > + dc->realize = pnv_n1_chiplet_realize; > +} > + > +static void pnv_n1_chiplet_instance_init(Object *obj) > +{ > + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(obj); > + > + object_initialize_child(OBJECT(n1_chiplet), "nest-pervasive-common", > + &n1_chiplet->nest_pervasive, > + TYPE_PNV_NEST_CHIPLET_PERVASIVE); > +} > + > +static const TypeInfo pnv_n1_chiplet_info = { > + .name = TYPE_PNV_N1_CHIPLET, > + .parent = TYPE_DEVICE, > + .instance_init = pnv_n1_chiplet_instance_init, > + .instance_size = sizeof(PnvN1Chiplet), > + .class_init = pnv_n1_chiplet_class_init, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PNV_XSCOM_INTERFACE }, > + { } > + } > +}; > + > +static void pnv_n1_chiplet_register_types(void) > +{ > + type_register_static(&pnv_n1_chiplet_info); > +} > + > +type_init(pnv_n1_chiplet_register_types); > diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build > index d6f6f94fcc..256e453c0c 100644 > --- a/hw/ppc/meson.build > +++ b/hw/ppc/meson.build > @@ -52,6 +52,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files( > 'pnv_homer.c', > 'pnv_pnor.c', > 'pnv_nest_pervasive.c', > + 'pnv_n1_chiplet.c', > )) > # PowerPC 4xx boards > ppc_ss.add(when: 'CONFIG_PPC405', if_true: files(
diff --git a/include/hw/ppc/pnv_n1_chiplet.h b/include/hw/ppc/pnv_n1_chiplet.h new file mode 100644 index 0000000000..d5177bebce --- /dev/null +++ b/include/hw/ppc/pnv_n1_chiplet.h @@ -0,0 +1,33 @@ +/* + * QEMU PowerPC N1 chiplet model + * + * Copyright (c) 2023, IBM Corporation. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef PPC_PNV_N1_CHIPLET_H +#define PPC_PNV_N1_CHIPLET_H + +#include "hw/ppc/pnv_nest_pervasive.h" + +#define TYPE_PNV_N1_CHIPLET "pnv-N1-chiplet" +#define PNV_N1_CHIPLET(obj) OBJECT_CHECK(PnvN1Chiplet, (obj), TYPE_PNV_N1_CHIPLET) + +typedef struct PnvPbScom { + uint64_t mode; + uint64_t hp_mode2_curr; +} PnvPbScom; + +typedef struct PnvN1Chiplet { + DeviceState parent; + MemoryRegion xscom_pb_eq_mr; + MemoryRegion xscom_pb_es_mr; + /* common pervasive chiplet unit */ + PnvNestChipletPervasive nest_pervasive; +#define PB_SCOM_EQ_SIZE 8 + PnvPbScom eq[PB_SCOM_EQ_SIZE]; +#define PB_SCOM_ES_SIZE 4 + PnvPbScom es[PB_SCOM_ES_SIZE]; +} PnvN1Chiplet; +#endif /*PPC_PNV_N1_CHIPLET_H */ diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h index 3e15706dec..535ae1dab0 100644 --- a/include/hw/ppc/pnv_xscom.h +++ b/include/hw/ppc/pnv_xscom.h @@ -173,6 +173,12 @@ struct PnvXScomInterfaceClass { #define PNV10_XSCOM_N1_CHIPLET_CTRL_REGS_BASE 0x3000000 #define PNV10_XSCOM_CHIPLET_CTRL_REGS_SIZE 0x400 +#define PNV10_XSCOM_N1_PB_SCOM_EQ_BASE 0x3011000 +#define PNV10_XSCOM_N1_PB_SCOM_EQ_SIZE 0x200 + +#define PNV10_XSCOM_N1_PB_SCOM_ES_BASE 0x3011300 +#define PNV10_XSCOM_N1_PB_SCOM_ES_SIZE 0x100 + #define PNV10_XSCOM_PEC_NEST_BASE 0x3011800 /* index goes downwards ... */ #define PNV10_XSCOM_PEC_NEST_SIZE 0x100 diff --git a/hw/ppc/pnv_n1_chiplet.c b/hw/ppc/pnv_n1_chiplet.c new file mode 100644 index 0000000000..03ff9fbad0 --- /dev/null +++ b/hw/ppc/pnv_n1_chiplet.c @@ -0,0 +1,173 @@ +/* + * QEMU PowerPC N1 chiplet model + * + * Copyright (c) 2023, IBM Corporation. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/qdev-properties.h" +#include "hw/ppc/pnv.h" +#include "hw/ppc/pnv_xscom.h" +#include "hw/ppc/pnv_n1_chiplet.h" +#include "hw/ppc/pnv_nest_pervasive.h" + +/* + * The n1 chiplet contains chiplet control unit, + * PowerBus/RaceTrack/Bridge logic, nest Memory Management Unit(nMMU) + * and more. + * + * In this model Nest1 chiplet control registers are modelled via common + * nest pervasive model and few PowerBus racetrack registers are modelled. + */ + +#define PB_SCOM_EQ0_HP_MODE2_CURR 0xe +#define PB_SCOM_ES3_MODE 0x8a + +static uint64_t pnv_n1_chiplet_pb_scom_eq_read(void *opaque, hwaddr addr, + unsigned size) +{ + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); + uint32_t reg = addr >> 3; + uint64_t val = ~0ull; + + switch (reg) { + case PB_SCOM_EQ0_HP_MODE2_CURR: + val = n1_chiplet->eq[0].hp_mode2_curr; + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom read at 0x%" PRIx32 "\n", + __func__, reg); + } + return val; +} + +static void pnv_n1_chiplet_pb_scom_eq_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); + uint32_t reg = addr >> 3; + + switch (reg) { + case PB_SCOM_EQ0_HP_MODE2_CURR: + n1_chiplet->eq[0].hp_mode2_curr = val; + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom write at 0x%" PRIx32 "\n", + __func__, reg); + } +} + +static const MemoryRegionOps pnv_n1_chiplet_pb_scom_eq_ops = { + .read = pnv_n1_chiplet_pb_scom_eq_read, + .write = pnv_n1_chiplet_pb_scom_eq_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 uint64_t pnv_n1_chiplet_pb_scom_es_read(void *opaque, hwaddr addr, + unsigned size) +{ + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); + uint32_t reg = addr >> 3; + uint64_t val = ~0ull; + + switch (reg) { + case PB_SCOM_ES3_MODE: + val = n1_chiplet->es[3].mode; + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom read at 0x%" PRIx32 "\n", + __func__, reg); + } + return val; +} + +static void pnv_n1_chiplet_pb_scom_es_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); + uint32_t reg = addr >> 3; + + switch (reg) { + case PB_SCOM_ES3_MODE: + n1_chiplet->es[3].mode = val; + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom write at 0x%" PRIx32 "\n", + __func__, reg); + } +} + +static const MemoryRegionOps pnv_n1_chiplet_pb_scom_es_ops = { + .read = pnv_n1_chiplet_pb_scom_es_read, + .write = pnv_n1_chiplet_pb_scom_es_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_n1_chiplet_realize(DeviceState *dev, Error **errp) +{ + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(dev); + + /* Realize nest pervasive common chiplet model */ + if (!qdev_realize(DEVICE(&n1_chiplet->nest_pervasive), NULL, errp)) { + return; + } + + /* Nest1 chiplet power bus EQ xscom region */ + pnv_xscom_region_init(&n1_chiplet->xscom_pb_eq_mr, OBJECT(n1_chiplet), + &pnv_n1_chiplet_pb_scom_eq_ops, n1_chiplet, + "xscom-n1-chiplet-pb-scom-eq", + PNV10_XSCOM_N1_PB_SCOM_EQ_SIZE); + + /* Nest1 chiplet power bus ES xscom region */ + pnv_xscom_region_init(&n1_chiplet->xscom_pb_es_mr, OBJECT(n1_chiplet), + &pnv_n1_chiplet_pb_scom_es_ops, n1_chiplet, + "xscom-n1-chiplet-pb-scom-es", + PNV10_XSCOM_N1_PB_SCOM_ES_SIZE); +} + +static void pnv_n1_chiplet_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->desc = "PowerNV n1 chiplet"; + dc->realize = pnv_n1_chiplet_realize; +} + +static void pnv_n1_chiplet_instance_init(Object *obj) +{ + PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(obj); + + object_initialize_child(OBJECT(n1_chiplet), "nest-pervasive-common", + &n1_chiplet->nest_pervasive, + TYPE_PNV_NEST_CHIPLET_PERVASIVE); +} + +static const TypeInfo pnv_n1_chiplet_info = { + .name = TYPE_PNV_N1_CHIPLET, + .parent = TYPE_DEVICE, + .instance_init = pnv_n1_chiplet_instance_init, + .instance_size = sizeof(PnvN1Chiplet), + .class_init = pnv_n1_chiplet_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_PNV_XSCOM_INTERFACE }, + { } + } +}; + +static void pnv_n1_chiplet_register_types(void) +{ + type_register_static(&pnv_n1_chiplet_info); +} + +type_init(pnv_n1_chiplet_register_types); diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index d6f6f94fcc..256e453c0c 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -52,6 +52,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files( 'pnv_homer.c', 'pnv_pnor.c', 'pnv_nest_pervasive.c', + 'pnv_n1_chiplet.c', )) # PowerPC 4xx boards ppc_ss.add(when: 'CONFIG_PPC405', if_true: files(
The N1 chiplet handle the high speed i/o traffic over PCIe and others. The N1 chiplet consists of PowerBus Fabric controller, nest Memory Management Unit, chiplet control unit and more. This commit creates a N1 chiplet model and initialize and realize the pervasive chiplet model where chiplet control registers are implemented. This commit also implement the read/write method for the powerbus scom registers Signed-off-by: Chalapathi V <chalapathi.v@linux.ibm.com> --- include/hw/ppc/pnv_n1_chiplet.h | 33 ++++++ include/hw/ppc/pnv_xscom.h | 6 ++ hw/ppc/pnv_n1_chiplet.c | 173 ++++++++++++++++++++++++++++++++ hw/ppc/meson.build | 1 + 4 files changed, 213 insertions(+) create mode 100644 include/hw/ppc/pnv_n1_chiplet.h create mode 100644 hw/ppc/pnv_n1_chiplet.c