/*
 * DEC 21272 (TSUNAMI/TYPHOON) chipset emulation.
 *
 * Written by Richard Henderson.
 *
 * This work is licensed under the GNU GPL license version 2 or later.
 */

#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/pci/pci_host.h"
#include "cpu.h"
#include "hw/irq.h"
#include "alpha_sys.h"


#define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
#define TYPE_TYPHOON_IOMMU_MEMORY_REGION "typhoon-iommu-memory-region"

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 {
    uint64_t wba;
    uint64_t wsm;
    uint64_t tba;
} TyphoonWindow;
 
typedef struct TyphoonPchip {
    MemoryRegion region;
    MemoryRegion reg_iack;
    MemoryRegion reg_mem;
    MemoryRegion reg_io;
    MemoryRegion reg_conf;

    AddressSpace iommu_as;
    IOMMUMemoryRegion iommu;

    uint64_t ctl;
    TyphoonWindow win[4];
} TyphoonPchip;

OBJECT_DECLARE_SIMPLE_TYPE(TyphoonState, TYPHOON_PCI_HOST_BRIDGE)

struct TyphoonState {
    PCIHostState parent_obj;

    TyphoonCchip cchip;
    TyphoonPchip pchip;
    MemoryRegion dchip_region;
};

/* 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 MemTxResult cchip_read(void *opaque, hwaddr addr,
                              uint64_t *data, unsigned size,
                              MemTxAttrs attrs)
{
    CPUState *cpu = current_cpu;
    TyphoonState *s = opaque;
    uint64_t ret = 0;

    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 | (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:
        return MEMTX_ERROR;
    }

    *data = ret;
    return MEMTX_OK;
}

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 MemTxResult pchip_read(void *opaque, hwaddr addr, uint64_t *data,
                              unsigned size, MemTxAttrs attrs)
{
    TyphoonState *s = opaque;
    uint64_t ret = 0;

    switch (addr) {
    case 0x0000:
        /* WSBA0: Window Space Base Address Register.  */
        ret = s->pchip.win[0].wba;
        break;
    case 0x0040:
        /* WSBA1 */
        ret = s->pchip.win[1].wba;
        break;
    case 0x0080:
        /* WSBA2 */
        ret = s->pchip.win[2].wba;
        break;
    case 0x00c0:
        /* WSBA3 */
        ret = s->pchip.win[3].wba;
        break;

    case 0x0100:
        /* WSM0: Window Space Mask Register.  */
        ret = s->pchip.win[0].wsm;
        break;
    case 0x0140:
        /* WSM1 */
        ret = s->pchip.win[1].wsm;
        break;
    case 0x0180:
        /* WSM2 */
        ret = s->pchip.win[2].wsm;
        break;
    case 0x01c0:
        /* WSM3 */
        ret = s->pchip.win[3].wsm;
        break;

    case 0x0200:
        /* TBA0: Translated Base Address Register.  */
        ret = s->pchip.win[0].tba;
        break;
    case 0x0240:
        /* TBA1 */
        ret = s->pchip.win[1].tba;
        break;
    case 0x0280:
        /* TBA2 */
        ret = s->pchip.win[2].tba;
        break;
    case 0x02c0:
        /* TBA3 */
        ret = s->pchip.win[3].tba;
        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:
        return MEMTX_ERROR;
    }

    *data = ret;
    return MEMTX_OK;
}

static MemTxResult cchip_write(void *opaque, hwaddr addr,
                               uint64_t val, unsigned size,
                               MemTxAttrs attrs)
{
    TyphoonState *s = opaque;
    uint64_t oldval, newval;

    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[1] = 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:
        return MEMTX_ERROR;
    }

    return MEMTX_OK;
}

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 MemTxResult pchip_write(void *opaque, hwaddr addr,
                               uint64_t val, unsigned size,
                               MemTxAttrs attrs)
{
    TyphoonState *s = opaque;
    uint64_t oldval;

    switch (addr) {
    case 0x0000:
        /* WSBA0: Window Space Base Address Register.  */
        s->pchip.win[0].wba = val & 0xfff00003u;
        break;
    case 0x0040:
        /* WSBA1 */
        s->pchip.win[1].wba = val & 0xfff00003u;
        break;
    case 0x0080:
        /* WSBA2 */
        s->pchip.win[2].wba = val & 0xfff00003u;
        break;
    case 0x00c0:
        /* WSBA3 */
        s->pchip.win[3].wba = (val & 0x80fff00001ull) | 2;
        break;

    case 0x0100:
        /* WSM0: Window Space Mask Register.  */
        s->pchip.win[0].wsm = val & 0xfff00000u;
        break;
    case 0x0140:
        /* WSM1 */
        s->pchip.win[1].wsm = val & 0xfff00000u;
        break;
    case 0x0180:
        /* WSM2 */
        s->pchip.win[2].wsm = val & 0xfff00000u;
        break;
    case 0x01c0:
        /* WSM3 */
        s->pchip.win[3].wsm = val & 0xfff00000u;
        break;

    case 0x0200:
        /* TBA0: Translated Base Address Register.  */
        s->pchip.win[0].tba = val & 0x7fffffc00ull;
        break;
    case 0x0240:
        /* TBA1 */
        s->pchip.win[1].tba = val & 0x7fffffc00ull;
        break;
    case 0x0280:
        /* TBA2 */
        s->pchip.win[2].tba = val & 0x7fffffc00ull;
        break;
    case 0x02c0:
        /* TBA3 */
        s->pchip.win[3].tba = val & 0x7fffffc00ull;
        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:
        return MEMTX_ERROR;
    }

    return MEMTX_OK;
}

