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