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
6 * (C) 2023 by Helge Deller <deller@gmx.de>
8 * This work is licensed under the GNU GPL license version 2 or later.
10 * Chip documentation is available at:
11 * https://parisc.wiki.kernel.org/index.php/Technical_Documentation
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
20 #define TYPE_ASTRO_IOMMU_MEMORY_REGION "astro-iommu-memory-region"
22 #define F_EXTEND(addr) ((addr) | MAKE_64BIT_MASK(32, 32))
24 #include "qemu/osdep.h"
25 #include "qemu/module.h"
26 #include "qemu/units.h"
27 #include "qapi/error.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"
37 #include "qom/object.h"
43 static uint64_t mask_32bit_val(hwaddr addr
, unsigned size
, uint64_t val
)
56 static void put_val_in_int64(uint64_t *p
, hwaddr addr
, unsigned size
,
61 } else if (size
== 4) {
63 *p
= ((*p
<< 32) >> 32) | (val
<< 32);
65 *p
= ((*p
>> 32) << 32) | (uint32_t) val
;
70 static void put_val_in_arrary(uint64_t *array
, hwaddr start_addr
,
71 hwaddr addr
, unsigned size
, uint64_t val
)
75 index
= (addr
- start_addr
) / 8;
76 put_val_in_int64(&array
[index
], addr
, size
, val
);
81 * The Elroy PCI host bridge. We have at least 4 of those under Astro.
84 static MemTxResult
elroy_chip_read_with_attrs(void *opaque
, hwaddr addr
,
85 uint64_t *data
, unsigned size
,
88 MemTxResult ret
= MEMTX_OK
;
89 ElroyState
*s
= opaque
;
93 switch ((addr
>> 3) << 3) {
95 val
= 0x6000005; /* func_class */
99 * Scratch register, but firmware initializes it with the
100 * PCI BUS number and Linux/HP-UX uses it then.
102 val
= s
->pci_bus_num
;
103 /* Upper byte holds the end of this bus number */
104 val
|= s
->pci_bus_num
<< 8;
107 val
= s
->arb_mask
; /* set ARB mask */
110 val
= s
->status_control
;
112 case 0x200 ... 0x250 - 1: /* LMMIO, GMMIO, WLMMIO, WGMMIO, ... */
113 index
= (addr
- 0x200) / 8;
114 val
= s
->mmio_base
[index
];
117 val
= s
->error_config
;
120 val
= 0; /* ERROR_STATUS */
122 case 0x0800: /* IOSAPIC_REG_SELECT */
123 val
= s
->iosapic_reg_select
;
126 val
= UINT64_MAX
; /* XXX: tbc. */
127 g_assert_not_reached();
129 case 0x0810: /* IOSAPIC_REG_WINDOW */
130 switch (s
->iosapic_reg_select
) {
131 case 0x01: /* IOSAPIC_REG_VERSION */
132 val
= (32 << 16) | 1; /* upper 16bit holds max entries */
135 if (s
->iosapic_reg_select
< ARRAY_SIZE(s
->iosapic_reg
)) {
136 val
= s
->iosapic_reg
[s
->iosapic_reg_select
];
138 trace_iosapic_reg_read(s
->iosapic_reg_select
, size
, val
);
139 g_assert_not_reached();
142 trace_iosapic_reg_read(s
->iosapic_reg_select
, size
, val
);
145 trace_elroy_read(addr
, size
, val
);
146 g_assert_not_reached();
148 trace_elroy_read(addr
, size
, val
);
150 /* for 32-bit accesses mask return value */
151 val
= mask_32bit_val(addr
, size
, val
);
153 trace_astro_chip_read(addr
, size
, val
);
159 static MemTxResult
elroy_chip_write_with_attrs(void *opaque
, hwaddr addr
,
160 uint64_t val
, unsigned size
,
163 ElroyState
*s
= opaque
;
166 trace_elroy_write(addr
, size
, val
);
168 switch ((addr
>> 3) << 3) {
169 case 0x000: /* PCI_ID & PCI_COMMAND_STATUS_REG */
172 put_val_in_int64(&s
->arb_mask
, addr
, size
, val
);
175 put_val_in_int64(&s
->status_control
, addr
, size
, val
);
177 case 0x200 ... 0x250 - 1: /* LMMIO, GMMIO, WLMMIO, WGMMIO, ... */
178 put_val_in_arrary(s
->mmio_base
, 0x200, addr
, size
, val
);
180 case 0x300: /* ibase */
181 case 0x308: /* imask */
184 put_val_in_int64(&s
->error_config
, addr
, size
, val
);
186 case 0x0800: /* IOSAPIC_REG_SELECT */
187 s
->iosapic_reg_select
= val
;
189 case 0x0810: /* IOSAPIC_REG_WINDOW */
190 trace_iosapic_reg_write(s
->iosapic_reg_select
, size
, val
);
191 if (s
->iosapic_reg_select
< ARRAY_SIZE(s
->iosapic_reg
)) {
192 s
->iosapic_reg
[s
->iosapic_reg_select
] = val
;
194 g_assert_not_reached();
197 case 0x0840: /* IOSAPIC_REG_EOI */
198 val
= le64_to_cpu(val
);
200 for (i
= 0; i
< ELROY_IRQS
; i
++) {
201 if ((s
->iosapic_reg
[0x10 + 2 * i
] & 63) == val
) {
202 s
->ilr
&= ~(1ull << i
);
207 g_assert_not_reached();
212 static const MemoryRegionOps elroy_chip_ops
= {
213 .read_with_attrs
= elroy_chip_read_with_attrs
,
214 .write_with_attrs
= elroy_chip_write_with_attrs
,
215 .endianness
= DEVICE_LITTLE_ENDIAN
,
217 .min_access_size
= 4,
218 .max_access_size
= 8,
221 .min_access_size
= 4,
222 .max_access_size
= 8,
227 /* Unlike pci_config_data_le_ops, no check of high bit set in config_reg. */
229 static uint64_t elroy_config_data_read(void *opaque
, hwaddr addr
, unsigned len
)
233 PCIHostState
*s
= opaque
;
234 val
= pci_data_read(s
->bus
, s
->config_reg
| (addr
& 3), len
);
235 trace_elroy_pci_config_data_read(s
->config_reg
| (addr
& 3), len
, val
);
239 static void elroy_config_data_write(void *opaque
, hwaddr addr
,
240 uint64_t val
, unsigned len
)
242 PCIHostState
*s
= opaque
;
243 pci_data_write(s
->bus
, s
->config_reg
| (addr
& 3), val
, len
);
244 trace_elroy_pci_config_data_write(s
->config_reg
| (addr
& 3), len
, val
);
247 static const MemoryRegionOps elroy_config_data_ops
= {
248 .read
= elroy_config_data_read
,
249 .write
= elroy_config_data_write
,
250 .endianness
= DEVICE_LITTLE_ENDIAN
,
253 static uint64_t elroy_config_addr_read(void *opaque
, hwaddr addr
, unsigned len
)
255 ElroyState
*s
= opaque
;
256 return s
->config_reg_elroy
;
259 static void elroy_config_addr_write(void *opaque
, hwaddr addr
,
260 uint64_t val
, unsigned len
)
262 PCIHostState
*s
= opaque
;
263 ElroyState
*es
= opaque
;
264 es
->config_reg_elroy
= val
; /* keep a copy of original value */
268 static const MemoryRegionOps elroy_config_addr_ops
= {
269 .read
= elroy_config_addr_read
,
270 .write
= elroy_config_addr_write
,
271 .valid
.min_access_size
= 4,
272 .valid
.max_access_size
= 8,
273 .endianness
= DEVICE_LITTLE_ENDIAN
,
277 /* Handle PCI-to-system address translation. */
278 static IOMMUTLBEntry
astro_translate_iommu(IOMMUMemoryRegion
*iommu
,
280 IOMMUAccessFlags flag
,
283 AstroState
*s
= container_of(iommu
, AstroState
, iommu
);
284 hwaddr pdir_ptr
, index
, ibase
;
285 hwaddr addr_mask
= 0xfff; /* 4k translation */
288 #define IOVP_SHIFT 12 /* equals PAGE_SHIFT */
289 #define PDIR_INDEX(iovp) ((iovp) >> IOVP_SHIFT)
290 #define SBA_PDIR_VALID_BIT 0x8000000000000000ULL
295 * Default translation: "32-bit PCI Addressing on 40-bit Runway".
296 * For addresses in the 32-bit memory address range ... and then
297 * language which not-coincidentally matches the PSW.W=0 mapping.
299 if (addr
<= UINT32_MAX
) {
300 entry
= hppa_abs_to_phys_pa2_w0(addr
);
305 /* "range enable" flag cleared? */
306 if ((s
->tlb_ibase
& 1) == 0) {
310 ibase
= s
->tlb_ibase
& ~1ULL;
311 if ((addr
& s
->tlb_imask
) != ibase
) {
312 /* do not translate this one! */
316 index
= PDIR_INDEX(addr
);
317 pdir_ptr
= s
->tlb_pdir_base
+ index
* sizeof(entry
);
318 entry
= ldq_le_phys(&address_space_memory
, pdir_ptr
);
320 if (!(entry
& SBA_PDIR_VALID_BIT
)) { /* I/O PDIR entry valid ? */
322 return (IOMMUTLBEntry
) { .perm
= IOMMU_NONE
};
325 entry
&= ~SBA_PDIR_VALID_BIT
;
326 entry
>>= IOVP_SHIFT
;
330 return (IOMMUTLBEntry
) {
331 .target_as
= &address_space_memory
,
333 .translated_addr
= entry
,
334 .addr_mask
= addr_mask
,
339 static AddressSpace
*elroy_pcihost_set_iommu(PCIBus
*bus
, void *opaque
,
342 ElroyState
*s
= opaque
;
343 return &s
->astro
->iommu_as
;
346 static const PCIIOMMUOps elroy_pcihost_iommu_ops
= {
347 .get_address_space
= elroy_pcihost_set_iommu
,
351 * Encoding in IOSAPIC:
352 * base_addr == 0xfffa0000, we want to get 0xa0ff0000.
353 * eid 0x0ff00000 -> 0x00ff0000
354 * id 0x000ff000 -> 0xff000000
356 #define SWIZZLE_HPA(a) \
357 ((((a) & 0x0ff00000) >> 4) | (((a) & 0x000ff000) << 12))
358 #define UNSWIZZLE_HPA(a) \
359 (((((a) << 4) & 0x0ff00000) | (((a) >> 12) & 0x000ff000) | 0xf0000000))
361 /* bits in the "low" I/O Sapic IRdT entry */
362 #define IOSAPIC_IRDT_DISABLE 0x10000 /* if bit is set, mask this irq */
363 #define IOSAPIC_IRDT_PO_LOW 0x02000
364 #define IOSAPIC_IRDT_LEVEL_TRIG 0x08000
365 #define IOSAPIC_IRDT_MODE_LPRI 0x00100
367 #define CPU_IRQ_OFFSET 2
369 static void elroy_set_irq(void *opaque
, int irq
, int level
)
371 ElroyState
*s
= opaque
;
373 uint32_t old_ilr
= s
->ilr
;
377 val
= s
->iosapic_reg
[0x10 + 2 * irq
];
378 cpu_hpa
= s
->iosapic_reg
[0x11 + 2 * irq
];
379 /* low nibble of val has value to write into CPU irq reg */
380 bit
= 1u << (val
& (ELROY_IRQS
- 1));
381 cpu_hpa
= UNSWIZZLE_HPA(cpu_hpa
);
383 if (level
&& (!(val
& IOSAPIC_IRDT_DISABLE
)) && cpu_hpa
) {
384 uint32_t ena
= bit
& ~old_ilr
;
385 s
->ilr
= old_ilr
| bit
;
387 stl_be_phys(&address_space_memory
, F_EXTEND(cpu_hpa
), val
& 63);
390 s
->ilr
= old_ilr
& ~bit
;
394 static int elroy_pci_map_irq(PCIDevice
*d
, int irq_num
)
396 int slot
= PCI_SLOT(d
->devfn
);
398 assert(irq_num
>= 0 && irq_num
< ELROY_IRQS
);
399 return slot
& (ELROY_IRQS
- 1);
402 static void elroy_reset(DeviceState
*dev
)
404 ElroyState
*s
= ELROY_PCI_HOST_BRIDGE(dev
);
408 * Make sure to disable interrupts at reboot, otherwise the Linux kernel
409 * serial8250_config_port() in drivers/tty/serial/8250/8250_port.c
410 * will hang during autoconfig().
413 for (irq
= 0; irq
< ELROY_IRQS
; irq
++) {
414 s
->iosapic_reg
[0x10 + 2 * irq
] = IOSAPIC_IRDT_PO_LOW
|
415 IOSAPIC_IRDT_LEVEL_TRIG
| (irq
+ CPU_IRQ_OFFSET
) |
416 IOSAPIC_IRDT_DISABLE
;
417 s
->iosapic_reg
[0x11 + 2 * irq
] = SWIZZLE_HPA(CPU_HPA
);
421 static void elroy_pcihost_init(Object
*obj
)
423 ElroyState
*s
= ELROY_PCI_HOST_BRIDGE(obj
);
424 PCIHostState
*phb
= PCI_HOST_BRIDGE(obj
);
425 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
427 /* Elroy config access from CPU. */
428 memory_region_init_io(&s
->this_mem
, OBJECT(s
), &elroy_chip_ops
,
431 /* Elroy PCI config. */
432 memory_region_init_io(&phb
->conf_mem
, OBJECT(phb
),
433 &elroy_config_addr_ops
, DEVICE(s
),
435 memory_region_init_io(&phb
->data_mem
, OBJECT(phb
),
436 &elroy_config_data_ops
, DEVICE(s
),
438 memory_region_add_subregion(&s
->this_mem
, 0x40,
440 memory_region_add_subregion(&s
->this_mem
, 0x48,
443 /* Elroy PCI bus memory. */
444 memory_region_init(&s
->pci_mmio
, OBJECT(s
), "pci-mmio", UINT64_MAX
);
445 memory_region_init_io(&s
->pci_io
, OBJECT(s
), &unassigned_io_ops
, obj
,
447 ((uint32_t) IOS_DIST_BASE_SIZE
) / ROPES_PER_IOC
);
449 phb
->bus
= pci_register_root_bus(DEVICE(s
), "pci",
450 elroy_set_irq
, elroy_pci_map_irq
, s
,
451 &s
->pci_mmio
, &s
->pci_io
,
452 PCI_DEVFN(0, 0), ELROY_IRQS
, TYPE_PCI_BUS
);
454 sysbus_init_mmio(sbd
, &s
->this_mem
);
456 qdev_init_gpio_in(DEVICE(obj
), elroy_set_irq
, ELROY_IRQS
);
459 static Property elroy_pcihost_properties
[] = {
460 DEFINE_PROP_END_OF_LIST(),
463 static const VMStateDescription vmstate_elroy
= {
466 .minimum_version_id
= 1,
467 .fields
= (const VMStateField
[]) {
468 VMSTATE_UINT64(hpa
, ElroyState
),
469 VMSTATE_UINT32(pci_bus_num
, ElroyState
),
470 VMSTATE_UINT64(config_address
, ElroyState
),
471 VMSTATE_UINT64(config_reg_elroy
, ElroyState
),
472 VMSTATE_UINT64(status_control
, ElroyState
),
473 VMSTATE_UINT64(arb_mask
, ElroyState
),
474 VMSTATE_UINT64_ARRAY(mmio_base
, ElroyState
, (0x0250 - 0x200) / 8),
475 VMSTATE_UINT64(error_config
, ElroyState
),
476 VMSTATE_UINT32(iosapic_reg_select
, ElroyState
),
477 VMSTATE_UINT64_ARRAY(iosapic_reg
, ElroyState
, 0x20),
478 VMSTATE_UINT32(ilr
, ElroyState
),
479 VMSTATE_END_OF_LIST()
483 static void elroy_pcihost_class_init(ObjectClass
*klass
, void *data
)
485 DeviceClass
*dc
= DEVICE_CLASS(klass
);
487 dc
->reset
= elroy_reset
;
488 device_class_set_props(dc
, elroy_pcihost_properties
);
489 dc
->vmsd
= &vmstate_elroy
;
490 dc
->user_creatable
= false;
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
,
501 static void elroy_register_types(void)
503 type_register_static(&elroy_pcihost_info
);
506 type_init(elroy_register_types
)
509 static ElroyState
*elroy_init(int num
)
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
);
517 return ELROY_PCI_HOST_BRIDGE(dev
);
524 static MemTxResult
astro_chip_read_with_attrs(void *opaque
, hwaddr addr
,
525 uint64_t *data
, unsigned size
,
528 AstroState
*s
= opaque
;
529 MemTxResult ret
= MEMTX_OK
;
533 switch ((addr
>> 3) << 3) {
535 case 0x0000: /* ID */
536 val
= (0x01 << 3) | 0x01ULL
;
538 case 0x0008: /* IOC_CTRL */
541 case 0x0010: /* TOC_CLIENT_ID */
543 case 0x0030: /* HP-UX 10.20 and 11.11 reads it. No idea. */
546 case 0x0078: /* NetBSD reads 0x78 ? */
549 case 0x0300 ... 0x03d8: /* LMMIO_DIRECT0_BASE... */
550 index
= (addr
- 0x300) / 8;
551 val
= s
->ioc_ranges
[index
];
557 case 0x10230: /* HP-UX 11.11 reads it. No idea. */
560 case 0x22108: /* IOC STATUS_CONTROL */
561 val
= s
->ioc_status_ctrl
;
563 case 0x20200 ... 0x20240 - 1: /* IOC Rope0_Control ... */
564 index
= (addr
- 0x20200) / 8;
565 val
= s
->ioc_rope_control
[index
];
567 case 0x20040: /* IOC Rope config */
568 val
= s
->ioc_rope_config
;
570 case 0x20050: /* IOC Rope debug */
573 case 0x20108: /* IOC STATUS_CONTROL */
574 val
= s
->ioc_status_control
;
576 case 0x20310: /* IOC_PCOM */
578 /* TODO: flush iommu */
581 val
= s
->ioc_flush_control
;
583 /* empty placeholders for non-existent elroys */
584 #define EMPTY_PORT(x) case x: case x+8: val = 0; break; \
585 case x+40: case x+48: val = UINT64_MAX; break;
597 trace_astro_chip_read(addr
, size
, val
);
598 g_assert_not_reached();
601 /* for 32-bit accesses mask return value */
602 val
= mask_32bit_val(addr
, size
, val
);
604 trace_astro_chip_read(addr
, size
, val
);
609 static MemTxResult
astro_chip_write_with_attrs(void *opaque
, hwaddr addr
,
610 uint64_t val
, unsigned size
,
613 AstroState
*s
= opaque
;
615 trace_astro_chip_write(addr
, size
, val
);
617 switch ((addr
>> 3) << 3) {
618 case 0x0000: /* ID */
620 case 0x0008: /* IOC_CTRL */
622 put_val_in_int64(&s
->ioc_ctrl
, addr
, size
, val
);
624 case 0x0010: /* TOC_CLIENT_ID */
626 case 0x0030: /* HP-UX 10.20 and 11.11 reads it. No idea. */
628 case 0x0300 ... 0x03d8 - 1: /* LMMIO_DIRECT0_BASE... */
629 put_val_in_arrary(s
->ioc_ranges
, 0x300, addr
, size
, val
);
633 case 0x10230: /* HP-UX 11.11 reads it. No idea. */
635 case 0x20200 ... 0x20240 - 1: /* IOC Rope0_Control ... */
636 put_val_in_arrary(s
->ioc_rope_control
, 0x20200, addr
, size
, val
);
638 case 0x20040: /* IOC Rope config */
640 put_val_in_int64(&s
->ioc_rope_config
, addr
, size
, val
);
644 put_val_in_int64(&s
->tlb_ibase
, addr
, size
, val
);
648 put_val_in_int64(&s
->tlb_imask
, addr
, size
, val
);
652 put_val_in_int64(&s
->tlb_pcom
, addr
, size
, val
);
653 /* TODO: flush iommu */
657 put_val_in_int64(&s
->tlb_tcnfg
, addr
, size
, val
);
661 put_val_in_int64(&s
->tlb_pdir_base
, addr
, size
, val
);
663 case 0x22000: /* func_id */
665 case 0x22008: /* func_class */
667 case 0x22050: /* rope_debug */
669 case 0x22108: /* IOC STATUS_CONTROL */
670 put_val_in_int64(&s
->ioc_status_ctrl
, addr
, size
, val
);
673 * empty placeholders for non-existent elroys, e.g.
674 * func_class, pci config & data
676 #define EMPTY_PORT(x) case x: case x+8: case x+0x40: case x+0x48:
689 /* Controlled by astro_chip_mem_valid above. */
690 trace_astro_chip_write(addr
, size
, val
);
691 g_assert_not_reached();
696 static const MemoryRegionOps astro_chip_ops
= {
697 .read_with_attrs
= astro_chip_read_with_attrs
,
698 .write_with_attrs
= astro_chip_write_with_attrs
,
699 .endianness
= DEVICE_LITTLE_ENDIAN
,
701 .min_access_size
= 4,
702 .max_access_size
= 8,
705 .min_access_size
= 4,
706 .max_access_size
= 8,
710 static const VMStateDescription vmstate_astro
= {
713 .minimum_version_id
= 1,
714 .fields
= (const VMStateField
[]) {
715 VMSTATE_UINT64(ioc_ctrl
, AstroState
),
716 VMSTATE_UINT64(ioc_status_ctrl
, AstroState
),
717 VMSTATE_UINT64_ARRAY(ioc_ranges
, AstroState
, (0x03d8 - 0x300) / 8),
718 VMSTATE_UINT64(ioc_rope_config
, AstroState
),
719 VMSTATE_UINT64(ioc_status_control
, AstroState
),
720 VMSTATE_UINT64(ioc_flush_control
, AstroState
),
721 VMSTATE_UINT64_ARRAY(ioc_rope_control
, AstroState
, 8),
722 VMSTATE_UINT64(tlb_ibase
, AstroState
),
723 VMSTATE_UINT64(tlb_imask
, AstroState
),
724 VMSTATE_UINT64(tlb_pcom
, AstroState
),
725 VMSTATE_UINT64(tlb_tcnfg
, AstroState
),
726 VMSTATE_UINT64(tlb_pdir_base
, AstroState
),
727 VMSTATE_END_OF_LIST()
731 static void astro_reset(DeviceState
*dev
)
733 AstroState
*s
= ASTRO_CHIP(dev
);
736 s
->ioc_ctrl
= 0x29cf;
737 s
->ioc_rope_config
= 0xc5f;
738 s
->ioc_flush_control
= 0xb03;
739 s
->ioc_status_control
= 0;
740 memset(&s
->ioc_rope_control
, 0, sizeof(s
->ioc_rope_control
));
743 * The SBA BASE/MASK registers control CPU -> IO routing.
744 * The LBA BASE/MASK registers control IO -> System routing (in Elroy)
746 memset(&s
->ioc_ranges
, 0, sizeof(s
->ioc_ranges
));
747 s
->ioc_ranges
[(0x360 - 0x300) / 8] = LMMIO_DIST_BASE_ADDR
| 0x01; /* LMMIO_DIST_BASE (SBA) */
748 s
->ioc_ranges
[(0x368 - 0x300) / 8] = 0xfc000000; /* LMMIO_DIST_MASK */
749 s
->ioc_ranges
[(0x370 - 0x300) / 8] = 0; /* LMMIO_DIST_ROUTE */
750 s
->ioc_ranges
[(0x390 - 0x300) / 8] = IOS_DIST_BASE_ADDR
| 0x01; /* IOS_DIST_BASE */
751 s
->ioc_ranges
[(0x398 - 0x300) / 8] = 0xffffff0000; /* IOS_DIST_MASK */
752 s
->ioc_ranges
[(0x3a0 - 0x300) / 8] = 0x3400000000000000ULL
; /* IOS_DIST_ROUTE */
753 s
->ioc_ranges
[(0x3c0 - 0x300) / 8] = 0xfffee00000; /* IOS_DIRECT_BASE */
754 s
->ioc_ranges
[(0x3c8 - 0x300) / 8] = 0xffffff0000; /* IOS_DIRECT_MASK */
755 s
->ioc_ranges
[(0x3d0 - 0x300) / 8] = 0x0; /* IOS_DIRECT_ROUTE */
761 s
->tlb_pdir_base
= 0;
763 for (i
= 0; i
< ELROY_NUM
; i
++) {
764 elroy_reset(DEVICE(s
->elroy
[i
]));
768 static void astro_init(Object
*obj
)
772 static void astro_realize(DeviceState
*obj
, Error
**errp
)
774 AstroState
*s
= ASTRO_CHIP(obj
);
775 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
778 memory_region_init_io(&s
->this_mem
, OBJECT(s
), &astro_chip_ops
,
779 s
, "astro", 0x40000);
780 sysbus_init_mmio(sbd
, &s
->this_mem
);
782 /* Host memory as seen from Elroys PCI side, via the IOMMU. */
783 memory_region_init_iommu(&s
->iommu
, sizeof(s
->iommu
),
784 TYPE_ASTRO_IOMMU_MEMORY_REGION
, OBJECT(s
),
785 "iommu-astro", UINT64_MAX
);
786 address_space_init(&s
->iommu_as
, MEMORY_REGION(&s
->iommu
),
789 /* Create Elroys (PCI host bus chips). */
790 for (i
= 0; i
< ELROY_NUM
; i
++) {
791 static const int elroy_hpa_offsets
[ELROY_NUM
] = {
792 0x30000, 0x32000, 0x38000, 0x3c000 };
793 static const char elroy_rope_nr
[ELROY_NUM
] = {
794 0, 1, 4, 6 }; /* busnum path, e.g. [10:6] */
801 addr_offset
= elroy_hpa_offsets
[i
];
802 rope
= elroy_rope_nr
[i
];
804 elroy
= elroy_init(i
);
806 elroy
->hpa
= ASTRO_HPA
+ addr_offset
;
807 elroy
->pci_bus_num
= i
;
811 * NOTE: we only allow PCI devices on first Elroy for now.
812 * SeaBIOS will not find devices on the other busses.
815 qbus_mark_full(&PCI_HOST_BRIDGE(elroy
)->bus
->qbus
);
818 /* map elroy config addresses into Astro space */
819 memory_region_add_subregion(&s
->this_mem
, addr_offset
,
823 elroy
->mmio_base
[(0x0200 - 0x200) / 8] = 0xf0000001;
824 elroy
->mmio_base
[(0x0208 - 0x200) / 8] = 0xf8000000;
826 elroy
->mmio_base
[(0x0210 - 0x200) / 8] = 0x000000f800000001;
827 elroy
->mmio_base
[(0x0218 - 0x200) / 8] = 0x000000ff80000000;
829 elroy
->mmio_base
[(0x0220 - 0x200) / 8] = 0xf0000001;
830 elroy
->mmio_base
[(0x0228 - 0x200) / 8] = 0xf0000000;
832 elroy
->mmio_base
[(0x0230 - 0x200) / 8] = 0x000000f800000001;
833 elroy
->mmio_base
[(0x0238 - 0x200) / 8] = 0x000000fc00000000;
835 map_size
= IOS_DIST_BASE_SIZE
/ ROPES_PER_IOC
;
836 elroy
->mmio_base
[(0x0240 - 0x200) / 8] = rope
* map_size
| 0x01;
837 elroy
->mmio_base
[(0x0248 - 0x200) / 8] = 0x0000e000;
839 /* map elroys mmio */
840 map_size
= LMMIO_DIST_BASE_SIZE
/ ROPES_PER_IOC
;
841 map_addr
= F_EXTEND(LMMIO_DIST_BASE_ADDR
+ rope
* map_size
);
842 memory_region_init_alias(&elroy
->pci_mmio_alias
, OBJECT(elroy
),
844 &elroy
->pci_mmio
, (uint32_t) map_addr
, map_size
);
845 memory_region_add_subregion(get_system_memory(), map_addr
,
846 &elroy
->pci_mmio_alias
);
849 map_size
= IOS_DIST_BASE_SIZE
/ ROPES_PER_IOC
;
850 map_addr
= F_EXTEND(IOS_DIST_BASE_ADDR
+ rope
* map_size
);
851 memory_region_add_subregion(get_system_memory(), map_addr
,
854 /* Host memory as seen from the PCI side, via the IOMMU. */
855 pci_setup_iommu(PCI_HOST_BRIDGE(elroy
)->bus
, &elroy_pcihost_iommu_ops
,
860 static void astro_class_init(ObjectClass
*klass
, void *data
)
862 DeviceClass
*dc
= DEVICE_CLASS(klass
);
864 dc
->reset
= astro_reset
;
865 dc
->vmsd
= &vmstate_astro
;
866 dc
->realize
= astro_realize
;
868 * astro with elroys are hard part of the newer PA2.0 machines and can not
869 * be created without that hardware
871 dc
->user_creatable
= false;
874 static const TypeInfo astro_chip_info
= {
875 .name
= TYPE_ASTRO_CHIP
,
876 .parent
= TYPE_SYS_BUS_DEVICE
,
877 .instance_init
= astro_init
,
878 .instance_size
= sizeof(AstroState
),
879 .class_init
= astro_class_init
,
882 static void astro_iommu_memory_region_class_init(ObjectClass
*klass
,
885 IOMMUMemoryRegionClass
*imrc
= IOMMU_MEMORY_REGION_CLASS(klass
);
887 imrc
->translate
= astro_translate_iommu
;
890 static const TypeInfo astro_iommu_memory_region_info
= {
891 .parent
= TYPE_IOMMU_MEMORY_REGION
,
892 .name
= TYPE_ASTRO_IOMMU_MEMORY_REGION
,
893 .class_init
= astro_iommu_memory_region_class_init
,
897 static void astro_register_types(void)
899 type_register_static(&astro_chip_info
);
900 type_register_static(&astro_iommu_memory_region_info
);
903 type_init(astro_register_types
)