1 /* 2 * HP-PARISC Astro/Pluto/Ike/REO system bus adapter (SBA) 3 * with Elroy PCI bus (LBA) adapter emulation 4 * Found in C3000 and similar machines 5 * 6 * (C) 2023 by Helge Deller <deller@gmx.de> 7 * 8 * This work is licensed under the GNU GPL license version 2 or later. 9 * 10 * Chip documentation is available at: 11 * https://parisc.wiki.kernel.org/index.php/Technical_Documentation 12 * 13 * TODO: 14 * - All user-added devices are currently attached to the first 15 * Elroy (PCI bus) only for now. To fix this additional work in 16 * SeaBIOS and this driver is needed. See "user_creatable" flag below. 17 * - GMMIO (Greater than 4 GB MMIO) register 18 */ 19 20 #define TYPE_ASTRO_IOMMU_MEMORY_REGION "astro-iommu-memory-region" 21 22 #include "qemu/osdep.h" 23 #include "qemu/module.h" 24 #include "qemu/units.h" 25 #include "qapi/error.h" 26 #include "hw/irq.h" 27 #include "hw/pci/pci_device.h" 28 #include "hw/pci/pci_bus.h" 29 #include "hw/qdev-properties.h" 30 #include "hw/pci-host/astro.h" 31 #include "hw/hppa/hppa_hardware.h" 32 #include "migration/vmstate.h" 33 #include "trace.h" 34 #include "qom/object.h" 35 36 /* 37 * Helper functions 38 */ 39 40 static uint64_t mask_32bit_val(hwaddr addr, unsigned size, uint64_t val) 41 { 42 if (size == 8) { 43 return val; 44 } 45 if (addr & 4) { 46 val >>= 32; 47 } else { 48 val = (uint32_t) val; 49 } 50 return val; 51 } 52 53 static void put_val_in_int64(uint64_t *p, hwaddr addr, unsigned size, 54 uint64_t val) 55 { 56 if (size == 8) { 57 *p = val; 58 } else if (size == 4) { 59 if (addr & 4) { 60 *p = ((*p << 32) >> 32) | (val << 32); 61 } else { 62 *p = ((*p >> 32) << 32) | (uint32_t) val; 63 } 64 } 65 } 66 67 static void put_val_in_arrary(uint64_t *array, hwaddr start_addr, 68 hwaddr addr, unsigned size, uint64_t val) 69 { 70 int index; 71 72 index = (addr - start_addr) / 8; 73 put_val_in_int64(&array[index], addr, size, val); 74 } 75 76 77 /* 78 * The Elroy PCI host bridge. We have at least 4 of those under Astro. 79 */ 80 81 static MemTxResult elroy_chip_read_with_attrs(void *opaque, hwaddr addr, 82 uint64_t *data, unsigned size, 83 MemTxAttrs attrs) 84 { 85 MemTxResult ret = MEMTX_OK; 86 ElroyState *s = opaque; 87 uint64_t val = -1; 88 int index; 89 90 switch ((addr >> 3) << 3) { 91 case 0x0008: 92 val = 0x6000005; /* func_class */ 93 break; 94 case 0x0058: 95 /* 96 * Scratch register, but firmware initializes it with the 97 * PCI BUS number and Linux/HP-UX uses it then. 98 */ 99 val = s->pci_bus_num; 100 /* Upper byte holds the end of this bus number */ 101 val |= s->pci_bus_num << 8; 102 break; 103 case 0x0080: 104 val = s->arb_mask; /* set ARB mask */ 105 break; 106 case 0x0108: 107 val = s->status_control; 108 break; 109 case 0x200 ... 0x250 - 1: /* LMMIO, GMMIO, WLMMIO, WGMMIO, ... */ 110 index = (addr - 0x200) / 8; 111 val = s->mmio_base[index]; 112 break; 113 case 0x0680: 114 val = s->error_config; 115 break; 116 case 0x0688: 117 val = 0; /* ERROR_STATUS */ 118 break; 119 case 0x0800: /* IOSAPIC_REG_SELECT */ 120 val = s->iosapic_reg_select; 121 break; 122 case 0x0808: 123 val = UINT64_MAX; /* XXX: tbc. */ 124 g_assert_not_reached(); 125 break; 126 case 0x0810: /* IOSAPIC_REG_WINDOW */ 127 switch (s->iosapic_reg_select) { 128 case 0x01: /* IOSAPIC_REG_VERSION */ 129 val = (32 << 16) | 1; /* upper 16bit holds max entries */ 130 break; 131 default: 132 if (s->iosapic_reg_select < ARRAY_SIZE(s->iosapic_reg)) { 133 val = s->iosapic_reg[s->iosapic_reg_select]; 134 } else { 135 trace_iosapic_reg_read(s->iosapic_reg_select, size, val); 136 g_assert_not_reached(); 137 } 138 } 139 trace_iosapic_reg_read(s->iosapic_reg_select, size, val); 140 break; 141 default: 142 trace_elroy_read(addr, size, val); 143 g_assert_not_reached(); 144 } 145 trace_elroy_read(addr, size, val); 146 147 /* for 32-bit accesses mask return value */ 148 val = mask_32bit_val(addr, size, val); 149 150 trace_astro_chip_read(addr, size, val); 151 *data = val; 152 return ret; 153 } 154 155 156 static MemTxResult elroy_chip_write_with_attrs(void *opaque, hwaddr addr, 157 uint64_t val, unsigned size, 158 MemTxAttrs attrs) 159 { 160 ElroyState *s = opaque; 161 int i; 162 163 trace_elroy_write(addr, size, val); 164 165 switch ((addr >> 3) << 3) { 166 case 0x080: 167 put_val_in_int64(&s->arb_mask, addr, size, val); 168 break; 169 case 0x0108: 170 put_val_in_int64(&s->status_control, addr, size, val); 171 break; 172 case 0x200 ... 0x250 - 1: /* LMMIO, GMMIO, WLMMIO, WGMMIO, ... */ 173 put_val_in_arrary(s->mmio_base, 0x200, addr, size, val); 174 break; 175 case 0x0680: 176 put_val_in_int64(&s->error_config, addr, size, val); 177 break; 178 case 0x0800: /* IOSAPIC_REG_SELECT */ 179 s->iosapic_reg_select = val; 180 break; 181 case 0x0810: /* IOSAPIC_REG_WINDOW */ 182 trace_iosapic_reg_write(s->iosapic_reg_select, size, val); 183 if (s->iosapic_reg_select < ARRAY_SIZE(s->iosapic_reg)) { 184 s->iosapic_reg[s->iosapic_reg_select] = val; 185 } else { 186 g_assert_not_reached(); 187 } 188 break; 189 case 0x0840: /* IOSAPIC_REG_EOI */ 190 val = le64_to_cpu(val); 191 val &= 63; 192 for (i = 0; i < ELROY_IRQS; i++) { 193 if ((s->iosapic_reg[0x10 + 2 * i] & 63) == val) { 194 s->ilr &= ~(1ull << i); 195 } 196 } 197 break; 198 default: 199 g_assert_not_reached(); 200 } 201 return MEMTX_OK; 202 } 203 204 static const MemoryRegionOps elroy_chip_ops = { 205 .read_with_attrs = elroy_chip_read_with_attrs, 206 .write_with_attrs = elroy_chip_write_with_attrs, 207 .endianness = DEVICE_LITTLE_ENDIAN, 208 .valid = { 209 .min_access_size = 4, 210 .max_access_size = 8, 211 }, 212 .impl = { 213 .min_access_size = 4, 214 .max_access_size = 8, 215 }, 216 }; 217 218 219 /* Unlike pci_config_data_le_ops, no check of high bit set in config_reg. */ 220 221 static uint64_t elroy_config_data_read(void *opaque, hwaddr addr, unsigned len) 222 { 223 uint64_t val; 224 225 PCIHostState *s = opaque; 226 val = pci_data_read(s->bus, s->config_reg | (addr & 3), len); 227 trace_elroy_pci_config_data_read(s->config_reg | (addr & 3), len, val); 228 return val; 229 } 230 231 static void elroy_config_data_write(void *opaque, hwaddr addr, 232 uint64_t val, unsigned len) 233 { 234 PCIHostState *s = opaque; 235 pci_data_write(s->bus, s->config_reg | (addr & 3), val, len); 236 trace_elroy_pci_config_data_write(s->config_reg | (addr & 3), len, val); 237 } 238 239 static const MemoryRegionOps elroy_config_data_ops = { 240 .read = elroy_config_data_read, 241 .write = elroy_config_data_write, 242 .endianness = DEVICE_LITTLE_ENDIAN, 243 }; 244 245 static uint64_t elroy_config_addr_read(void *opaque, hwaddr addr, unsigned len) 246 { 247 ElroyState *s = opaque; 248 return s->config_reg_elroy; 249 } 250 251 static void elroy_config_addr_write(void *opaque, hwaddr addr, 252 uint64_t val, unsigned len) 253 { 254 PCIHostState *s = opaque; 255 ElroyState *es = opaque; 256 es->config_reg_elroy = val; /* keep a copy of original value */ 257 s->config_reg = val; 258 } 259 260 static const MemoryRegionOps elroy_config_addr_ops = { 261 .read = elroy_config_addr_read, 262 .write = elroy_config_addr_write, 263 .valid.min_access_size = 4, 264 .valid.max_access_size = 8, 265 .endianness = DEVICE_LITTLE_ENDIAN, 266 }; 267 268 269 /* 270 * A subroutine of astro_translate_iommu that builds an IOMMUTLBEntry using the 271 * given translated address and mask. 272 */ 273 static bool make_iommu_tlbe(hwaddr addr, hwaddr taddr, hwaddr mask, 274 IOMMUTLBEntry *ret) 275 { 276 hwaddr tce_mask = ~((1ull << 12) - 1); 277 ret->target_as = &address_space_memory; 278 ret->iova = addr & tce_mask; 279 ret->translated_addr = taddr & tce_mask; 280 ret->addr_mask = ~tce_mask; 281 ret->perm = IOMMU_RW; 282 return true; 283 } 284 285 /* Handle PCI-to-system address translation. */ 286 static IOMMUTLBEntry astro_translate_iommu(IOMMUMemoryRegion *iommu, 287 hwaddr addr, 288 IOMMUAccessFlags flag, 289 int iommu_idx) 290 { 291 AstroState *s = container_of(iommu, AstroState, iommu); 292 IOMMUTLBEntry ret = { 293 .target_as = &address_space_memory, 294 .iova = addr, 295 .translated_addr = 0, 296 .addr_mask = ~(hwaddr)0, 297 .perm = IOMMU_NONE, 298 }; 299 hwaddr pdir_ptr, index, a, ibase; 300 hwaddr addr_mask = 0xfff; /* 4k translation */ 301 uint64_t entry; 302 303 #define IOVP_SHIFT 12 /* equals PAGE_SHIFT */ 304 #define PDIR_INDEX(iovp) ((iovp) >> IOVP_SHIFT) 305 #define IOVP_MASK PAGE_MASK 306 #define SBA_PDIR_VALID_BIT 0x8000000000000000ULL 307 308 /* "range enable" flag cleared? */ 309 if ((s->tlb_ibase & 1) == 0) { 310 make_iommu_tlbe(addr, addr, addr_mask, &ret); 311 return ret; 312 } 313 314 a = addr; 315 ibase = s->tlb_ibase & ~1ULL; 316 if ((a & s->tlb_imask) != ibase) { 317 /* do not translate this one! */ 318 make_iommu_tlbe(addr, addr, addr_mask, &ret); 319 return ret; 320 } 321 index = PDIR_INDEX(a); 322 pdir_ptr = s->tlb_pdir_base + index * sizeof(entry); 323 entry = ldq_le_phys(&address_space_memory, pdir_ptr); 324 if (!(entry & SBA_PDIR_VALID_BIT)) { /* I/O PDIR entry valid ? */ 325 g_assert_not_reached(); 326 goto failure; 327 } 328 entry &= ~SBA_PDIR_VALID_BIT; 329 entry >>= IOVP_SHIFT; 330 entry <<= 12; 331 entry |= addr & 0xfff; 332 make_iommu_tlbe(addr, entry, addr_mask, &ret); 333 goto success; 334 335 failure: 336 ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE }; 337 success: 338 return ret; 339 } 340 341 static AddressSpace *elroy_pcihost_set_iommu(PCIBus *bus, void *opaque, 342 int devfn) 343 { 344 ElroyState *s = opaque; 345 return &s->astro->iommu_as; 346 } 347 348 static const PCIIOMMUOps elroy_pcihost_iommu_ops = { 349 .get_address_space = elroy_pcihost_set_iommu, 350 }; 351 352 /* 353 * Encoding in IOSAPIC: 354 * base_addr == 0xfffa0000, we want to get 0xa0ff0000. 355 * eid 0x0ff00000 -> 0x00ff0000 356 * id 0x000ff000 -> 0xff000000 357 */ 358 #define SWIZZLE_HPA(a) \ 359 ((((a) & 0x0ff00000) >> 4) | (((a) & 0x000ff000) << 12)) 360 #define UNSWIZZLE_HPA(a) \ 361 (((((a) << 4) & 0x0ff00000) | (((a) >> 12) & 0x000ff000) | 0xf0000000)) 362 363 /* bits in the "low" I/O Sapic IRdT entry */ 364 #define IOSAPIC_IRDT_DISABLE 0x10000 /* if bit is set, mask this irq */ 365 #define IOSAPIC_IRDT_PO_LOW 0x02000 366 #define IOSAPIC_IRDT_LEVEL_TRIG 0x08000 367 #define IOSAPIC_IRDT_MODE_LPRI 0x00100 368 369 #define CPU_IRQ_OFFSET 2 370 371 static void elroy_set_irq(void *opaque, int irq, int level) 372 { 373 ElroyState *s = opaque; 374 uint32_t bit; 375 uint32_t old_ilr = s->ilr; 376 hwaddr cpu_hpa; 377 uint32_t val; 378 379 val = s->iosapic_reg[0x10 + 2 * irq]; 380 cpu_hpa = s->iosapic_reg[0x11 + 2 * irq]; 381 /* low nibble of val has value to write into CPU irq reg */ 382 bit = 1u << (val & (ELROY_IRQS - 1)); 383 cpu_hpa = UNSWIZZLE_HPA(cpu_hpa); 384 385 if (level && (!(val & IOSAPIC_IRDT_DISABLE)) && cpu_hpa) { 386 uint32_t ena = bit & ~old_ilr; 387 s->ilr = old_ilr | bit; 388 if (ena != 0) { 389 stl_be_phys(&address_space_memory, cpu_hpa, val & 63); 390 } 391 } else { 392 s->ilr = old_ilr & ~bit; 393 } 394 } 395 396 static int elroy_pci_map_irq(PCIDevice *d, int irq_num) 397 { 398 int slot = PCI_SLOT(d->devfn); 399 400 assert(irq_num >= 0 && irq_num < ELROY_IRQS); 401 return slot & (ELROY_IRQS - 1); 402 } 403 404 static void elroy_reset(DeviceState *dev) 405 { 406 ElroyState *s = ELROY_PCI_HOST_BRIDGE(dev); 407 int irq; 408 409 /* 410 * Make sure to disable interrupts at reboot, otherwise the Linux kernel 411 * serial8250_config_port() in drivers/tty/serial/8250/8250_port.c 412 * will hang during autoconfig(). 413 */ 414 s->ilr = 0; 415 for (irq = 0; irq < ELROY_IRQS; irq++) { 416 s->iosapic_reg[0x10 + 2 * irq] = IOSAPIC_IRDT_PO_LOW | 417 IOSAPIC_IRDT_LEVEL_TRIG | (irq + CPU_IRQ_OFFSET) | 418 IOSAPIC_IRDT_DISABLE; 419 s->iosapic_reg[0x11 + 2 * irq] = SWIZZLE_HPA(CPU_HPA); 420 } 421 } 422 423 static void elroy_pcihost_init(Object *obj) 424 { 425 ElroyState *s = ELROY_PCI_HOST_BRIDGE(obj); 426 PCIHostState *phb = PCI_HOST_BRIDGE(obj); 427 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 428 429 /* Elroy config access from CPU. */ 430 memory_region_init_io(&s->this_mem, OBJECT(s), &elroy_chip_ops, 431 s, "elroy", 0x2000); 432 433 /* Elroy PCI config. */ 434 memory_region_init_io(&phb->conf_mem, OBJECT(phb), 435 &elroy_config_addr_ops, DEVICE(s), 436 "pci-conf-idx", 8); 437 memory_region_init_io(&phb->data_mem, OBJECT(phb), 438 &elroy_config_data_ops, DEVICE(s), 439 "pci-conf-data", 8); 440 memory_region_add_subregion(&s->this_mem, 0x40, 441 &phb->conf_mem); 442 memory_region_add_subregion(&s->this_mem, 0x48, 443 &phb->data_mem); 444 445 /* Elroy PCI bus memory. */ 446 memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", UINT64_MAX); 447 memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, 448 "pci-isa-mmio", 449 ((uint32_t) IOS_DIST_BASE_SIZE) / ROPES_PER_IOC); 450 451 phb->bus = pci_register_root_bus(DEVICE(s), "pci", 452 elroy_set_irq, elroy_pci_map_irq, s, 453 &s->pci_mmio, &s->pci_io, 454 PCI_DEVFN(0, 0), ELROY_IRQS, TYPE_PCI_BUS); 455 456 sysbus_init_mmio(sbd, &s->this_mem); 457 458 qdev_init_gpio_in(DEVICE(obj), elroy_set_irq, ELROY_IRQS); 459 } 460 461 static Property elroy_pcihost_properties[] = { 462 DEFINE_PROP_END_OF_LIST(), 463 }; 464 465 static const VMStateDescription vmstate_elroy = { 466 .name = "Elroy", 467 .version_id = 1, 468 .minimum_version_id = 1, 469 .fields = (VMStateField[]) { 470 VMSTATE_UINT64(hpa, ElroyState), 471 VMSTATE_UINT32(pci_bus_num, ElroyState), 472 VMSTATE_UINT64(config_address, ElroyState), 473 VMSTATE_UINT64(config_reg_elroy, ElroyState), 474 VMSTATE_UINT64(status_control, ElroyState), 475 VMSTATE_UINT64(arb_mask, ElroyState), 476 VMSTATE_UINT64_ARRAY(mmio_base, ElroyState, (0x0250 - 0x200) / 8), 477 VMSTATE_UINT64(error_config, ElroyState), 478 VMSTATE_UINT32(iosapic_reg_select, ElroyState), 479 VMSTATE_UINT64_ARRAY(iosapic_reg, ElroyState, 0x20), 480 VMSTATE_UINT32(ilr, ElroyState), 481 VMSTATE_END_OF_LIST() 482 } 483 }; 484 485 static void elroy_pcihost_class_init(ObjectClass *klass, void *data) 486 { 487 DeviceClass *dc = DEVICE_CLASS(klass); 488 489 dc->reset = elroy_reset; 490 device_class_set_props(dc, elroy_pcihost_properties); 491 dc->vmsd = &vmstate_elroy; 492 dc->user_creatable = false; 493 } 494 495 static const TypeInfo elroy_pcihost_info = { 496 .name = TYPE_ELROY_PCI_HOST_BRIDGE, 497 .parent = TYPE_PCI_HOST_BRIDGE, 498 .instance_init = elroy_pcihost_init, 499 .instance_size = sizeof(ElroyState), 500 .class_init = elroy_pcihost_class_init, 501 }; 502 503 static void elroy_register_types(void) 504 { 505 type_register_static(&elroy_pcihost_info); 506 } 507 508 type_init(elroy_register_types) 509 510 511 static ElroyState *elroy_init(int num) 512 { 513 DeviceState *dev; 514 515 dev = qdev_new(TYPE_ELROY_PCI_HOST_BRIDGE); 516 dev->id = g_strdup_printf("elroy%d", num); 517 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 518 519 return ELROY_PCI_HOST_BRIDGE(dev); 520 } 521 522 /* 523 * Astro Runway chip. 524 */ 525 526 static MemTxResult astro_chip_read_with_attrs(void *opaque, hwaddr addr, 527 uint64_t *data, unsigned size, 528 MemTxAttrs attrs) 529 { 530 AstroState *s = opaque; 531 MemTxResult ret = MEMTX_OK; 532 uint64_t val = -1; 533 int index; 534 535 switch ((addr >> 3) << 3) { 536 /* R2I registers */ 537 case 0x0000: /* ID */ 538 val = (0x01 << 3) | 0x01ULL; 539 break; 540 case 0x0008: /* IOC_CTRL */ 541 val = s->ioc_ctrl; 542 break; 543 case 0x0010: /* TOC_CLIENT_ID */ 544 break; 545 case 0x0030: /* HP-UX 10.20 and 11.11 reads it. No idea. */ 546 val = -1; 547 break; 548 case 0x0300 ... 0x03d8: /* LMMIO_DIRECT0_BASE... */ 549 index = (addr - 0x300) / 8; 550 val = s->ioc_ranges[index]; 551 break; 552 case 0x10200: 553 val = 0; 554 break; 555 case 0x10220: 556 case 0x10230: /* HP-UX 11.11 reads it. No idea. */ 557 val = -1; 558 break; 559 case 0x22108: /* IOC STATUS_CONTROL */ 560 val = s->ioc_status_ctrl; 561 break; 562 case 0x20200 ... 0x20240 - 1: /* IOC Rope0_Control ... */ 563 index = (addr - 0x20200) / 8; 564 val = s->ioc_rope_control[index]; 565 break; 566 case 0x20040: /* IOC Rope config */ 567 val = s->ioc_rope_config; 568 break; 569 case 0x20050: /* IOC Rope debug */ 570 val = 0; 571 break; 572 case 0x20108: /* IOC STATUS_CONTROL */ 573 val = s->ioc_status_control; 574 break; 575 case 0x20310: /* IOC_PCOM */ 576 val = s->tlb_pcom; 577 /* TODO: flush iommu */ 578 break; 579 case 0x20400: 580 val = s->ioc_flush_control; 581 break; 582 /* empty placeholders for non-existent elroys */ 583 #define EMPTY_PORT(x) case x: case x+8: val = 0; break; \ 584 case x+40: case x+48: val = UINT64_MAX; break; 585 EMPTY_PORT(0x30000) 586 EMPTY_PORT(0x32000) 587 EMPTY_PORT(0x34000) 588 EMPTY_PORT(0x36000) 589 EMPTY_PORT(0x38000) 590 EMPTY_PORT(0x3a000) 591 EMPTY_PORT(0x3c000) 592 EMPTY_PORT(0x3e000) 593 #undef EMPTY_PORT 594 595 default: 596 trace_astro_chip_read(addr, size, val); 597 g_assert_not_reached(); 598 } 599 600 /* for 32-bit accesses mask return value */ 601 val = mask_32bit_val(addr, size, val); 602 603 trace_astro_chip_read(addr, size, val); 604 *data = val; 605 return ret; 606 } 607 608 static MemTxResult astro_chip_write_with_attrs(void *opaque, hwaddr addr, 609 uint64_t val, unsigned size, 610 MemTxAttrs attrs) 611 { 612 AstroState *s = opaque; 613 614 trace_astro_chip_write(addr, size, val); 615 616 switch ((addr >> 3) << 3) { 617 case 0x0000: /* ID */ 618 break; 619 case 0x0008: /* IOC_CTRL */ 620 val &= 0x0ffffff; 621 put_val_in_int64(&s->ioc_ctrl, addr, size, val); 622 break; 623 case 0x0010: /* TOC_CLIENT_ID */ 624 break; 625 case 0x0030: /* HP-UX 10.20 and 11.11 reads it. No idea. */ 626 break; 627 case 0x0300 ... 0x03d8 - 1: /* LMMIO_DIRECT0_BASE... */ 628 put_val_in_arrary(s->ioc_ranges, 0x300, addr, size, val); 629 break; 630 case 0x10200: 631 case 0x10220: 632 case 0x10230: /* HP-UX 11.11 reads it. No idea. */ 633 break; 634 case 0x22108: /* IOC STATUS_CONTROL */ 635 put_val_in_int64(&s->ioc_status_ctrl, addr, size, val); 636 break; 637 case 0x20200 ... 0x20240 - 1: /* IOC Rope0_Control ... */ 638 put_val_in_arrary(s->ioc_rope_control, 0x20200, addr, size, val); 639 break; 640 case 0x20040: /* IOC Rope config */ 641 put_val_in_int64(&s->ioc_rope_config, addr, size, val); 642 break; 643 case 0x20300: 644 put_val_in_int64(&s->tlb_ibase, addr, size, val); 645 break; 646 case 0x20308: 647 put_val_in_int64(&s->tlb_imask, addr, size, val); 648 break; 649 case 0x20310: 650 put_val_in_int64(&s->tlb_pcom, addr, size, val); 651 /* TODO: flush iommu */ 652 break; 653 case 0x20318: 654 put_val_in_int64(&s->tlb_tcnfg, addr, size, val); 655 break; 656 case 0x20320: 657 put_val_in_int64(&s->tlb_pdir_base, addr, size, val); 658 break; 659 /* 660 * empty placeholders for non-existent elroys, e.g. 661 * func_class, pci config & data 662 */ 663 #define EMPTY_PORT(x) case x: case x+8: case x+0x40: case x+0x48: 664 EMPTY_PORT(0x30000) 665 EMPTY_PORT(0x32000) 666 EMPTY_PORT(0x34000) 667 EMPTY_PORT(0x36000) 668 EMPTY_PORT(0x38000) 669 EMPTY_PORT(0x3a000) 670 EMPTY_PORT(0x3c000) 671 EMPTY_PORT(0x3e000) 672 break; 673 #undef EMPTY_PORT 674 675 default: 676 /* Controlled by astro_chip_mem_valid above. */ 677 trace_astro_chip_write(addr, size, val); 678 g_assert_not_reached(); 679 } 680 return MEMTX_OK; 681 } 682 683 static const MemoryRegionOps astro_chip_ops = { 684 .read_with_attrs = astro_chip_read_with_attrs, 685 .write_with_attrs = astro_chip_write_with_attrs, 686 .endianness = DEVICE_LITTLE_ENDIAN, 687 .valid = { 688 .min_access_size = 4, 689 .max_access_size = 8, 690 }, 691 .impl = { 692 .min_access_size = 4, 693 .max_access_size = 8, 694 }, 695 }; 696 697 static const VMStateDescription vmstate_astro = { 698 .name = "Astro", 699 .version_id = 1, 700 .minimum_version_id = 1, 701 .fields = (VMStateField[]) { 702 VMSTATE_UINT64(ioc_ctrl, AstroState), 703 VMSTATE_UINT64(ioc_status_ctrl, AstroState), 704 VMSTATE_UINT64_ARRAY(ioc_ranges, AstroState, (0x03d8 - 0x300) / 8), 705 VMSTATE_UINT64(ioc_rope_config, AstroState), 706 VMSTATE_UINT64(ioc_status_control, AstroState), 707 VMSTATE_UINT64(ioc_flush_control, AstroState), 708 VMSTATE_UINT64_ARRAY(ioc_rope_control, AstroState, 8), 709 VMSTATE_UINT64(tlb_ibase, AstroState), 710 VMSTATE_UINT64(tlb_imask, AstroState), 711 VMSTATE_UINT64(tlb_pcom, AstroState), 712 VMSTATE_UINT64(tlb_tcnfg, AstroState), 713 VMSTATE_UINT64(tlb_pdir_base, AstroState), 714 VMSTATE_END_OF_LIST() 715 } 716 }; 717 718 static void astro_reset(DeviceState *dev) 719 { 720 AstroState *s = ASTRO_CHIP(dev); 721 int i; 722 723 s->ioc_ctrl = 0x29cf; 724 s->ioc_rope_config = 0xc5f; 725 s->ioc_flush_control = 0xb03; 726 s->ioc_status_control = 0; 727 memset(&s->ioc_rope_control, 0, sizeof(s->ioc_rope_control)); 728 729 /* 730 * The SBA BASE/MASK registers control CPU -> IO routing. 731 * The LBA BASE/MASK registers control IO -> System routing (in Elroy) 732 */ 733 memset(&s->ioc_ranges, 0, sizeof(s->ioc_ranges)); 734 s->ioc_ranges[(0x360 - 0x300) / 8] = LMMIO_DIST_BASE_ADDR | 0x01; /* LMMIO_DIST_BASE (SBA) */ 735 s->ioc_ranges[(0x368 - 0x300) / 8] = 0xfc000000; /* LMMIO_DIST_MASK */ 736 s->ioc_ranges[(0x370 - 0x300) / 8] = 0; /* LMMIO_DIST_ROUTE */ 737 s->ioc_ranges[(0x390 - 0x300) / 8] = IOS_DIST_BASE_ADDR | 0x01; /* IOS_DIST_BASE */ 738 s->ioc_ranges[(0x398 - 0x300) / 8] = 0xffffff0000; /* IOS_DIST_MASK */ 739 s->ioc_ranges[(0x3a0 - 0x300) / 8] = 0x3400000000000000ULL; /* IOS_DIST_ROUTE */ 740 s->ioc_ranges[(0x3c0 - 0x300) / 8] = 0xfffee00000; /* IOS_DIRECT_BASE */ 741 s->ioc_ranges[(0x3c8 - 0x300) / 8] = 0xffffff0000; /* IOS_DIRECT_MASK */ 742 s->ioc_ranges[(0x3d0 - 0x300) / 8] = 0x0; /* IOS_DIRECT_ROUTE */ 743 744 s->tlb_ibase = 0; 745 s->tlb_imask = 0; 746 s->tlb_pcom = 0; 747 s->tlb_tcnfg = 0; 748 s->tlb_pdir_base = 0; 749 750 for (i = 0; i < ELROY_NUM; i++) { 751 elroy_reset(DEVICE(s->elroy[i])); 752 } 753 } 754 755 static void astro_init(Object *obj) 756 { 757 } 758 759 static void astro_realize(DeviceState *obj, Error **errp) 760 { 761 AstroState *s = ASTRO_CHIP(obj); 762 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 763 int i; 764 765 memory_region_init_io(&s->this_mem, OBJECT(s), &astro_chip_ops, 766 s, "astro", 0x40000); 767 sysbus_init_mmio(sbd, &s->this_mem); 768 769 /* Host memory as seen from Elroys PCI side, via the IOMMU. */ 770 memory_region_init_iommu(&s->iommu, sizeof(s->iommu), 771 TYPE_ASTRO_IOMMU_MEMORY_REGION, OBJECT(s), 772 "iommu-astro", UINT64_MAX); 773 address_space_init(&s->iommu_as, MEMORY_REGION(&s->iommu), 774 "bm-pci"); 775 776 /* Create Elroys (PCI host bus chips). */ 777 for (i = 0; i < ELROY_NUM; i++) { 778 static const int elroy_hpa_offsets[ELROY_NUM] = { 779 0x30000, 0x32000, 0x38000, 0x3c000 }; 780 static const char elroy_rope_nr[ELROY_NUM] = { 781 0, 1, 4, 6 }; /* busnum path, e.g. [10:6] */ 782 int addr_offset; 783 ElroyState *elroy; 784 hwaddr map_addr; 785 uint64_t map_size; 786 int rope; 787 788 addr_offset = elroy_hpa_offsets[i]; 789 rope = elroy_rope_nr[i]; 790 791 elroy = elroy_init(i); 792 s->elroy[i] = elroy; 793 elroy->hpa = ASTRO_HPA + addr_offset; 794 elroy->pci_bus_num = i; 795 elroy->astro = s; 796 797 /* 798 * NOTE: we only allow PCI devices on first Elroy for now. 799 * SeaBIOS will not find devices on the other busses. 800 */ 801 if (i > 0) { 802 qbus_mark_full(&PCI_HOST_BRIDGE(elroy)->bus->qbus); 803 } 804 805 /* map elroy config addresses into Astro space */ 806 memory_region_add_subregion(&s->this_mem, addr_offset, 807 &elroy->this_mem); 808 809 /* LMMIO */ 810 elroy->mmio_base[(0x0200 - 0x200) / 8] = 0xf0000001; 811 elroy->mmio_base[(0x0208 - 0x200) / 8] = 0xf8000000; 812 /* GMMIO */ 813 elroy->mmio_base[(0x0210 - 0x200) / 8] = 0x000000f800000001; 814 elroy->mmio_base[(0x0218 - 0x200) / 8] = 0x000000ff80000000; 815 /* WLMMIO */ 816 elroy->mmio_base[(0x0220 - 0x200) / 8] = 0xf0000001; 817 elroy->mmio_base[(0x0228 - 0x200) / 8] = 0xf0000000; 818 /* WGMMIO */ 819 elroy->mmio_base[(0x0230 - 0x200) / 8] = 0x000000f800000001; 820 elroy->mmio_base[(0x0238 - 0x200) / 8] = 0x000000fc00000000; 821 /* IOS_BASE */ 822 map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC; 823 elroy->mmio_base[(0x0240 - 0x200) / 8] = rope * map_size | 0x01; 824 elroy->mmio_base[(0x0248 - 0x200) / 8] = 0x0000e000; 825 826 /* map elroys mmio */ 827 map_size = LMMIO_DIST_BASE_SIZE / ROPES_PER_IOC; 828 map_addr = (uint32_t) (LMMIO_DIST_BASE_ADDR + rope * map_size); 829 memory_region_init_alias(&elroy->pci_mmio_alias, OBJECT(elroy), 830 "pci-mmio-alias", 831 &elroy->pci_mmio, map_addr, map_size); 832 memory_region_add_subregion(get_system_memory(), map_addr, 833 &elroy->pci_mmio_alias); 834 835 map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC; 836 map_addr = (uint32_t) (IOS_DIST_BASE_ADDR + rope * map_size); 837 memory_region_add_subregion(get_system_memory(), map_addr, 838 &elroy->pci_io); 839 840 /* Host memory as seen from the PCI side, via the IOMMU. */ 841 pci_setup_iommu(PCI_HOST_BRIDGE(elroy)->bus, &elroy_pcihost_iommu_ops, 842 elroy); 843 } 844 } 845 846 static void astro_class_init(ObjectClass *klass, void *data) 847 { 848 DeviceClass *dc = DEVICE_CLASS(klass); 849 850 dc->reset = astro_reset; 851 dc->vmsd = &vmstate_astro; 852 dc->realize = astro_realize; 853 /* 854 * astro with elroys are hard part of the newer PA2.0 machines and can not 855 * be created without that hardware 856 */ 857 dc->user_creatable = false; 858 } 859 860 static const TypeInfo astro_chip_info = { 861 .name = TYPE_ASTRO_CHIP, 862 .parent = TYPE_SYS_BUS_DEVICE, 863 .instance_init = astro_init, 864 .instance_size = sizeof(AstroState), 865 .class_init = astro_class_init, 866 }; 867 868 static void astro_iommu_memory_region_class_init(ObjectClass *klass, 869 void *data) 870 { 871 IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); 872 873 imrc->translate = astro_translate_iommu; 874 } 875 876 static const TypeInfo astro_iommu_memory_region_info = { 877 .parent = TYPE_IOMMU_MEMORY_REGION, 878 .name = TYPE_ASTRO_IOMMU_MEMORY_REGION, 879 .class_init = astro_iommu_memory_region_class_init, 880 }; 881 882 883 static void astro_register_types(void) 884 { 885 type_register_static(&astro_chip_info); 886 type_register_static(&astro_iommu_memory_region_info); 887 } 888 889 type_init(astro_register_types) 890