static const MemoryRegionOps cchip_ops = {
    .read_with_attrs = cchip_read,
    .write_with_attrs = cchip_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
};

static const MemoryRegionOps dchip_ops = {
    .read = dchip_read,
    .write = dchip_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
};

static const MemoryRegionOps pchip_ops = {
    .read_with_attrs = pchip_read,
    .write_with_attrs = pchip_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
};

/* A subroutine of typhoon_translate_iommu that builds an IOMMUTLBEntry
   using the given translated address and mask.  */
static bool make_iommu_tlbe(hwaddr taddr, hwaddr mask, IOMMUTLBEntry *ret)
{
    *ret = (IOMMUTLBEntry) {
        .target_as = &address_space_memory,
        .translated_addr = taddr,
        .addr_mask = mask,
        .perm = IOMMU_RW,
    };
    return true;
}

/* A subroutine of typhoon_translate_iommu that handles scatter-gather
   translation, given the address of the PTE.  */
static bool pte_translate(hwaddr pte_addr, IOMMUTLBEntry *ret)
{
    uint64_t pte = address_space_ldq(&address_space_memory, pte_addr,
                                     MEMTXATTRS_UNSPECIFIED, NULL);

    /* Check valid bit.  */
    if ((pte & 1) == 0) {
        return false;
    }

    return make_iommu_tlbe((pte & 0x3ffffe) << 12, 0x1fff, ret);
}

/* A subroutine of typhoon_translate_iommu that handles one of the
   four single-address-cycle translation windows.  */
static bool window_translate(TyphoonWindow *win, hwaddr addr,
                             IOMMUTLBEntry *ret)
{
    uint32_t wba = win->wba;
    uint64_t wsm = win->wsm;
    uint64_t tba = win->tba;
    uint64_t wsm_ext = wsm | 0xfffff;

    /* Check for window disabled.  */
    if ((wba & 1) == 0) {
        return false;
    }

    /* Check for window hit.  */
    if ((addr & ~wsm_ext) != (wba & 0xfff00000u)) {
        return false;
    }

    if (wba & 2) {
        /* Scatter-gather translation.  */
        hwaddr pte_addr;

        /* See table 10-6, Generating PTE address for PCI DMA Address.  */
        pte_addr  = tba & ~(wsm >> 10);
        pte_addr |= (addr & (wsm | 0xfe000)) >> 10;
        return pte_translate(pte_addr, ret);
    } else {
        /* Direct-mapped translation.  */
        return make_iommu_tlbe(tba & ~wsm_ext, wsm_ext, ret);
    }
}

/* Handle PCI-to-system address translation.  */
/* TODO: A translation failure here ought to set PCI error codes on the
   Pchip and generate a machine check interrupt.  */
static IOMMUTLBEntry typhoon_translate_iommu(IOMMUMemoryRegion *iommu,
                                             hwaddr addr,
                                             IOMMUAccessFlags flag,
                                             int iommu_idx)
{
    TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
    IOMMUTLBEntry ret;
    int i;

    if (addr <= 0xffffffffu) {
        /* Single-address cycle.  */

        /* Check for the Window Hole, inhibiting matching.  */
        if ((pchip->ctl & 0x20)
            && addr >= 0x80000
            && addr <= 0xfffff) {
            goto failure;
        }

        /* Check the first three windows.  */
        for (i = 0; i < 3; ++i) {
            if (window_translate(&pchip->win[i], addr, &ret)) {
                goto success;
            }
        }

        /* Check the fourth window for DAC disable.  */
        if ((pchip->win[3].wba & 0x80000000000ull) == 0
            && window_translate(&pchip->win[3], addr, &ret)) {
            goto success;
        }
    } else {
        /* Double-address cycle.  */

        if (addr >= 0x10000000000ull && addr < 0x20000000000ull) {
            /* Check for the DMA monster window.  */
            if (pchip->ctl & 0x40) {
                /* See 10.1.4.4; in particular <39:35> is ignored.  */
                make_iommu_tlbe(0, 0x007ffffffffull, &ret);
                goto success;
            }
        }

        if (addr >= 0x80000000000ull && addr <= 0xfffffffffffull) {
            /* Check the fourth window for DAC enable and window enable.  */
            if ((pchip->win[3].wba & 0x80000000001ull) == 0x80000000001ull) {
                uint64_t pte_addr;

                pte_addr  = pchip->win[3].tba & 0x7ffc00000ull;
                pte_addr |= (addr & 0xffffe000u) >> 10;
                if (pte_translate(pte_addr, &ret)) {
                        goto success;
                }
            }
        }
    }

 failure:
    ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE };
 success:
    return ret;
}

