1 /* 2 * QEMU PowerPC N1 chiplet model 3 * 4 * Copyright (c) 2023, IBM Corporation. 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9 #include "qemu/osdep.h" 10 #include "qemu/log.h" 11 #include "hw/qdev-properties.h" 12 #include "hw/ppc/pnv.h" 13 #include "hw/ppc/pnv_xscom.h" 14 #include "hw/ppc/pnv_n1_chiplet.h" 15 #include "hw/ppc/pnv_nest_pervasive.h" 16 17 /* 18 * The n1 chiplet contains chiplet control unit, 19 * PowerBus/RaceTrack/Bridge logic, nest Memory Management Unit(nMMU) 20 * and more. 21 * 22 * In this model Nest1 chiplet control registers are modelled via common 23 * nest pervasive model and few PowerBus racetrack registers are modelled. 24 */ 25 26 #define PB_SCOM_EQ0_HP_MODE2_CURR 0xe 27 #define PB_SCOM_ES3_MODE 0x8a 28 29 static uint64_t pnv_n1_chiplet_pb_scom_eq_read(void *opaque, hwaddr addr, 30 unsigned size) 31 { 32 PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); 33 uint32_t reg = addr >> 3; 34 uint64_t val = ~0ull; 35 36 switch (reg) { 37 case PB_SCOM_EQ0_HP_MODE2_CURR: 38 val = n1_chiplet->eq[0].hp_mode2_curr; 39 break; 40 default: 41 qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom read at 0x%" PRIx32 "\n", 42 __func__, reg); 43 } 44 return val; 45 } 46 47 static void pnv_n1_chiplet_pb_scom_eq_write(void *opaque, hwaddr addr, 48 uint64_t val, unsigned size) 49 { 50 PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); 51 uint32_t reg = addr >> 3; 52 53 switch (reg) { 54 case PB_SCOM_EQ0_HP_MODE2_CURR: 55 n1_chiplet->eq[0].hp_mode2_curr = val; 56 break; 57 default: 58 qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom write at 0x%" PRIx32 "\n", 59 __func__, reg); 60 } 61 } 62 63 static const MemoryRegionOps pnv_n1_chiplet_pb_scom_eq_ops = { 64 .read = pnv_n1_chiplet_pb_scom_eq_read, 65 .write = pnv_n1_chiplet_pb_scom_eq_write, 66 .valid.min_access_size = 8, 67 .valid.max_access_size = 8, 68 .impl.min_access_size = 8, 69 .impl.max_access_size = 8, 70 .endianness = DEVICE_BIG_ENDIAN, 71 }; 72 73 static uint64_t pnv_n1_chiplet_pb_scom_es_read(void *opaque, hwaddr addr, 74 unsigned size) 75 { 76 PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); 77 uint32_t reg = addr >> 3; 78 uint64_t val = ~0ull; 79 80 switch (reg) { 81 case PB_SCOM_ES3_MODE: 82 val = n1_chiplet->es[3].mode; 83 break; 84 default: 85 qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom read at 0x%" PRIx32 "\n", 86 __func__, reg); 87 } 88 return val; 89 } 90 91 static void pnv_n1_chiplet_pb_scom_es_write(void *opaque, hwaddr addr, 92 uint64_t val, unsigned size) 93 { 94 PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(opaque); 95 uint32_t reg = addr >> 3; 96 97 switch (reg) { 98 case PB_SCOM_ES3_MODE: 99 n1_chiplet->es[3].mode = val; 100 break; 101 default: 102 qemu_log_mask(LOG_UNIMP, "%s: Invalid xscom write at 0x%" PRIx32 "\n", 103 __func__, reg); 104 } 105 } 106 107 static const MemoryRegionOps pnv_n1_chiplet_pb_scom_es_ops = { 108 .read = pnv_n1_chiplet_pb_scom_es_read, 109 .write = pnv_n1_chiplet_pb_scom_es_write, 110 .valid.min_access_size = 8, 111 .valid.max_access_size = 8, 112 .impl.min_access_size = 8, 113 .impl.max_access_size = 8, 114 .endianness = DEVICE_BIG_ENDIAN, 115 }; 116 117 static void pnv_n1_chiplet_realize(DeviceState *dev, Error **errp) 118 { 119 PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(dev); 120 121 /* Realize nest pervasive common chiplet model */ 122 if (!qdev_realize(DEVICE(&n1_chiplet->nest_pervasive), NULL, errp)) { 123 return; 124 } 125 126 /* Nest1 chiplet power bus EQ xscom region */ 127 pnv_xscom_region_init(&n1_chiplet->xscom_pb_eq_mr, OBJECT(n1_chiplet), 128 &pnv_n1_chiplet_pb_scom_eq_ops, n1_chiplet, 129 "xscom-n1-chiplet-pb-scom-eq", 130 PNV10_XSCOM_N1_PB_SCOM_EQ_SIZE); 131 132 /* Nest1 chiplet power bus ES xscom region */ 133 pnv_xscom_region_init(&n1_chiplet->xscom_pb_es_mr, OBJECT(n1_chiplet), 134 &pnv_n1_chiplet_pb_scom_es_ops, n1_chiplet, 135 "xscom-n1-chiplet-pb-scom-es", 136 PNV10_XSCOM_N1_PB_SCOM_ES_SIZE); 137 } 138 139 static void pnv_n1_chiplet_class_init(ObjectClass *klass, void *data) 140 { 141 DeviceClass *dc = DEVICE_CLASS(klass); 142 143 dc->desc = "PowerNV n1 chiplet"; 144 dc->realize = pnv_n1_chiplet_realize; 145 } 146 147 static void pnv_n1_chiplet_instance_init(Object *obj) 148 { 149 PnvN1Chiplet *n1_chiplet = PNV_N1_CHIPLET(obj); 150 151 object_initialize_child(OBJECT(n1_chiplet), "nest-pervasive-common", 152 &n1_chiplet->nest_pervasive, 153 TYPE_PNV_NEST_CHIPLET_PERVASIVE); 154 } 155 156 static const TypeInfo pnv_n1_chiplet_info = { 157 .name = TYPE_PNV_N1_CHIPLET, 158 .parent = TYPE_DEVICE, 159 .instance_init = pnv_n1_chiplet_instance_init, 160 .instance_size = sizeof(PnvN1Chiplet), 161 .class_init = pnv_n1_chiplet_class_init, 162 .interfaces = (InterfaceInfo[]) { 163 { TYPE_PNV_XSCOM_INTERFACE }, 164 { } 165 } 166 }; 167 168 static void pnv_n1_chiplet_register_types(void) 169 { 170 type_register_static(&pnv_n1_chiplet_info); 171 } 172 173 type_init(pnv_n1_chiplet_register_types); 174