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