/*
 * 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-all.h"
#include "hw.h"
#include "devices.h"
#include "sysemu.h"
#include "alpha_sys.h"
#include "exec-memory.h"


typedef struct TyphoonCchip {
    MemoryRegion region;
    uint64_t misc;
    uint64_t drir;
    uint64_t dim[4];
    uint32_t iic[4];
    CPUAlphaState *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;

typedef struct TyphoonState {
    PCIHostState host;
    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(CPUAlphaState *env, uint64_t req)
{
    /* If there are any non-masked interrupts, tell the cpu.  */
    if (env) {
        if (req) {
            cpu_interrupt(env, CPU_INTERRUPT_HARD);
        } else {
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
        }
    }
}

static uint64_t cchip_read(void *opaque, target_phys_addr_t addr, unsigned size)
{
    CPUAlphaState *env = cpu_single_env;
    TyphoonState *s = opaque;
    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.  */
        ret = s->cchip.misc | (env->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, target_phys_addr_t addr, unsigned size)
{
    /* Skip this.  It's all related to DRAM timing and setup.  */
    return 0;
}

static uint64_t pchip_read(void *opaque, target_phys_addr_t 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, target_phys_addr_t 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) {
                CPUAlphaState *env = s->cchip.cpu[i];
                if (env) {
                    /* IPI can be either cleared or set by the write.  */
                    if (newval & (1 << (i + 8))) {
                        cpu_interrupt(env, CPU_INTERRUPT_SMP);
                    } else {
                        cpu_reset_interrupt(env, CPU_INTERRUPT_SMP);
                    }

                    /* ITI can only be cleared by the write.  */
                    if ((newval & (1 << (i + 4))) == 0) {
                        cpu_reset_interrupt(env, 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, target_phys_addr_t addr,
                        uint64_t val, unsigned size)
{
    /* Skip this.  It's all related to DRAM timing and setup.  */
}

static void pchip_write(void *opaque, target_phys_addr_t 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) {
        CPUAlphaState *env = s->cchip.cpu[i];
        if (env) {
            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(env, 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(s->cchip.cpu[cpu], CPU_INTERRUPT_TIMER);
}

PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
                     qemu_irq *p_rtc_irq,
                     CPUAlphaState *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;
    PCIHostState *p;
    TyphoonState *s;
    PCIBus *b;
    int i;

    dev = qdev_create(NULL, "typhoon-pcihost");
    qdev_init_nofail(dev);

    p = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
    s = container_of(p, TyphoonState, host);

    /* Remember the CPUs so that we can deliver interrupts to them.  */
    for (i = 0; i < 4; i++) {
        CPUAlphaState *env = cpus[i];
        s->cchip.cpu[i] = env;
        if (env) {
            env->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(&s->host.busdev.qdev, "pci",
                         typhoon_set_irq, sys_map_irq, s,
                         &s->pchip.reg_mem, addr_space_io, 0, 64);
    s->host.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 TypeInfo typhoon_pcihost_info = {
    .name          = "typhoon-pcihost",
    .parent        = TYPE_SYS_BUS_DEVICE,
    .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)
