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