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