diff options
author | Chalapathi V <chalapathi.v@linux.ibm.com> | 2024-01-23 16:37:02 +1000 |
---|---|---|
committer | Nicholas Piggin <npiggin@gmail.com> | 2024-02-23 23:24:42 +1000 |
commit | 5706b0064d6a78c32bf46f18910bc4e10dde2687 (patch) | |
tree | 4a05fad717b2c03dcc41ef3289cee26e182e8d46 /hw | |
parent | 1adf24708bf7f8506fab6f2d53530af0210e6658 (diff) | |
download | qemu-5706b0064d6a78c32bf46f18910bc4e10dde2687.zip qemu-5706b0064d6a78c32bf46f18910bc4e10dde2687.tar.gz qemu-5706b0064d6a78c32bf46f18910bc4e10dde2687.tar.bz2 |
hw/ppc: Add N1 chiplet model
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
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Chalapathi V <chalapathi.v@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ppc/meson.build | 1 | ||||
-rw-r--r-- | hw/ppc/pnv_n1_chiplet.c | 173 |
2 files changed, 174 insertions, 0 deletions
diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index 960ff52..3717d74 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -54,6 +54,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/hw/ppc/pnv_n1_chiplet.c b/hw/ppc/pnv_n1_chiplet.c new file mode 100644 index 0000000..03ff9fb --- /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); |