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