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