static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
{
    TyphoonState *s = opaque;
    return &s->pchip.iommu_as;
}

static const PCIIOMMUOps typhoon_iommu_ops = {
    .get_address_space = typhoon_pci_dma_iommu,
};

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(MemoryRegion *ram, qemu_irq *p_isa_irq,
                     qemu_irq *p_rtc_irq, AlphaCPU *cpus[4],
                     pci_map_irq_fn sys_map_irq, uint8_t devfn_min)
{
    MemoryRegion *addr_space = get_system_memory();
    DeviceState *dev;
    TyphoonState *s;
    PCIHostState *phb;
    PCIBus *b;
    int i;

    dev = qdev_new(TYPE_TYPHOON_PCI_HOST_BRIDGE);

    s = TYPHOON_PCI_HOST_BRIDGE(dev);
    phb = PCI_HOST_BRIDGE(dev);

    s->cchip.misc = 0x800000000ull; /* Revision: Typhoon.  */
    s->pchip.win[3].wba = 2;        /* Window 3 SG always enabled. */

    /* 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 = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                                 typhoon_alarm_timer,
                                                 (void *)((uintptr_t)s + i));
        }
    }

    *p_isa_irq = qemu_allocate_irq(typhoon_set_isa_irq, s, 0);
    *p_rtc_irq = qemu_allocate_irq(typhoon_set_timer_irq, s, 0);

    /* Main memory region, 0x00.0000.0000.  Real hardware supports 32GB,
       but the address space hole reserved at this point is 8TB.  */
    memory_region_add_subregion(addr_space, 0, ram);

    /* 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, OBJECT(s), &pchip_ops, s, "pchip0",
                          256 * MiB);
    memory_region_add_subregion(addr_space, 0x80180000000ULL,
                                &s->pchip.region);

    /* Cchip CSRs, 0x801.A000.0000, 256MB.  */
    memory_region_init_io(&s->cchip.region, OBJECT(s), &cchip_ops, s, "cchip0",
                          256 * MiB);
    memory_region_add_subregion(addr_space, 0x801a0000000ULL,
                                &s->cchip.region);

    /* Dchip CSRs, 0x801.B000.0000, 256MB.  */
    memory_region_init_io(&s->dchip_region, OBJECT(s), &dchip_ops, s, "dchip0",
                          256 * MiB);
    memory_region_add_subregion(addr_space, 0x801b0000000ULL,
                                &s->dchip_region);

    /* Pchip0 PCI memory, 0x800.0000.0000, 4GB.  */
    memory_region_init(&s->pchip.reg_mem, OBJECT(s), "pci0-mem", 4 * GiB);
    memory_region_add_subregion(addr_space, 0x80000000000ULL,
                                &s->pchip.reg_mem);

    /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB.  */
    memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_ignore_ops,
                          NULL, "pci0-io", 32 * MiB);
    memory_region_add_subregion(addr_space, 0x801fc000000ULL,
                                &s->pchip.reg_io);

    b = pci_register_root_bus(dev, "pci",
                              typhoon_set_irq, sys_map_irq, s,
                              &s->pchip.reg_mem, &s->pchip.reg_io,
                              devfn_min, 64, TYPE_PCI_BUS);
    phb->bus = b;
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    /* Host memory as seen from the PCI side, via the IOMMU.  */
    memory_region_init_iommu(&s->pchip.iommu, sizeof(s->pchip.iommu),
                             TYPE_TYPHOON_IOMMU_MEMORY_REGION, OBJECT(s),
                             "iommu-typhoon", UINT64_MAX);
    address_space_init(&s->pchip.iommu_as, MEMORY_REGION(&s->pchip.iommu),
                       "pchip0-pci");
    pci_setup_iommu(b, &typhoon_iommu_ops, s);

    /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB.  */
    memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
                          b, "pci0-iack", 64 * MiB);
    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, OBJECT(s), &alpha_pci_conf1_ops,
                          b, "pci0-conf", 16 * MiB);
    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.  */

    return b;
}

static const TypeInfo typhoon_pcihost_info = {
    .name          = TYPE_TYPHOON_PCI_HOST_BRIDGE,
    .parent        = TYPE_PCI_HOST_BRIDGE,
    .instance_size = sizeof(TyphoonState),
};

static void typhoon_iommu_memory_region_class_init(ObjectClass *klass,
                                                   void *data)
{
    IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);

    imrc->translate = typhoon_translate_iommu;
}

static const TypeInfo typhoon_iommu_memory_region_info = {
    .parent = TYPE_IOMMU_MEMORY_REGION,
    .name = TYPE_TYPHOON_IOMMU_MEMORY_REGION,
    .class_init = typhoon_iommu_memory_region_class_init,
};

static void typhoon_register_types(void)
{
    type_register_static(&typhoon_pcihost_info);
    type_register_static(&typhoon_iommu_memory_region_info);
}

type_init(typhoon_register_types)
