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 "system/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_chip.h" 29 #include "hw/ppc/pnv_homer.h" 30 #include "hw/ppc/pnv_xscom.h" 31 32 33 static bool core_max_array(PnvHomer *homer, hwaddr addr) 34 { 35 int i; 36 PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer); 37 38 for (i = 0; i <= homer->chip->nr_cores; i++) { 39 if (addr == (hmrc->core_max_base + i)) { 40 return true; 41 } 42 } 43 return false; 44 } 45 46 /* P8 Pstate table */ 47 48 #define PNV8_OCC_PSTATE_VERSION 0x1f8001 49 #define PNV8_OCC_PSTATE_MIN 0x1f8003 50 #define PNV8_OCC_PSTATE_VALID 0x1f8000 51 #define PNV8_OCC_PSTATE_THROTTLE 0x1f8002 52 #define PNV8_OCC_PSTATE_NOM 0x1f8004 53 #define PNV8_OCC_PSTATE_TURBO 0x1f8005 54 #define PNV8_OCC_PSTATE_ULTRA_TURBO 0x1f8006 55 #define PNV8_OCC_PSTATE_DATA 0x1f8008 56 #define PNV8_OCC_PSTATE_ID_ZERO 0x1f8010 57 #define PNV8_OCC_PSTATE_ID_ONE 0x1f8018 58 #define PNV8_OCC_PSTATE_ID_TWO 0x1f8020 59 #define PNV8_OCC_VDD_VOLTAGE_IDENTIFIER 0x1f8012 60 #define PNV8_OCC_VCS_VOLTAGE_IDENTIFIER 0x1f8013 61 #define PNV8_OCC_PSTATE_ZERO_FREQUENCY 0x1f8014 62 #define PNV8_OCC_PSTATE_ONE_FREQUENCY 0x1f801c 63 #define PNV8_OCC_PSTATE_TWO_FREQUENCY 0x1f8024 64 #define PNV8_CORE_MAX_BASE 0x1f8810 65 66 67 static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr, 68 unsigned size) 69 { 70 PnvHomer *homer = PNV_HOMER(opaque); 71 72 switch (addr) { 73 case PNV8_OCC_PSTATE_VALID: 74 return 1; 75 case PNV8_OCC_PSTATE_THROTTLE: 76 return 0; 77 case PNV8_OCC_PSTATE_VERSION: 78 return 0x02; 79 case PNV8_OCC_PSTATE_MIN: 80 return -2; 81 case PNV8_OCC_PSTATE_NOM: 82 case PNV8_OCC_PSTATE_TURBO: 83 return -1; 84 case PNV8_OCC_PSTATE_ULTRA_TURBO: 85 return 0; 86 case PNV8_OCC_PSTATE_ID_ZERO: 87 return 0; 88 case PNV8_OCC_VDD_VOLTAGE_IDENTIFIER: 89 case PNV8_OCC_VCS_VOLTAGE_IDENTIFIER: 90 return 1; 91 case PNV8_OCC_PSTATE_DATA: 92 return 0; 93 /* P8 frequency for 0, 1, and 2 pstates */ 94 case PNV8_OCC_PSTATE_ZERO_FREQUENCY: 95 case PNV8_OCC_PSTATE_ONE_FREQUENCY: 96 case PNV8_OCC_PSTATE_TWO_FREQUENCY: 97 return 3000; 98 case PNV8_OCC_PSTATE_ID_ONE: 99 return -1; 100 case PNV8_OCC_PSTATE_ID_TWO: 101 return -2; 102 } 103 /* pstate table core max array */ 104 if (core_max_array(homer, addr)) { 105 return 1; 106 } 107 return 0; 108 } 109 110 static void pnv_power8_homer_write(void *opaque, hwaddr addr, 111 uint64_t val, unsigned size) 112 { 113 /* callback function defined to homer write */ 114 return; 115 } 116 117 static const MemoryRegionOps pnv_power8_homer_ops = { 118 .read = pnv_power8_homer_read, 119 .write = pnv_power8_homer_write, 120 .valid.min_access_size = 1, 121 .valid.max_access_size = 8, 122 .impl.min_access_size = 1, 123 .impl.max_access_size = 8, 124 .endianness = DEVICE_BIG_ENDIAN, 125 }; 126 127 /* P8 PBA BARs */ 128 #define PBA_BAR0 0x00 129 #define PBA_BAR1 0x01 130 #define PBA_BAR2 0x02 131 #define PBA_BAR3 0x03 132 #define PBA_BARMASK0 0x04 133 #define PBA_BARMASK1 0x05 134 #define PBA_BARMASK2 0x06 135 #define PBA_BARMASK3 0x07 136 137 static uint64_t pnv_homer_power8_pba_read(void *opaque, hwaddr addr, 138 unsigned size) 139 { 140 PnvHomer *homer = PNV_HOMER(opaque); 141 PnvChip *chip = homer->chip; 142 uint32_t reg = addr >> 3; 143 uint64_t val = 0; 144 145 switch (reg) { 146 case PBA_BAR0: 147 val = PNV_HOMER_BASE(chip); 148 break; 149 case PBA_BARMASK0: /* P8 homer region mask */ 150 val = (PNV_HOMER_SIZE - 1) & 0x300000; 151 break; 152 case PBA_BAR3: /* P8 occ common area */ 153 val = PNV_OCC_COMMON_AREA_BASE; 154 break; 155 case PBA_BARMASK3: /* P8 occ common area mask */ 156 val = (PNV_OCC_COMMON_AREA_SIZE - 1) & 0x700000; 157 break; 158 default: 159 qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%" 160 HWADDR_PRIx "\n", addr >> 3); 161 } 162 return val; 163 } 164 165 static void pnv_homer_power8_pba_write(void *opaque, hwaddr addr, 166 uint64_t val, unsigned size) 167 { 168 qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%" 169 HWADDR_PRIx "\n", addr >> 3); 170 } 171 172 static const MemoryRegionOps pnv_homer_power8_pba_ops = { 173 .read = pnv_homer_power8_pba_read, 174 .write = pnv_homer_power8_pba_write, 175 .valid.min_access_size = 8, 176 .valid.max_access_size = 8, 177 .impl.min_access_size = 8, 178 .impl.max_access_size = 8, 179 .endianness = DEVICE_BIG_ENDIAN, 180 }; 181 182 static void pnv_homer_power8_class_init(ObjectClass *klass, void *data) 183 { 184 PnvHomerClass *homer = PNV_HOMER_CLASS(klass); 185 186 homer->pba_size = PNV_XSCOM_PBA_SIZE; 187 homer->pba_ops = &pnv_homer_power8_pba_ops; 188 homer->homer_size = PNV_HOMER_SIZE; 189 homer->homer_ops = &pnv_power8_homer_ops; 190 homer->core_max_base = PNV8_CORE_MAX_BASE; 191 } 192 193 static const TypeInfo pnv_homer_power8_type_info = { 194 .name = TYPE_PNV8_HOMER, 195 .parent = TYPE_PNV_HOMER, 196 .instance_size = sizeof(PnvHomer), 197 .class_init = pnv_homer_power8_class_init, 198 }; 199 200 /* P9 Pstate table */ 201 202 #define PNV9_OCC_PSTATE_VALID 0xe2000 203 #define PNV9_OCC_PSTATE_ID_ZERO 0xe2018 204 #define PNV9_OCC_PSTATE_ID_ONE 0xe2020 205 #define PNV9_OCC_PSTATE_ID_TWO 0xe2028 206 #define PNV9_OCC_PSTATE_DATA 0xe2000 207 #define PNV9_OCC_PSTATE_MINOR_VERSION 0xe2008 208 #define PNV9_OCC_PSTATE_MIN 0xe2003 209 #define PNV9_OCC_PSTATE_NOM 0xe2004 210 #define PNV9_OCC_PSTATE_TURBO 0xe2005 211 #define PNV9_OCC_PSTATE_ULTRA_TURBO 0xe2818 212 #define PNV9_OCC_MAX_PSTATE_ULTRA_TURBO 0xe2006 213 #define PNV9_OCC_PSTATE_MAJOR_VERSION 0xe2001 214 #define PNV9_OCC_OPAL_RUNTIME_DATA 0xe2b85 215 #define PNV9_CHIP_HOMER_IMAGE_POINTER 0x200008 216 #define PNV9_CHIP_HOMER_BASE 0x0 217 #define PNV9_OCC_PSTATE_ZERO_FREQUENCY 0xe201c 218 #define PNV9_OCC_PSTATE_ONE_FREQUENCY 0xe2024 219 #define PNV9_OCC_PSTATE_TWO_FREQUENCY 0xe202c 220 #define PNV9_OCC_ROLE_MASTER_OR_SLAVE 0xe2002 221 #define PNV9_CORE_MAX_BASE 0xe2819 222 #define PNV9_DYNAMIC_DATA_STATE 0xe2b80 223 224 static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr, 225 unsigned size) 226 { 227 PnvHomer *homer = PNV_HOMER(opaque); 228 229 switch (addr) { 230 case PNV9_OCC_PSTATE_VALID: 231 return 1; 232 case PNV9_OCC_MAX_PSTATE_ULTRA_TURBO: 233 case PNV9_OCC_PSTATE_ID_ZERO: 234 return 0; 235 case PNV9_OCC_ROLE_MASTER_OR_SLAVE: 236 if (homer->chip->chip_id == 0) { 237 return 0x1; /* master */ 238 } else { 239 return 0x0; /* slave */ 240 } 241 case PNV9_OCC_PSTATE_NOM: 242 case PNV9_OCC_PSTATE_TURBO: 243 case PNV9_OCC_PSTATE_ID_ONE: 244 case PNV9_OCC_PSTATE_ULTRA_TURBO: 245 case PNV9_OCC_OPAL_RUNTIME_DATA: 246 return 1; 247 case PNV9_OCC_PSTATE_MIN: 248 case PNV9_OCC_PSTATE_ID_TWO: 249 return 2; 250 251 /* 3000 khz frequency for 0, 1, and 2 pstates */ 252 case PNV9_OCC_PSTATE_ZERO_FREQUENCY: 253 case PNV9_OCC_PSTATE_ONE_FREQUENCY: 254 case PNV9_OCC_PSTATE_TWO_FREQUENCY: 255 return 3000; 256 case PNV9_OCC_PSTATE_MAJOR_VERSION: 257 return 0x90; 258 case PNV9_OCC_PSTATE_MINOR_VERSION: 259 return 0x01; 260 case PNV9_CHIP_HOMER_BASE: 261 case PNV9_CHIP_HOMER_IMAGE_POINTER: 262 return 0; 263 case PNV9_DYNAMIC_DATA_STATE: 264 return 0x03; /* active */ 265 } 266 /* pstate table core max array */ 267 if (core_max_array(homer, addr)) { 268 return 1; 269 } 270 return 0; 271 } 272 273 static void pnv_power9_homer_write(void *opaque, hwaddr addr, 274 uint64_t val, unsigned size) 275 { 276 /* callback function defined to homer write */ 277 return; 278 } 279 280 static const MemoryRegionOps pnv_power9_homer_ops = { 281 .read = pnv_power9_homer_read, 282 .write = pnv_power9_homer_write, 283 .valid.min_access_size = 1, 284 .valid.max_access_size = 8, 285 .impl.min_access_size = 1, 286 .impl.max_access_size = 8, 287 .endianness = DEVICE_BIG_ENDIAN, 288 }; 289 290 static uint64_t pnv_homer_power9_pba_read(void *opaque, hwaddr addr, 291 unsigned size) 292 { 293 PnvHomer *homer = PNV_HOMER(opaque); 294 PnvChip *chip = homer->chip; 295 uint32_t reg = addr >> 3; 296 uint64_t val = 0; 297 298 switch (reg) { 299 case PBA_BAR0: 300 val = PNV9_HOMER_BASE(chip); 301 break; 302 case PBA_BARMASK0: /* P9 homer region mask */ 303 val = (PNV9_HOMER_SIZE - 1) & 0x300000; 304 break; 305 case PBA_BAR2: /* P9 occ common area */ 306 val = PNV9_OCC_COMMON_AREA_BASE; 307 break; 308 case PBA_BARMASK2: /* P9 occ common area size */ 309 val = (PNV9_OCC_COMMON_AREA_SIZE - 1) & 0x700000; 310 break; 311 default: 312 qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%" 313 HWADDR_PRIx "\n", addr >> 3); 314 } 315 return val; 316 } 317 318 static void pnv_homer_power9_pba_write(void *opaque, hwaddr addr, 319 uint64_t val, unsigned size) 320 { 321 qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%" 322 HWADDR_PRIx "\n", addr >> 3); 323 } 324 325 static const MemoryRegionOps pnv_homer_power9_pba_ops = { 326 .read = pnv_homer_power9_pba_read, 327 .write = pnv_homer_power9_pba_write, 328 .valid.min_access_size = 8, 329 .valid.max_access_size = 8, 330 .impl.min_access_size = 8, 331 .impl.max_access_size = 8, 332 .endianness = DEVICE_BIG_ENDIAN, 333 }; 334 335 static void pnv_homer_power9_class_init(ObjectClass *klass, void *data) 336 { 337 PnvHomerClass *homer = PNV_HOMER_CLASS(klass); 338 339 homer->pba_size = PNV9_XSCOM_PBA_SIZE; 340 homer->pba_ops = &pnv_homer_power9_pba_ops; 341 homer->homer_size = PNV9_HOMER_SIZE; 342 homer->homer_ops = &pnv_power9_homer_ops; 343 homer->core_max_base = PNV9_CORE_MAX_BASE; 344 } 345 346 static const TypeInfo pnv_homer_power9_type_info = { 347 .name = TYPE_PNV9_HOMER, 348 .parent = TYPE_PNV_HOMER, 349 .instance_size = sizeof(PnvHomer), 350 .class_init = pnv_homer_power9_class_init, 351 }; 352 353 static uint64_t pnv_homer_power10_pba_read(void *opaque, hwaddr addr, 354 unsigned size) 355 { 356 PnvHomer *homer = PNV_HOMER(opaque); 357 PnvChip *chip = homer->chip; 358 uint32_t reg = addr >> 3; 359 uint64_t val = 0; 360 361 switch (reg) { 362 case PBA_BAR0: 363 val = PNV10_HOMER_BASE(chip); 364 break; 365 case PBA_BARMASK0: /* P10 homer region mask */ 366 val = (PNV10_HOMER_SIZE - 1) & 0x300000; 367 break; 368 case PBA_BAR2: /* P10 occ common area */ 369 val = PNV10_OCC_COMMON_AREA_BASE; 370 break; 371 case PBA_BARMASK2: /* P10 occ common area size */ 372 val = (PNV10_OCC_COMMON_AREA_SIZE - 1) & 0x700000; 373 break; 374 default: 375 qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%" 376 HWADDR_PRIx "\n", addr >> 3); 377 } 378 return val; 379 } 380 381 static void pnv_homer_power10_pba_write(void *opaque, hwaddr addr, 382 uint64_t val, unsigned size) 383 { 384 qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%" 385 HWADDR_PRIx "\n", addr >> 3); 386 } 387 388 static const MemoryRegionOps pnv_homer_power10_pba_ops = { 389 .read = pnv_homer_power10_pba_read, 390 .write = pnv_homer_power10_pba_write, 391 .valid.min_access_size = 8, 392 .valid.max_access_size = 8, 393 .impl.min_access_size = 8, 394 .impl.max_access_size = 8, 395 .endianness = DEVICE_BIG_ENDIAN, 396 }; 397 398 static void pnv_homer_power10_class_init(ObjectClass *klass, void *data) 399 { 400 PnvHomerClass *homer = PNV_HOMER_CLASS(klass); 401 402 homer->pba_size = PNV10_XSCOM_PBA_SIZE; 403 homer->pba_ops = &pnv_homer_power10_pba_ops; 404 homer->homer_size = PNV10_HOMER_SIZE; 405 homer->homer_ops = &pnv_power9_homer_ops; /* TODO */ 406 homer->core_max_base = PNV9_CORE_MAX_BASE; 407 } 408 409 static const TypeInfo pnv_homer_power10_type_info = { 410 .name = TYPE_PNV10_HOMER, 411 .parent = TYPE_PNV_HOMER, 412 .instance_size = sizeof(PnvHomer), 413 .class_init = pnv_homer_power10_class_init, 414 }; 415 416 static void pnv_homer_realize(DeviceState *dev, Error **errp) 417 { 418 PnvHomer *homer = PNV_HOMER(dev); 419 PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer); 420 421 assert(homer->chip); 422 423 pnv_xscom_region_init(&homer->pba_regs, OBJECT(dev), hmrc->pba_ops, 424 homer, "xscom-pba", hmrc->pba_size); 425 426 /* homer region */ 427 memory_region_init_io(&homer->regs, OBJECT(dev), 428 hmrc->homer_ops, homer, "homer-main-memory", 429 hmrc->homer_size); 430 } 431 432 static const Property pnv_homer_properties[] = { 433 DEFINE_PROP_LINK("chip", PnvHomer, chip, TYPE_PNV_CHIP, PnvChip *), 434 }; 435 436 static void pnv_homer_class_init(ObjectClass *klass, void *data) 437 { 438 DeviceClass *dc = DEVICE_CLASS(klass); 439 440 dc->realize = pnv_homer_realize; 441 dc->desc = "PowerNV HOMER Memory"; 442 device_class_set_props(dc, pnv_homer_properties); 443 dc->user_creatable = false; 444 } 445 446 static const TypeInfo pnv_homer_type_info = { 447 .name = TYPE_PNV_HOMER, 448 .parent = TYPE_DEVICE, 449 .instance_size = sizeof(PnvHomer), 450 .class_init = pnv_homer_class_init, 451 .class_size = sizeof(PnvHomerClass), 452 .abstract = true, 453 }; 454 455 static void pnv_homer_register_types(void) 456 { 457 type_register_static(&pnv_homer_type_info); 458 type_register_static(&pnv_homer_power8_type_info); 459 type_register_static(&pnv_homer_power9_type_info); 460 type_register_static(&pnv_homer_power10_type_info); 461 } 462 463 type_init(pnv_homer_register_types); 464