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