diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2013-02-05 15:06:20 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-04-08 18:13:14 +0200 |
commit | c0907c9e6417cb959dfd9ef6873221536ec91351 (patch) | |
tree | cc8df9eea467139d4cbc961cf34d357f618d0e9e /hw/alpha_typhoon.c | |
parent | 8ac5c6510b609c123d6b394b2de16462ac7c395f (diff) |
hw: move PCI bridges to hw/pci-* or hw/ARCH
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/alpha_typhoon.c')
-rw-r--r-- | hw/alpha_typhoon.c | 842 |
1 files changed, 0 insertions, 842 deletions
diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c deleted file mode 100644 index 41a0ebc7a3..0000000000 --- a/hw/alpha_typhoon.c +++ /dev/null @@ -1,842 +0,0 @@ -/* - * DEC 21272 (TSUNAMI/TYPHOON) chipset emulation. - * - * Written by Richard Henderson. - * - * This work is licensed under the GNU GPL license version 2 or later. - */ - -#include "cpu.h" -#include "exec/exec-all.h" -#include "hw/hw.h" -#include "hw/arm/devices.h" -#include "sysemu/sysemu.h" -#include "hw/alpha_sys.h" -#include "exec/address-spaces.h" - - -#define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost" - -typedef struct TyphoonCchip { - MemoryRegion region; - uint64_t misc; - uint64_t drir; - uint64_t dim[4]; - uint32_t iic[4]; - AlphaCPU *cpu[4]; -} TyphoonCchip; - -typedef struct TyphoonWindow { - uint32_t base_addr; - uint32_t mask; - uint32_t translated_base_pfn; -} TyphoonWindow; - -typedef struct TyphoonPchip { - MemoryRegion region; - MemoryRegion reg_iack; - MemoryRegion reg_mem; - MemoryRegion reg_io; - MemoryRegion reg_conf; - uint64_t ctl; - TyphoonWindow win[4]; -} TyphoonPchip; - -#define TYPHOON_PCI_HOST_BRIDGE(obj) \ - OBJECT_CHECK(TyphoonState, (obj), TYPE_TYPHOON_PCI_HOST_BRIDGE) - -typedef struct TyphoonState { - PCIHostState parent_obj; - - TyphoonCchip cchip; - TyphoonPchip pchip; - MemoryRegion dchip_region; - MemoryRegion ram_region; - - /* QEMU emulation state. */ - uint32_t latch_tmp; -} TyphoonState; - -/* Called when one of DRIR or DIM changes. */ -static void cpu_irq_change(AlphaCPU *cpu, uint64_t req) -{ - /* If there are any non-masked interrupts, tell the cpu. */ - if (cpu != NULL) { - CPUState *cs = CPU(cpu); - if (req) { - cpu_interrupt(cs, CPU_INTERRUPT_HARD); - } else { - cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); - } - } -} - -static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size) -{ - CPUAlphaState *env = cpu_single_env; - TyphoonState *s = opaque; - CPUState *cpu; - uint64_t ret = 0; - - if (addr & 4) { - return s->latch_tmp; - } - - switch (addr) { - case 0x0000: - /* CSC: Cchip System Configuration Register. */ - /* All sorts of data here; probably the only thing relevant is - PIP<14> Pchip 1 Present = 0. */ - break; - - case 0x0040: - /* MTR: Memory Timing Register. */ - /* All sorts of stuff related to real DRAM. */ - break; - - case 0x0080: - /* MISC: Miscellaneous Register. */ - cpu = ENV_GET_CPU(env); - ret = s->cchip.misc | (cpu->cpu_index & 3); - break; - - case 0x00c0: - /* MPD: Memory Presence Detect Register. */ - break; - - case 0x0100: /* AAR0 */ - case 0x0140: /* AAR1 */ - case 0x0180: /* AAR2 */ - case 0x01c0: /* AAR3 */ - /* AAR: Array Address Register. */ - /* All sorts of information about DRAM. */ - break; - - case 0x0200: - /* DIM0: Device Interrupt Mask Register, CPU0. */ - ret = s->cchip.dim[0]; - break; - case 0x0240: - /* DIM1: Device Interrupt Mask Register, CPU1. */ - ret = s->cchip.dim[1]; - break; - case 0x0280: - /* DIR0: Device Interrupt Request Register, CPU0. */ - ret = s->cchip.dim[0] & s->cchip.drir; - break; - case 0x02c0: - /* DIR1: Device Interrupt Request Register, CPU1. */ - ret = s->cchip.dim[1] & s->cchip.drir; - break; - case 0x0300: - /* DRIR: Device Raw Interrupt Request Register. */ - ret = s->cchip.drir; - break; - - case 0x0340: - /* PRBEN: Probe Enable Register. */ - break; - - case 0x0380: - /* IIC0: Interval Ignore Count Register, CPU0. */ - ret = s->cchip.iic[0]; - break; - case 0x03c0: - /* IIC1: Interval Ignore Count Register, CPU1. */ - ret = s->cchip.iic[1]; - break; - - case 0x0400: /* MPR0 */ - case 0x0440: /* MPR1 */ - case 0x0480: /* MPR2 */ - case 0x04c0: /* MPR3 */ - /* MPR: Memory Programming Register. */ - break; - - case 0x0580: - /* TTR: TIGbus Timing Register. */ - /* All sorts of stuff related to interrupt delivery timings. */ - break; - case 0x05c0: - /* TDR: TIGbug Device Timing Register. */ - break; - - case 0x0600: - /* DIM2: Device Interrupt Mask Register, CPU2. */ - ret = s->cchip.dim[2]; - break; - case 0x0640: - /* DIM3: Device Interrupt Mask Register, CPU3. */ - ret = s->cchip.dim[3]; - break; - case 0x0680: - /* DIR2: Device Interrupt Request Register, CPU2. */ - ret = s->cchip.dim[2] & s->cchip.drir; - break; - case 0x06c0: - /* DIR3: Device Interrupt Request Register, CPU3. */ - ret = s->cchip.dim[3] & s->cchip.drir; - break; - - case 0x0700: - /* IIC2: Interval Ignore Count Register, CPU2. */ - ret = s->cchip.iic[2]; - break; - case 0x0740: - /* IIC3: Interval Ignore Count Register, CPU3. */ - ret = s->cchip.iic[3]; - break; - - case 0x0780: - /* PWR: Power Management Control. */ - break; - - case 0x0c00: /* CMONCTLA */ - case 0x0c40: /* CMONCTLB */ - case 0x0c80: /* CMONCNT01 */ - case 0x0cc0: /* CMONCNT23 */ - break; - - default: - cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size); - return -1; - } - - s->latch_tmp = ret >> 32; - return ret; -} - -static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size) -{ - /* Skip this. It's all related to DRAM timing and setup. */ - return 0; -} - -static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size) -{ - TyphoonState *s = opaque; - uint64_t ret = 0; - - if (addr & 4) { - return s->latch_tmp; - } - - switch (addr) { - case 0x0000: - /* WSBA0: Window Space Base Address Register. */ - ret = s->pchip.win[0].base_addr; - break; - case 0x0040: - /* WSBA1 */ - ret = s->pchip.win[1].base_addr; - break; - case 0x0080: - /* WSBA2 */ - ret = s->pchip.win[2].base_addr; - break; - case 0x00c0: - /* WSBA3 */ - ret = s->pchip.win[3].base_addr; - break; - - case 0x0100: - /* WSM0: Window Space Mask Register. */ - ret = s->pchip.win[0].mask; - break; - case 0x0140: - /* WSM1 */ - ret = s->pchip.win[1].mask; - break; - case 0x0180: - /* WSM2 */ - ret = s->pchip.win[2].mask; - break; - case 0x01c0: - /* WSM3 */ - ret = s->pchip.win[3].mask; - break; - - case 0x0200: - /* TBA0: Translated Base Address Register. */ - ret = (uint64_t)s->pchip.win[0].translated_base_pfn << 10; - break; - case 0x0240: - /* TBA1 */ - ret = (uint64_t)s->pchip.win[1].translated_base_pfn << 10; - break; - case 0x0280: - /* TBA2 */ - ret = (uint64_t)s->pchip.win[2].translated_base_pfn << 10; - break; - case 0x02c0: - /* TBA3 */ - ret = (uint64_t)s->pchip.win[3].translated_base_pfn << 10; - break; - - case 0x0300: - /* PCTL: Pchip Control Register. */ - ret = s->pchip.ctl; - break; - case 0x0340: - /* PLAT: Pchip Master Latency Register. */ - break; - case 0x03c0: - /* PERROR: Pchip Error Register. */ - break; - case 0x0400: - /* PERRMASK: Pchip Error Mask Register. */ - break; - case 0x0440: - /* PERRSET: Pchip Error Set Register. */ - break; - case 0x0480: - /* TLBIV: Translation Buffer Invalidate Virtual Register (WO). */ - break; - case 0x04c0: - /* TLBIA: Translation Buffer Invalidate All Register (WO). */ - break; - case 0x0500: /* PMONCTL */ - case 0x0540: /* PMONCNT */ - case 0x0800: /* SPRST */ - break; - - default: - cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size); - return -1; - } - - s->latch_tmp = ret >> 32; - return ret; -} - -static void cchip_write(void *opaque, hwaddr addr, - uint64_t v32, unsigned size) -{ - TyphoonState *s = opaque; - uint64_t val, oldval, newval; - - if (addr & 4) { - val = v32 << 32 | s->latch_tmp; - addr ^= 4; - } else { - s->latch_tmp = v32; - return; - } - - switch (addr) { - case 0x0000: - /* CSC: Cchip System Configuration Register. */ - /* All sorts of data here; nothing relevant RW. */ - break; - - case 0x0040: - /* MTR: Memory Timing Register. */ - /* All sorts of stuff related to real DRAM. */ - break; - - case 0x0080: - /* MISC: Miscellaneous Register. */ - newval = oldval = s->cchip.misc; - newval &= ~(val & 0x10000ff0); /* W1C fields */ - if (val & 0x100000) { - newval &= ~0xff0000ull; /* ACL clears ABT and ABW */ - } else { - newval |= val & 0x00f00000; /* ABT field is W1S */ - if ((newval & 0xf0000) == 0) { - newval |= val & 0xf0000; /* ABW field is W1S iff zero */ - } - } - newval |= (val & 0xf000) >> 4; /* IPREQ field sets IPINTR. */ - - newval &= ~0xf0000000000ull; /* WO and RW fields */ - newval |= val & 0xf0000000000ull; - s->cchip.misc = newval; - - /* Pass on changes to IPI and ITI state. */ - if ((newval ^ oldval) & 0xff0) { - int i; - for (i = 0; i < 4; ++i) { - AlphaCPU *cpu = s->cchip.cpu[i]; - if (cpu != NULL) { - CPUState *cs = CPU(cpu); - /* IPI can be either cleared or set by the write. */ - if (newval & (1 << (i + 8))) { - cpu_interrupt(cs, CPU_INTERRUPT_SMP); - } else { - cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP); - } - - /* ITI can only be cleared by the write. */ - if ((newval & (1 << (i + 4))) == 0) { - cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER); - } - } - } - } - break; - - case 0x00c0: - /* MPD: Memory Presence Detect Register. */ - break; - - case 0x0100: /* AAR0 */ - case 0x0140: /* AAR1 */ - case 0x0180: /* AAR2 */ - case 0x01c0: /* AAR3 */ - /* AAR: Array Address Register. */ - /* All sorts of information about DRAM. */ - break; - - case 0x0200: /* DIM0 */ - /* DIM: Device Interrupt Mask Register, CPU0. */ - s->cchip.dim[0] = val; - cpu_irq_change(s->cchip.cpu[0], val & s->cchip.drir); - break; - case 0x0240: /* DIM1 */ - /* DIM: Device Interrupt Mask Register, CPU1. */ - s->cchip.dim[0] = val; - cpu_irq_change(s->cchip.cpu[1], val & s->cchip.drir); - break; - - case 0x0280: /* DIR0 (RO) */ - case 0x02c0: /* DIR1 (RO) */ - case 0x0300: /* DRIR (RO) */ - break; - - case 0x0340: - /* PRBEN: Probe Enable Register. */ - break; - - case 0x0380: /* IIC0 */ - s->cchip.iic[0] = val & 0xffffff; - break; - case 0x03c0: /* IIC1 */ - s->cchip.iic[1] = val & 0xffffff; - break; - - case 0x0400: /* MPR0 */ - case 0x0440: /* MPR1 */ - case 0x0480: /* MPR2 */ - case 0x04c0: /* MPR3 */ - /* MPR: Memory Programming Register. */ - break; - - case 0x0580: - /* TTR: TIGbus Timing Register. */ - /* All sorts of stuff related to interrupt delivery timings. */ - break; - case 0x05c0: - /* TDR: TIGbug Device Timing Register. */ - break; - - case 0x0600: - /* DIM2: Device Interrupt Mask Register, CPU2. */ - s->cchip.dim[2] = val; - cpu_irq_change(s->cchip.cpu[2], val & s->cchip.drir); - break; - case 0x0640: - /* DIM3: Device Interrupt Mask Register, CPU3. */ - s->cchip.dim[3] = val; - cpu_irq_change(s->cchip.cpu[3], val & s->cchip.drir); - break; - - case 0x0680: /* DIR2 (RO) */ - case 0x06c0: /* DIR3 (RO) */ - break; - - case 0x0700: /* IIC2 */ - s->cchip.iic[2] = val & 0xffffff; - break; - case 0x0740: /* IIC3 */ - s->cchip.iic[3] = val & 0xffffff; - break; - - case 0x0780: - /* PWR: Power Management Control. */ - break; - - case 0x0c00: /* CMONCTLA */ - case 0x0c40: /* CMONCTLB */ - case 0x0c80: /* CMONCNT01 */ - case 0x0cc0: /* CMONCNT23 */ - break; - - default: - cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size); - return; - } -} - -static void dchip_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) -{ - /* Skip this. It's all related to DRAM timing and setup. */ -} - -static void pchip_write(void *opaque, hwaddr addr, - uint64_t v32, unsigned size) -{ - TyphoonState *s = opaque; - uint64_t val, oldval; - - if (addr & 4) { - val = v32 << 32 | s->latch_tmp; - addr ^= 4; - } else { - s->latch_tmp = v32; - return; - } - - switch (addr) { - case 0x0000: - /* WSBA0: Window Space Base Address Register. */ - s->pchip.win[0].base_addr = val; - break; - case 0x0040: - /* WSBA1 */ - s->pchip.win[1].base_addr = val; - break; - case 0x0080: - /* WSBA2 */ - s->pchip.win[2].base_addr = val; - break; - case 0x00c0: - /* WSBA3 */ - s->pchip.win[3].base_addr = val; - break; - - case 0x0100: - /* WSM0: Window Space Mask Register. */ - s->pchip.win[0].mask = val; - break; - case 0x0140: - /* WSM1 */ - s->pchip.win[1].mask = val; - break; - case 0x0180: - /* WSM2 */ - s->pchip.win[2].mask = val; - break; - case 0x01c0: - /* WSM3 */ - s->pchip.win[3].mask = val; - break; - - case 0x0200: - /* TBA0: Translated Base Address Register. */ - s->pchip.win[0].translated_base_pfn = val >> 10; - break; - case 0x0240: - /* TBA1 */ - s->pchip.win[1].translated_base_pfn = val >> 10; - break; - case 0x0280: - /* TBA2 */ - s->pchip.win[2].translated_base_pfn = val >> 10; - break; - case 0x02c0: - /* TBA3 */ - s->pchip.win[3].translated_base_pfn = val >> 10; - break; - - case 0x0300: - /* PCTL: Pchip Control Register. */ - oldval = s->pchip.ctl; - oldval &= ~0x00001cff0fc7ffull; /* RW fields */ - oldval |= val & 0x00001cff0fc7ffull; - - s->pchip.ctl = oldval; - break; - - case 0x0340: - /* PLAT: Pchip Master Latency Register. */ - break; - case 0x03c0: - /* PERROR: Pchip Error Register. */ - break; - case 0x0400: - /* PERRMASK: Pchip Error Mask Register. */ - break; - case 0x0440: - /* PERRSET: Pchip Error Set Register. */ - break; - - case 0x0480: - /* TLBIV: Translation Buffer Invalidate Virtual Register. */ - break; - - case 0x04c0: - /* TLBIA: Translation Buffer Invalidate All Register (WO). */ - break; - - case 0x0500: - /* PMONCTL */ - case 0x0540: - /* PMONCNT */ - case 0x0800: - /* SPRST */ - break; - - default: - cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size); - return; - } -} - -static const MemoryRegionOps cchip_ops = { - .read = cchip_read, - .write = cchip_write, - .endianness = DEVICE_LITTLE_ENDIAN, - .valid = { - .min_access_size = 4, /* ??? Should be 8. */ - .max_access_size = 8, - }, - .impl = { - .min_access_size = 4, - .max_access_size = 4, - }, -}; - -static const MemoryRegionOps dchip_ops = { - .read = dchip_read, - .write = dchip_write, - .endianness = DEVICE_LITTLE_ENDIAN, - .valid = { - .min_access_size = 4, /* ??? Should be 8. */ - .max_access_size = 8, - }, - .impl = { - .min_access_size = 4, - .max_access_size = 8, - }, -}; - -static const MemoryRegionOps pchip_ops = { - .read = pchip_read, - .write = pchip_write, - .endianness = DEVICE_LITTLE_ENDIAN, - .valid = { - .min_access_size = 4, /* ??? Should be 8. */ - .max_access_size = 8, - }, - .impl = { - .min_access_size = 4, - .max_access_size = 4, - }, -}; - -static void typhoon_set_irq(void *opaque, int irq, int level) -{ - TyphoonState *s = opaque; - uint64_t drir; - int i; - - /* Set/Reset the bit in CCHIP.DRIR based on IRQ+LEVEL. */ - drir = s->cchip.drir; - if (level) { - drir |= 1ull << irq; - } else { - drir &= ~(1ull << irq); - } - s->cchip.drir = drir; - - for (i = 0; i < 4; ++i) { - cpu_irq_change(s->cchip.cpu[i], s->cchip.dim[i] & drir); - } -} - -static void typhoon_set_isa_irq(void *opaque, int irq, int level) -{ - typhoon_set_irq(opaque, 55, level); -} - -static void typhoon_set_timer_irq(void *opaque, int irq, int level) -{ - TyphoonState *s = opaque; - int i; - - /* Thankfully, the mc146818rtc code doesn't track the IRQ state, - and so we don't have to worry about missing interrupts just - because we never actually ACK the interrupt. Just ignore any - case of the interrupt level going low. */ - if (level == 0) { - return; - } - - /* Deliver the interrupt to each CPU, considering each CPU's IIC. */ - for (i = 0; i < 4; ++i) { - AlphaCPU *cpu = s->cchip.cpu[i]; - if (cpu != NULL) { - uint32_t iic = s->cchip.iic[i]; - - /* ??? The verbage in Section 10.2.2.10 isn't 100% clear. - Bit 24 is the OverFlow bit, RO, and set when the count - decrements past 0. When is OF cleared? My guess is that - OF is actually cleared when the IIC is written, and that - the ICNT field always decrements. At least, that's an - interpretation that makes sense, and "allows the CPU to - determine exactly how mant interval timer ticks were - skipped". At least within the next 4M ticks... */ - - iic = ((iic - 1) & 0x1ffffff) | (iic & 0x1000000); - s->cchip.iic[i] = iic; - - if (iic & 0x1000000) { - /* Set the ITI bit for this cpu. */ - s->cchip.misc |= 1 << (i + 4); - /* And signal the interrupt. */ - cpu_interrupt(CPU(cpu), CPU_INTERRUPT_TIMER); - } - } - } -} - -static void typhoon_alarm_timer(void *opaque) -{ - TyphoonState *s = (TyphoonState *)((uintptr_t)opaque & ~3); - int cpu = (uintptr_t)opaque & 3; - - /* Set the ITI bit for this cpu. */ - s->cchip.misc |= 1 << (cpu + 4); - cpu_interrupt(CPU(s->cchip.cpu[cpu]), CPU_INTERRUPT_TIMER); -} - -PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus, - qemu_irq *p_rtc_irq, - AlphaCPU *cpus[4], pci_map_irq_fn sys_map_irq) -{ - const uint64_t MB = 1024 * 1024; - const uint64_t GB = 1024 * MB; - MemoryRegion *addr_space = get_system_memory(); - MemoryRegion *addr_space_io = get_system_io(); - DeviceState *dev; - TyphoonState *s; - PCIHostState *phb; - PCIBus *b; - int i; - - dev = qdev_create(NULL, TYPE_TYPHOON_PCI_HOST_BRIDGE); - qdev_init_nofail(dev); - - s = TYPHOON_PCI_HOST_BRIDGE(dev); - phb = PCI_HOST_BRIDGE(dev); - - /* Remember the CPUs so that we can deliver interrupts to them. */ - for (i = 0; i < 4; i++) { - AlphaCPU *cpu = cpus[i]; - s->cchip.cpu[i] = cpu; - if (cpu != NULL) { - cpu->alarm_timer = qemu_new_timer_ns(rtc_clock, - typhoon_alarm_timer, - (void *)((uintptr_t)s + i)); - } - } - - *p_rtc_irq = *qemu_allocate_irqs(typhoon_set_timer_irq, s, 1); - - /* Main memory region, 0x00.0000.0000. Real hardware supports 32GB, - but the address space hole reserved at this point is 8TB. */ - memory_region_init_ram(&s->ram_region, "ram", ram_size); - vmstate_register_ram_global(&s->ram_region); - memory_region_add_subregion(addr_space, 0, &s->ram_region); - - /* TIGbus, 0x801.0000.0000, 1GB. */ - /* ??? The TIGbus is used for delivering interrupts, and access to - the flash ROM. I'm not sure that we need to implement it at all. */ - - /* Pchip0 CSRs, 0x801.8000.0000, 256MB. */ - memory_region_init_io(&s->pchip.region, &pchip_ops, s, "pchip0", 256*MB); - memory_region_add_subregion(addr_space, 0x80180000000ULL, - &s->pchip.region); - - /* Cchip CSRs, 0x801.A000.0000, 256MB. */ - memory_region_init_io(&s->cchip.region, &cchip_ops, s, "cchip0", 256*MB); - memory_region_add_subregion(addr_space, 0x801a0000000ULL, - &s->cchip.region); - - /* Dchip CSRs, 0x801.B000.0000, 256MB. */ - memory_region_init_io(&s->dchip_region, &dchip_ops, s, "dchip0", 256*MB); - memory_region_add_subregion(addr_space, 0x801b0000000ULL, - &s->dchip_region); - - /* Pchip0 PCI memory, 0x800.0000.0000, 4GB. */ - memory_region_init(&s->pchip.reg_mem, "pci0-mem", 4*GB); - memory_region_add_subregion(addr_space, 0x80000000000ULL, - &s->pchip.reg_mem); - - /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB. */ - /* ??? Ideally we drop the "system" i/o space on the floor and give the - PCI subsystem the full address space reserved by the chipset. - We can't do that until the MEM and IO paths in memory.c are unified. */ - memory_region_init_io(&s->pchip.reg_io, &alpha_pci_bw_io_ops, NULL, - "pci0-io", 32*MB); - memory_region_add_subregion(addr_space, 0x801fc000000ULL, - &s->pchip.reg_io); - - b = pci_register_bus(dev, "pci", - typhoon_set_irq, sys_map_irq, s, - &s->pchip.reg_mem, addr_space_io, 0, 64, TYPE_PCI_BUS); - phb->bus = b; - - /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */ - memory_region_init_io(&s->pchip.reg_iack, &alpha_pci_iack_ops, b, - "pci0-iack", 64*MB); - memory_region_add_subregion(addr_space, 0x801f8000000ULL, - &s->pchip.reg_iack); - - /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB. */ - memory_region_init_io(&s->pchip.reg_conf, &alpha_pci_conf1_ops, b, - "pci0-conf", 16*MB); - memory_region_add_subregion(addr_space, 0x801fe000000ULL, - &s->pchip.reg_conf); - - /* For the record, these are the mappings for the second PCI bus. - We can get away with not implementing them because we indicate - via the Cchip.CSC<PIP> bit that Pchip1 is not present. */ - /* Pchip1 PCI memory, 0x802.0000.0000, 4GB. */ - /* Pchip1 CSRs, 0x802.8000.0000, 256MB. */ - /* Pchip1 PCI special/interrupt acknowledge, 0x802.F800.0000, 64MB. */ - /* Pchip1 PCI I/O, 0x802.FC00.0000, 32MB. */ - /* Pchip1 PCI configuration, 0x802.FE00.0000, 16MB. */ - - /* Init the ISA bus. */ - /* ??? Technically there should be a cy82c693ub pci-isa bridge. */ - { - qemu_irq isa_pci_irq, *isa_irqs; - - *isa_bus = isa_bus_new(NULL, addr_space_io); - isa_pci_irq = *qemu_allocate_irqs(typhoon_set_isa_irq, s, 1); - isa_irqs = i8259_init(*isa_bus, isa_pci_irq); - isa_bus_irqs(*isa_bus, isa_irqs); - } - - return b; -} - -static int typhoon_pcihost_init(SysBusDevice *dev) -{ - return 0; -} - -static void typhoon_pcihost_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = typhoon_pcihost_init; - dc->no_user = 1; -} - -static const TypeInfo typhoon_pcihost_info = { - .name = TYPE_TYPHOON_PCI_HOST_BRIDGE, - .parent = TYPE_PCI_HOST_BRIDGE, - .instance_size = sizeof(TyphoonState), - .class_init = typhoon_pcihost_class_init, -}; - -static void typhoon_register_types(void) -{ - type_register_static(&typhoon_pcihost_info); -} - -type_init(typhoon_register_types) |