1 /* 2 * QEMU Uninorth PCI host (for all Mac99 and newer machines) 3 * 4 * Copyright (c) 2006 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "hw/irq.h" 27 #include "hw/ppc/mac.h" 28 #include "hw/qdev-properties.h" 29 #include "qemu/module.h" 30 #include "hw/pci/pci.h" 31 #include "hw/pci/pci_host.h" 32 #include "hw/pci-host/uninorth.h" 33 #include "trace.h" 34 35 static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num) 36 { 37 return (irq_num + (pci_dev->devfn >> 3)) & 3; 38 } 39 40 static void pci_unin_set_irq(void *opaque, int irq_num, int level) 41 { 42 UNINHostState *s = opaque; 43 44 trace_unin_set_irq(irq_num, level); 45 qemu_set_irq(s->irqs[irq_num], level); 46 } 47 48 static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr) 49 { 50 uint32_t retval; 51 52 if (reg & (1u << 31)) { 53 /* XXX OpenBIOS compatibility hack */ 54 retval = reg | (addr & 3); 55 } else if (reg & 1) { 56 /* CFA1 style */ 57 retval = (reg & ~7u) | (addr & 7); 58 } else { 59 uint32_t slot, func; 60 61 /* Grab CFA0 style values */ 62 slot = ctz32(reg & 0xfffff800); 63 if (slot == 32) { 64 slot = -1; /* XXX: should this be 0? */ 65 } 66 func = (reg >> 8) & 7; 67 68 /* ... and then convert them to x86 format */ 69 /* config pointer */ 70 retval = (reg & (0xff - 7)) | (addr & 7); 71 /* slot */ 72 retval |= slot << 11; 73 /* fn */ 74 retval |= func << 8; 75 } 76 77 trace_unin_get_config_reg(reg, addr, retval); 78 79 return retval; 80 } 81 82 static void unin_data_write(void *opaque, hwaddr addr, 83 uint64_t val, unsigned len) 84 { 85 UNINHostState *s = opaque; 86 PCIHostState *phb = PCI_HOST_BRIDGE(s); 87 trace_unin_data_write(addr, len, val); 88 pci_data_write(phb->bus, 89 unin_get_config_reg(phb->config_reg, addr), 90 val, len); 91 } 92 93 static uint64_t unin_data_read(void *opaque, hwaddr addr, 94 unsigned len) 95 { 96 UNINHostState *s = opaque; 97 PCIHostState *phb = PCI_HOST_BRIDGE(s); 98 uint32_t val; 99 100 val = pci_data_read(phb->bus, 101 unin_get_config_reg(phb->config_reg, addr), 102 len); 103 trace_unin_data_read(addr, len, val); 104 return val; 105 } 106 107 static const MemoryRegionOps unin_data_ops = { 108 .read = unin_data_read, 109 .write = unin_data_write, 110 .endianness = DEVICE_LITTLE_ENDIAN, 111 }; 112 113 static char *pci_unin_main_ofw_unit_address(const SysBusDevice *dev) 114 { 115 UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); 116 117 return g_strdup_printf("%x", s->ofw_addr); 118 } 119 120 static void pci_unin_main_realize(DeviceState *dev, Error **errp) 121 { 122 UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); 123 PCIHostState *h = PCI_HOST_BRIDGE(dev); 124 125 h->bus = pci_register_root_bus(dev, NULL, 126 pci_unin_set_irq, pci_unin_map_irq, 127 s, 128 &s->pci_mmio, 129 &s->pci_io, 130 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); 131 132 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-pci"); 133 134 /* DEC 21154 bridge */ 135 #if 0 136 /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */ 137 pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154"); 138 #endif 139 } 140 141 static void pci_unin_main_init(Object *obj) 142 { 143 UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(obj); 144 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 145 PCIHostState *h = PCI_HOST_BRIDGE(obj); 146 147 /* Use values found on a real PowerMac */ 148 /* Uninorth main bus */ 149 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, 150 obj, "unin-pci-conf-idx", 0x1000); 151 memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, 152 "unin-pci-conf-data", 0x1000); 153 154 memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", 155 0x100000000ULL); 156 memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, 157 "unin-pci-isa-mmio", 0x00800000); 158 159 memory_region_init_alias(&s->pci_hole, OBJECT(s), 160 "unin-pci-hole", &s->pci_mmio, 161 0x80000000ULL, 0x10000000ULL); 162 163 sysbus_init_mmio(sbd, &h->conf_mem); 164 sysbus_init_mmio(sbd, &h->data_mem); 165 sysbus_init_mmio(sbd, &s->pci_hole); 166 sysbus_init_mmio(sbd, &s->pci_io); 167 168 qdev_init_gpio_out(DEVICE(obj), s->irqs, ARRAY_SIZE(s->irqs)); 169 } 170 171 static void pci_u3_agp_realize(DeviceState *dev, Error **errp) 172 { 173 UNINHostState *s = U3_AGP_HOST_BRIDGE(dev); 174 PCIHostState *h = PCI_HOST_BRIDGE(dev); 175 176 h->bus = pci_register_root_bus(dev, NULL, 177 pci_unin_set_irq, pci_unin_map_irq, 178 s, 179 &s->pci_mmio, 180 &s->pci_io, 181 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); 182 183 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "u3-agp"); 184 } 185 186 static void pci_u3_agp_init(Object *obj) 187 { 188 UNINHostState *s = U3_AGP_HOST_BRIDGE(obj); 189 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 190 PCIHostState *h = PCI_HOST_BRIDGE(obj); 191 192 /* Uninorth U3 AGP bus */ 193 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, 194 obj, "unin-pci-conf-idx", 0x1000); 195 memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, 196 "unin-pci-conf-data", 0x1000); 197 198 memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", 199 0x100000000ULL); 200 memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, 201 "unin-pci-isa-mmio", 0x00800000); 202 203 memory_region_init_alias(&s->pci_hole, OBJECT(s), 204 "unin-pci-hole", &s->pci_mmio, 205 0x80000000ULL, 0x70000000ULL); 206 207 sysbus_init_mmio(sbd, &h->conf_mem); 208 sysbus_init_mmio(sbd, &h->data_mem); 209 sysbus_init_mmio(sbd, &s->pci_hole); 210 sysbus_init_mmio(sbd, &s->pci_io); 211 212 qdev_init_gpio_out(DEVICE(obj), s->irqs, ARRAY_SIZE(s->irqs)); 213 } 214 215 static void pci_unin_agp_realize(DeviceState *dev, Error **errp) 216 { 217 UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(dev); 218 PCIHostState *h = PCI_HOST_BRIDGE(dev); 219 220 h->bus = pci_register_root_bus(dev, NULL, 221 pci_unin_set_irq, pci_unin_map_irq, 222 s, 223 &s->pci_mmio, 224 &s->pci_io, 225 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); 226 227 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); 228 } 229 230 static void pci_unin_agp_init(Object *obj) 231 { 232 UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(obj); 233 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 234 PCIHostState *h = PCI_HOST_BRIDGE(obj); 235 236 /* Uninorth AGP bus */ 237 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, 238 obj, "unin-agp-conf-idx", 0x1000); 239 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, 240 obj, "unin-agp-conf-data", 0x1000); 241 242 sysbus_init_mmio(sbd, &h->conf_mem); 243 sysbus_init_mmio(sbd, &h->data_mem); 244 245 qdev_init_gpio_out(DEVICE(obj), s->irqs, ARRAY_SIZE(s->irqs)); 246 } 247 248 static void pci_unin_internal_realize(DeviceState *dev, Error **errp) 249 { 250 UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(dev); 251 PCIHostState *h = PCI_HOST_BRIDGE(dev); 252 253 h->bus = pci_register_root_bus(dev, NULL, 254 pci_unin_set_irq, pci_unin_map_irq, 255 s, 256 &s->pci_mmio, 257 &s->pci_io, 258 PCI_DEVFN(14, 0), 4, TYPE_PCI_BUS); 259 260 pci_create_simple(h->bus, PCI_DEVFN(14, 0), "uni-north-internal-pci"); 261 } 262 263 static void pci_unin_internal_init(Object *obj) 264 { 265 UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj); 266 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 267 PCIHostState *h = PCI_HOST_BRIDGE(obj); 268 269 /* Uninorth internal bus */ 270 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, 271 obj, "unin-pci-conf-idx", 0x1000); 272 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, 273 obj, "unin-pci-conf-data", 0x1000); 274 275 sysbus_init_mmio(sbd, &h->conf_mem); 276 sysbus_init_mmio(sbd, &h->data_mem); 277 278 qdev_init_gpio_out(DEVICE(obj), s->irqs, ARRAY_SIZE(s->irqs)); 279 } 280 281 static void unin_main_pci_host_realize(PCIDevice *d, Error **errp) 282 { 283 /* cache_line_size */ 284 d->config[0x0C] = 0x08; 285 /* latency_timer */ 286 d->config[0x0D] = 0x10; 287 /* capabilities_pointer */ 288 d->config[0x34] = 0x00; 289 290 /* 291 * Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI 292 * memory space with base 0x80000000, size 0x10000000 for Apple's 293 * AppleMacRiscPCI driver 294 */ 295 d->config[0x48] = 0x0; 296 d->config[0x49] = 0x0; 297 d->config[0x4a] = 0x0; 298 d->config[0x4b] = 0x1; 299 } 300 301 static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp) 302 { 303 /* cache_line_size */ 304 d->config[0x0C] = 0x08; 305 /* latency_timer */ 306 d->config[0x0D] = 0x10; 307 /* capabilities_pointer 308 d->config[0x34] = 0x80; */ 309 } 310 311 static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp) 312 { 313 /* cache line size */ 314 d->config[0x0C] = 0x08; 315 /* latency timer */ 316 d->config[0x0D] = 0x10; 317 } 318 319 static void unin_internal_pci_host_realize(PCIDevice *d, Error **errp) 320 { 321 /* cache_line_size */ 322 d->config[0x0C] = 0x08; 323 /* latency_timer */ 324 d->config[0x0D] = 0x10; 325 /* capabilities_pointer */ 326 d->config[0x34] = 0x00; 327 } 328 329 static void unin_main_pci_host_class_init(ObjectClass *klass, void *data) 330 { 331 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 332 DeviceClass *dc = DEVICE_CLASS(klass); 333 334 k->realize = unin_main_pci_host_realize; 335 k->vendor_id = PCI_VENDOR_ID_APPLE; 336 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI; 337 k->revision = 0x00; 338 k->class_id = PCI_CLASS_BRIDGE_HOST; 339 /* 340 * PCI-facing part of the host bridge, not usable without the 341 * host-facing part, which can't be device_add'ed, yet. 342 */ 343 dc->user_creatable = false; 344 } 345 346 static const TypeInfo unin_main_pci_host_info = { 347 .name = "uni-north-pci", 348 .parent = TYPE_PCI_DEVICE, 349 .instance_size = sizeof(PCIDevice), 350 .class_init = unin_main_pci_host_class_init, 351 .interfaces = (InterfaceInfo[]) { 352 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 353 { }, 354 }, 355 }; 356 357 static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data) 358 { 359 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 360 DeviceClass *dc = DEVICE_CLASS(klass); 361 362 k->realize = u3_agp_pci_host_realize; 363 k->vendor_id = PCI_VENDOR_ID_APPLE; 364 k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP; 365 k->revision = 0x00; 366 k->class_id = PCI_CLASS_BRIDGE_HOST; 367 /* 368 * PCI-facing part of the host bridge, not usable without the 369 * host-facing part, which can't be device_add'ed, yet. 370 */ 371 dc->user_creatable = false; 372 } 373 374 static const TypeInfo u3_agp_pci_host_info = { 375 .name = "u3-agp", 376 .parent = TYPE_PCI_DEVICE, 377 .instance_size = sizeof(PCIDevice), 378 .class_init = u3_agp_pci_host_class_init, 379 .interfaces = (InterfaceInfo[]) { 380 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 381 { }, 382 }, 383 }; 384 385 static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data) 386 { 387 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 388 DeviceClass *dc = DEVICE_CLASS(klass); 389 390 k->realize = unin_agp_pci_host_realize; 391 k->vendor_id = PCI_VENDOR_ID_APPLE; 392 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP; 393 k->revision = 0x00; 394 k->class_id = PCI_CLASS_BRIDGE_HOST; 395 /* 396 * PCI-facing part of the host bridge, not usable without the 397 * host-facing part, which can't be device_add'ed, yet. 398 */ 399 dc->user_creatable = false; 400 } 401 402 static const TypeInfo unin_agp_pci_host_info = { 403 .name = "uni-north-agp", 404 .parent = TYPE_PCI_DEVICE, 405 .instance_size = sizeof(PCIDevice), 406 .class_init = unin_agp_pci_host_class_init, 407 .interfaces = (InterfaceInfo[]) { 408 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 409 { }, 410 }, 411 }; 412 413 static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data) 414 { 415 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 416 DeviceClass *dc = DEVICE_CLASS(klass); 417 418 k->realize = unin_internal_pci_host_realize; 419 k->vendor_id = PCI_VENDOR_ID_APPLE; 420 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI; 421 k->revision = 0x00; 422 k->class_id = PCI_CLASS_BRIDGE_HOST; 423 /* 424 * PCI-facing part of the host bridge, not usable without the 425 * host-facing part, which can't be device_add'ed, yet. 426 */ 427 dc->user_creatable = false; 428 } 429 430 static const TypeInfo unin_internal_pci_host_info = { 431 .name = "uni-north-internal-pci", 432 .parent = TYPE_PCI_DEVICE, 433 .instance_size = sizeof(PCIDevice), 434 .class_init = unin_internal_pci_host_class_init, 435 .interfaces = (InterfaceInfo[]) { 436 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 437 { }, 438 }, 439 }; 440 441 static Property pci_unin_main_pci_host_props[] = { 442 DEFINE_PROP_UINT32("ofw-addr", UNINHostState, ofw_addr, -1), 443 DEFINE_PROP_END_OF_LIST() 444 }; 445 446 static void pci_unin_main_class_init(ObjectClass *klass, void *data) 447 { 448 DeviceClass *dc = DEVICE_CLASS(klass); 449 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); 450 451 dc->realize = pci_unin_main_realize; 452 device_class_set_props(dc, pci_unin_main_pci_host_props); 453 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 454 dc->fw_name = "pci"; 455 sbc->explicit_ofw_unit_address = pci_unin_main_ofw_unit_address; 456 } 457 458 static const TypeInfo pci_unin_main_info = { 459 .name = TYPE_UNI_NORTH_PCI_HOST_BRIDGE, 460 .parent = TYPE_PCI_HOST_BRIDGE, 461 .instance_size = sizeof(UNINHostState), 462 .instance_init = pci_unin_main_init, 463 .class_init = pci_unin_main_class_init, 464 }; 465 466 static void pci_u3_agp_class_init(ObjectClass *klass, void *data) 467 { 468 DeviceClass *dc = DEVICE_CLASS(klass); 469 470 dc->realize = pci_u3_agp_realize; 471 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 472 } 473 474 static const TypeInfo pci_u3_agp_info = { 475 .name = TYPE_U3_AGP_HOST_BRIDGE, 476 .parent = TYPE_PCI_HOST_BRIDGE, 477 .instance_size = sizeof(UNINHostState), 478 .instance_init = pci_u3_agp_init, 479 .class_init = pci_u3_agp_class_init, 480 }; 481 482 static void pci_unin_agp_class_init(ObjectClass *klass, void *data) 483 { 484 DeviceClass *dc = DEVICE_CLASS(klass); 485 486 dc->realize = pci_unin_agp_realize; 487 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 488 } 489 490 static const TypeInfo pci_unin_agp_info = { 491 .name = TYPE_UNI_NORTH_AGP_HOST_BRIDGE, 492 .parent = TYPE_PCI_HOST_BRIDGE, 493 .instance_size = sizeof(UNINHostState), 494 .instance_init = pci_unin_agp_init, 495 .class_init = pci_unin_agp_class_init, 496 }; 497 498 static void pci_unin_internal_class_init(ObjectClass *klass, void *data) 499 { 500 DeviceClass *dc = DEVICE_CLASS(klass); 501 502 dc->realize = pci_unin_internal_realize; 503 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 504 } 505 506 static const TypeInfo pci_unin_internal_info = { 507 .name = TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE, 508 .parent = TYPE_PCI_HOST_BRIDGE, 509 .instance_size = sizeof(UNINHostState), 510 .instance_init = pci_unin_internal_init, 511 .class_init = pci_unin_internal_class_init, 512 }; 513 514 /* UniN device */ 515 static void unin_write(void *opaque, hwaddr addr, uint64_t value, 516 unsigned size) 517 { 518 trace_unin_write(addr, value); 519 } 520 521 static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size) 522 { 523 uint32_t value; 524 525 switch (addr) { 526 case 0: 527 value = UNINORTH_VERSION_10A; 528 break; 529 default: 530 value = 0; 531 } 532 533 trace_unin_read(addr, value); 534 535 return value; 536 } 537 538 static const MemoryRegionOps unin_ops = { 539 .read = unin_read, 540 .write = unin_write, 541 .endianness = DEVICE_BIG_ENDIAN, 542 }; 543 544 static void unin_init(Object *obj) 545 { 546 UNINState *s = UNI_NORTH(obj); 547 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 548 549 memory_region_init_io(&s->mem, obj, &unin_ops, s, "unin", 0x1000); 550 551 sysbus_init_mmio(sbd, &s->mem); 552 } 553 554 static void unin_class_init(ObjectClass *klass, void *data) 555 { 556 DeviceClass *dc = DEVICE_CLASS(klass); 557 558 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 559 } 560 561 static const TypeInfo unin_info = { 562 .name = TYPE_UNI_NORTH, 563 .parent = TYPE_SYS_BUS_DEVICE, 564 .instance_size = sizeof(UNINState), 565 .instance_init = unin_init, 566 .class_init = unin_class_init, 567 }; 568 569 static void unin_register_types(void) 570 { 571 type_register_static(&unin_main_pci_host_info); 572 type_register_static(&u3_agp_pci_host_info); 573 type_register_static(&unin_agp_pci_host_info); 574 type_register_static(&unin_internal_pci_host_info); 575 576 type_register_static(&pci_unin_main_info); 577 type_register_static(&pci_u3_agp_info); 578 type_register_static(&pci_unin_agp_info); 579 type_register_static(&pci_unin_internal_info); 580 581 type_register_static(&unin_info); 582 } 583 584 type_init(unin_register_types) 585