1 /* 2 * QEMU PowerPC PowerNV Emulation of a few HOMER related registers 3 * 4 * Copyright (c) 2019, IBM Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License, version 2, as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include "qemu/osdep.h" 20 #include "qemu/log.h" 21 #include "qapi/error.h" 22 #include "exec/hwaddr.h" 23 #include "exec/memory.h" 24 #include "sysemu/cpus.h" 25 #include "hw/qdev-core.h" 26 #include "hw/qdev-properties.h" 27 #include "hw/ppc/pnv.h" 28 #include "hw/ppc/pnv_homer.h" 29 #include "hw/ppc/pnv_xscom.h" 30 31 32 static bool core_max_array(PnvHomer *homer, hwaddr addr) 33 { 34 int i; 35 PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer); 36 37 for (i = 0; i <= homer->chip->nr_cores; i++) { 38 if (addr == (hmrc->core_max_base + i)) { 39 return true; 40 } 41 } 42 return false; 43 } 44 45 /* P8 Pstate table */ 46 47 #define PNV8_OCC_PSTATE_VERSION 0x1f8001 48 #define PNV8_OCC_PSTATE_MIN 0x1f8003 49 #define PNV8_OCC_PSTATE_VALID 0x1f8000 50 #define PNV8_OCC_PSTATE_THROTTLE 0x1f8002 51 #define PNV8_OCC_PSTATE_NOM 0x1f8004 52 #define PNV8_OCC_PSTATE_TURBO 0x1f8005 53 #define PNV8_OCC_PSTATE_ULTRA_TURBO 0x1f8006 54 #define PNV8_OCC_PSTATE_DATA 0x1f8008 55 #define PNV8_OCC_PSTATE_ID_ZERO 0x1f8010 56 #define PNV8_OCC_PSTATE_ID_ONE 0x1f8018 57 #define PNV8_OCC_PSTATE_ID_TWO 0x1f8020 58 #define PNV8_OCC_VDD_VOLTAGE_IDENTIFIER 0x1f8012 59 #define PNV8_OCC_VCS_VOLTAGE_IDENTIFIER 0x1f8013 60 #define PNV8_OCC_PSTATE_ZERO_FREQUENCY 0x1f8014 61 #define PNV8_OCC_PSTATE_ONE_FREQUENCY 0x1f801c 62 #define PNV8_OCC_PSTATE_TWO_FREQUENCY 0x1f8024 63 #define PNV8_CORE_MAX_BASE 0x1f8810 64 65 66 static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr, 67 unsigned size) 68 { 69 PnvHomer *homer = PNV_HOMER(opaque); 70 71 switch (addr) { 72 case PNV8_OCC_PSTATE_VERSION: 73 case PNV8_OCC_PSTATE_MIN: 74 case PNV8_OCC_PSTATE_ID_ZERO: 75 return 0; 76 case PNV8_OCC_PSTATE_VALID: 77 case PNV8_OCC_PSTATE_THROTTLE: 78 case PNV8_OCC_PSTATE_NOM: 79 case PNV8_OCC_PSTATE_TURBO: 80 case PNV8_OCC_PSTATE_ID_ONE: 81 case PNV8_OCC_VDD_VOLTAGE_IDENTIFIER: 82 case PNV8_OCC_VCS_VOLTAGE_IDENTIFIER: 83 return 1; 84 case PNV8_OCC_PSTATE_ULTRA_TURBO: 85 case PNV8_OCC_PSTATE_ID_TWO: 86 return 2; 87 case PNV8_OCC_PSTATE_DATA: 88 return 0x1000000000000000; 89 /* P8 frequency for 0, 1, and 2 pstates */ 90 case PNV8_OCC_PSTATE_ZERO_FREQUENCY: 91 case PNV8_OCC_PSTATE_ONE_FREQUENCY: 92 case PNV8_OCC_PSTATE_TWO_FREQUENCY: 93 return 3000; 94 } 95 /* pstate table core max array */ 96 if (core_max_array(homer, addr)) { 97 return 1; 98 } 99 return 0; 100 } 101 102 static void pnv_power8_homer_write(void *opaque, hwaddr addr, 103 uint64_t val, unsigned size) 104 { 105 /* callback function defined to homer write */ 106 return; 107 } 108 109 static const MemoryRegionOps pnv_power8_homer_ops = { 110 .read = pnv_power8_homer_read, 111 .write = pnv_power8_homer_write, 112 .valid.min_access_size = 1, 113 .valid.max_access_size = 8, 114 .impl.min_access_size = 1, 115 .impl.max_access_size = 8, 116 .endianness = DEVICE_BIG_ENDIAN, 117 }; 118 119 /* P8 PBA BARs */ 120 #define PBA_BAR0 0x00 121 #define PBA_BAR1 0x01 122 #define PBA_BAR2 0x02 123 #define PBA_BAR3 0x03 124 #define PBA_BARMASK0 0x04 125 #define PBA_BARMASK1 0x05 126 #define PBA_BARMASK2 0x06 127 #define PBA_BARMASK3 0x07 128 129 static uint64_t pnv_homer_power8_pba_read(void *opaque, hwaddr addr, 130 unsigned size) 131 { 132 PnvHomer *homer = PNV_HOMER(opaque); 133 PnvChip *chip = homer->chip; 134 uint32_t reg = addr >> 3; 135 uint64_t val = 0; 136 137 switch (reg) { 138 case PBA_BAR0: 139 val = PNV_HOMER_BASE(chip); 140 break; 141 case PBA_BARMASK0: /* P8 homer region mask */ 142 val = (PNV_HOMER_SIZE - 1) & 0x300000; 143 break; 144 case PBA_BAR3: /* P8 occ common area */ 145 val = PNV_OCC_COMMON_AREA_BASE; 146 break; 147 case PBA_BARMASK3: /* P8 occ common area mask */ 148 val = (PNV_OCC_COMMON_AREA_SIZE - 1) & 0x700000; 149 break; 150 default: 151 qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%" 152 HWADDR_PRIx "\n", addr >> 3); 153 } 154 return val; 155 } 156 157 static void pnv_homer_power8_pba_write(void *opaque, hwaddr addr, 158 uint64_t val, unsigned size) 159 { 160 qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%" 161 HWADDR_PRIx "\n", addr >> 3); 162 } 163 164 static const MemoryRegionOps pnv_homer_power8_pba_ops = { 165 .read = pnv_homer_power8_pba_read, 166 .write = pnv_homer_power8_pba_write, 167 .valid.min_access_size = 8, 168 .valid.max_access_size = 8, 169 .impl.min_access_size = 8, 170 .impl.max_access_size = 8, 171 .endianness = DEVICE_BIG_ENDIAN, 172 }; 173 174 static void pnv_homer_power8_class_init(ObjectClass *klass, void *data) 175 { 176 PnvHomerClass *homer = PNV_HOMER_CLASS(klass); 177 178 homer->pba_size = PNV_XSCOM_PBA_SIZE; 179 homer->pba_ops = &pnv_homer_power8_pba_ops; 180 homer->homer_size = PNV_HOMER_SIZE; 181 homer->homer_ops = &pnv_power8_homer_ops; 182 homer->core_max_base = PNV8_CORE_MAX_BASE; 183 } 184 185 static const TypeInfo pnv_homer_power8_type_info = { 186 .name = TYPE_PNV8_HOMER, 187 .parent = TYPE_PNV_HOMER, 188 .instance_size = sizeof(PnvHomer), 189 .class_init = pnv_homer_power8_class_init, 190 }; 191 192 /* P9 Pstate table */ 193 194 #define PNV9_OCC_PSTATE_ID_ZERO 0xe2018 195 #define PNV9_OCC_PSTATE_ID_ONE 0xe2020 196 #define PNV9_OCC_PSTATE_ID_TWO 0xe2028 197 #define PNV9_OCC_PSTATE_DATA 0xe2000 198 #define PNV9_OCC_PSTATE_DATA_AREA 0xe2008 199 #define PNV9_OCC_PSTATE_MIN 0xe2003 200 #define PNV9_OCC_PSTATE_NOM 0xe2004 201 #define PNV9_OCC_PSTATE_TURBO 0xe2005 202 #define PNV9_OCC_PSTATE_ULTRA_TURBO 0xe2818 203 #define PNV9_OCC_MAX_PSTATE_ULTRA_TURBO 0xe2006 204 #define PNV9_OCC_PSTATE_MAJOR_VERSION 0xe2001 205 #define PNV9_OCC_OPAL_RUNTIME_DATA 0xe2b85 206 #define PNV9_CHIP_HOMER_IMAGE_POINTER 0x200008 207 #define PNV9_CHIP_HOMER_BASE 0x0 208 #define PNV9_OCC_PSTATE_ZERO_FREQUENCY 0xe201c 209 #define PNV9_OCC_PSTATE_ONE_FREQUENCY 0xe2024 210 #define PNV9_OCC_PSTATE_TWO_FREQUENCY 0xe202c 211 #define PNV9_OCC_ROLE_MASTER_OR_SLAVE 0xe2002 212 #define PNV9_CORE_MAX_BASE 0xe2819 213 214 215 static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr, 216 unsigned size) 217 { 218 PnvHomer *homer = PNV_HOMER(opaque); 219 220 switch (addr) { 221 case PNV9_OCC_MAX_PSTATE_ULTRA_TURBO: 222 case PNV9_OCC_PSTATE_ID_ZERO: 223 return 0; 224 case PNV9_OCC_PSTATE_DATA: 225 case PNV9_OCC_ROLE_MASTER_OR_SLAVE: 226 case PNV9_OCC_PSTATE_NOM: 227 case PNV9_OCC_PSTATE_TURBO: 228 case PNV9_OCC_PSTATE_ID_ONE: 229 case PNV9_OCC_PSTATE_ULTRA_TURBO: 230 case PNV9_OCC_OPAL_RUNTIME_DATA: 231 return 1; 232 case PNV9_OCC_PSTATE_MIN: 233 case PNV9_OCC_PSTATE_ID_TWO: 234 return 2; 235 236 /* 3000 khz frequency for 0, 1, and 2 pstates */ 237 case PNV9_OCC_PSTATE_ZERO_FREQUENCY: 238 case PNV9_OCC_PSTATE_ONE_FREQUENCY: 239 case PNV9_OCC_PSTATE_TWO_FREQUENCY: 240 return 3000; 241 case PNV9_OCC_PSTATE_MAJOR_VERSION: 242 return 0x90; 243 case PNV9_CHIP_HOMER_BASE: 244 case PNV9_OCC_PSTATE_DATA_AREA: 245 case PNV9_CHIP_HOMER_IMAGE_POINTER: 246 return 0x1000000000000000; 247 } 248 /* pstate table core max array */ 249 if (core_max_array(homer, addr)) { 250 return 1; 251 } 252 return 0; 253 } 254 255 static void pnv_power9_homer_write(void *opaque, hwaddr addr, 256 uint64_t val, unsigned size) 257 { 258 /* callback function defined to homer write */ 259 return; 260 } 261 262 static const MemoryRegionOps pnv_power9_homer_ops = { 263 .read = pnv_power9_homer_read, 264 .write = pnv_power9_homer_write, 265 .valid.min_access_size = 1, 266 .valid.max_access_size = 8, 267 .impl.min_access_size = 1, 268 .impl.max_access_size = 8, 269 .endianness = DEVICE_BIG_ENDIAN, 270 }; 271 272 static uint64_t pnv_homer_power9_pba_read(void *opaque, hwaddr addr, 273 unsigned size) 274 { 275 PnvHomer *homer = PNV_HOMER(opaque); 276 PnvChip *chip = homer->chip; 277 uint32_t reg = addr >> 3; 278 uint64_t val = 0; 279 280 switch (reg) { 281 case PBA_BAR0: 282 val = PNV9_HOMER_BASE(chip); 283 break; 284 case PBA_BARMASK0: /* P9 homer region mask */ 285 val = (PNV9_HOMER_SIZE - 1) & 0x300000; 286 break; 287 case PBA_BAR2: /* P9 occ common area */ 288 val = PNV9_OCC_COMMON_AREA_BASE; 289 break; 290 case PBA_BARMASK2: /* P9 occ common area size */ 291 val = (PNV9_OCC_COMMON_AREA_SIZE - 1) & 0x700000; 292 break; 293 default: 294 qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%" 295 HWADDR_PRIx "\n", addr >> 3); 296 } 297 return val; 298 } 299 300 static void pnv_homer_power9_pba_write(void *opaque, hwaddr addr, 301 uint64_t val, unsigned size) 302 { 303 qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%" 304 HWADDR_PRIx "\n", addr >> 3); 305 } 306 307 static const MemoryRegionOps pnv_homer_power9_pba_ops = { 308 .read = pnv_homer_power9_pba_read, 309 .write = pnv_homer_power9_pba_write, 310 .valid.min_access_size = 8, 311 .valid.max_access_size = 8, 312 .impl.min_access_size = 8, 313 .impl.max_access_size = 8, 314 .endianness = DEVICE_BIG_ENDIAN, 315 }; 316 317 static void pnv_homer_power9_class_init(ObjectClass *klass, void *data) 318 { 319 PnvHomerClass *homer = PNV_HOMER_CLASS(klass); 320 321 homer->pba_size = PNV9_XSCOM_PBA_SIZE; 322 homer->pba_ops = &pnv_homer_power9_pba_ops; 323 homer->homer_size = PNV9_HOMER_SIZE; 324 homer->homer_ops = &pnv_power9_homer_ops; 325 homer->core_max_base = PNV9_CORE_MAX_BASE; 326 } 327 328 static const TypeInfo pnv_homer_power9_type_info = { 329 .name = TYPE_PNV9_HOMER, 330 .parent = TYPE_PNV_HOMER, 331 .instance_size = sizeof(PnvHomer), 332 .class_init = pnv_homer_power9_class_init, 333 }; 334 335 static void pnv_homer_realize(DeviceState *dev, Error **errp) 336 { 337 PnvHomer *homer = PNV_HOMER(dev); 338 PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer); 339 340 assert(homer->chip); 341 342 pnv_xscom_region_init(&homer->pba_regs, OBJECT(dev), hmrc->pba_ops, 343 homer, "xscom-pba", hmrc->pba_size); 344 345 /* homer region */ 346 memory_region_init_io(&homer->regs, OBJECT(dev), 347 hmrc->homer_ops, homer, "homer-main-memory", 348 hmrc->homer_size); 349 } 350 351 static Property pnv_homer_properties[] = { 352 DEFINE_PROP_LINK("chip", PnvHomer, chip, TYPE_PNV_CHIP, PnvChip *), 353 DEFINE_PROP_END_OF_LIST(), 354 }; 355 356 static void pnv_homer_class_init(ObjectClass *klass, void *data) 357 { 358 DeviceClass *dc = DEVICE_CLASS(klass); 359 360 dc->realize = pnv_homer_realize; 361 dc->desc = "PowerNV HOMER Memory"; 362 device_class_set_props(dc, pnv_homer_properties); 363 dc->user_creatable = false; 364 } 365 366 static const TypeInfo pnv_homer_type_info = { 367 .name = TYPE_PNV_HOMER, 368 .parent = TYPE_DEVICE, 369 .instance_size = sizeof(PnvHomer), 370 .class_init = pnv_homer_class_init, 371 .class_size = sizeof(PnvHomerClass), 372 .abstract = true, 373 }; 374 375 static void pnv_homer_register_types(void) 376 { 377 type_register_static(&pnv_homer_type_info); 378 type_register_static(&pnv_homer_power8_type_info); 379 type_register_static(&pnv_homer_power9_type_info); 380 } 381 382 type_init(pnv_homer_register_types); 383