qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Tristan Gingold <gingold@adacore.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 11/19] Add 21272 chipset (memory and pci controller for alpha)
Date: Mon, 30 Mar 2009 16:36:26 +0200	[thread overview]
Message-ID: <1238423794-25455-12-git-send-email-gingold@adacore.com> (raw)
In-Reply-To: <1238423794-25455-11-git-send-email-gingold@adacore.com>

Signed-off-by: Tristan Gingold <gingold@adacore.com>
---
 hw/21272.c |  869 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/pci.h   |    8 +
 2 files changed, 877 insertions(+), 0 deletions(-)
 create mode 100644 hw/21272.c

diff --git a/hw/21272.c b/hw/21272.c
new file mode 100644
index 0000000..a54dd59
--- /dev/null
+++ b/hw/21272.c
@@ -0,0 +1,869 @@
+/*
+ * Qemu 21272 (Tsunami/Typhoon) chipset emulation.
+ *
+ * Copyright (c) 2009 AdaCore
+ *
+ * Written by Tristan Gingold.
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ */
+#include "hw.h"
+#include "devices.h"
+#include "pci.h"
+
+//#define DEBUG_CCHIP
+//#define DEBUG_PCHIP
+//#define DEBUG_DCHIP
+//#define DEBUG_PCICFG
+
+typedef struct PchipState PchipState;
+struct PchipState {
+    /* IntAck handler.  */
+    int (*iack_handler)(void *);
+    void *iack_handler_param;
+
+    PCIBus *pci;
+
+    /* Pchip id.  */
+    int num;
+
+    /* Used to reconstruct 64bits accesses.  Low long word first.  */
+    uint32_t data;
+
+    uint32_t wsba[3];
+    uint64_t wsba3;
+    uint32_t wsm[3];
+    uint32_t wsm3;
+    uint64_t tba[3];
+    uint64_t tba3;
+    uint32_t perrmask;
+    uint32_t plat;
+    /* pctl */
+    unsigned char ptevrfy;
+    unsigned char mwin;
+    unsigned char hole;
+    unsigned char chaindis;
+};
+
+struct TyphoonState {
+    qemu_irq *irqs;
+    qemu_irq *intim_irq;
+    CPUState *cpu[4];
+
+    /* Used to reconstruct 64bits accesses.  Low long word first.  */
+    uint32_t data;
+
+    unsigned char misc_rev;
+    unsigned char misc_abw;
+    unsigned char misc_abt;
+
+    int b_irq[4];
+
+    uint64_t dim[4];
+    uint64_t dir[4];
+    uint64_t drir;
+    uint64_t aar[4];
+
+    /* dchip */
+    uint64_t csc;
+    uint64_t str;
+
+    PchipState pchip[2];
+};
+
+static void illegal_write (void *opaque,
+                            target_phys_addr_t addr, uint32_t value)
+{
+    qemu_log("illegal_write at addr="TARGET_FMT_lx"\n", addr);
+}
+
+static uint32_t illegal_read (void *opaque, target_phys_addr_t addr)
+{
+    qemu_log("illegal_read at addr="TARGET_FMT_lx"\n", addr);
+    return 0;
+}
+
+static uint32_t typhoon_cchip_readl (void *opaque, target_phys_addr_t addr)
+{
+    TyphoonState *s = opaque;
+    uint64_t val;
+    int reg;
+
+    /* Handle 64-bits accesses;  */
+    if (addr & 0x04)
+        return s->data;
+
+    reg = addr >> 6;
+    switch (reg) {
+    case 0x00: /* CSC */
+        val = s->csc;
+        break;
+    case 0x02: /* MISC */
+        val = ((uint64_t)s->misc_rev << 32)
+            | ((uint64_t)s->misc_abt << 20)
+            | ((uint64_t)s->misc_abw << 16)
+            | ((s->b_irq[0] & 4) << 2)
+            | ((s->b_irq[1] & 4) << 3)
+            | ((s->b_irq[2] & 4) << 4)
+            | ((s->b_irq[3] & 4) << 5)
+            | ((s->b_irq[0] & 8) << 5)
+            | ((s->b_irq[1] & 8) << 6)
+            | ((s->b_irq[2] & 8) << 7)
+            | ((s->b_irq[3] & 8) << 8);
+        break;
+    case 0x04:
+    case 0x05:
+    case 0x06:
+    case 0x07:
+        val = s->aar[reg - 4];
+        break;
+    case 0x08:
+    case 0x09:
+    case 0x18:
+    case 0x19:
+        val = s->dim[(reg & 1) | ((reg & 0x10) >> 3)];
+        break;
+    case 0x0a:
+    case 0x0b:
+    case 0x1a:
+    case 0x1b:
+        val = s->dir[(reg & 1) | ((reg & 0x10) >> 3)];
+        break;
+    case 0x0c:
+        val = s->drir;
+        break;
+    default:
+        qemu_log("21272: unhandled cchip read  reg=%x\n", reg);
+        val = 0;
+        break;
+    }
+
+#ifdef DEBUG_CCHIP
+    fprintf(stderr,"typhoon cchip read  reg=%x, val=%016"PRIx64"\n", reg, val);
+#endif
+    s->data = val >> 32;
+    return (uint32_t)val;
+}
+
+static void typhoon_cchip_writel (void *opaque,
+                                  target_phys_addr_t addr, uint32_t value)
+{
+    TyphoonState *s = opaque;
+    int reg;
+    uint64_t val;
+
+#if 0
+    fprintf(stderr,"typhoon write addr="TARGET_FMT_lx", val=%08x\n",
+            addr, value);
+#endif
+
+    /* Handle 64-bits accesses.  LSB first.  */
+    if (!(addr & 0x04)) {
+        s->data = value;
+        return;
+    }
+    else
+        val = ((uint64_t)value << 32) | s->data;
+
+    reg = addr >> 6;
+
+#ifdef DEBUG_CCHIP
+    fprintf(stderr,"typhoon cchip write reg=%x, val=%016"PRIx64"\n", reg, val);
+#endif
+
+    switch (reg) {
+    case 0x00: /* CSC */
+        s->csc = (s->csc & 0xffffU) | (val & 0x0777777fff3f0000ULL);
+        break;
+    case 0x02: /* MISC */
+        if (val & (1 << 24)) {
+            /* ACL: arbitration clear.  */
+            s->misc_abt = 0;
+            s->misc_abw = 0;
+        }
+        if (val & (0xf << 12)) {
+            int i;
+            for (i = 0; i < 4 && s->cpu[i]; i++)
+                if ((val & (0x1000 << i))) {
+                    s->b_irq[i] &= ~(1 << 3);
+                    cpu_alpha_update_irq(s->cpu[i], s->b_irq[i]);
+                }
+        }
+        if ((val & (0xf << 16)) && s->misc_abw == 0) {
+            /* ABW: arbitration won.  */
+            s->misc_abw = (val >> 16) & 0x0f;
+        }
+        if ((val & (0x0f << 20)) && s->misc_abt == 0) {
+            /* ABT: arbitration try.  */
+            s->misc_abt = (val >> 20) & 0x0f;
+        }
+        if (val & (1ULL << 28)) {
+            /* NXM - not handled.  */
+        }
+        if (val & (0x0fULL << 40)) {
+            /* DEVUP - not handled.  */
+        }
+        if (val & (0x0f << 4)) {
+            /* ITINTR */
+            int i;
+            for (i = 0; i < 4 && s->cpu[i]; i++)
+                if ((val & (0x10 << i))) {
+                    s->b_irq[i] &= ~(1 << 2);
+                    cpu_alpha_update_irq(s->cpu[i], s->b_irq[i]);
+                }
+        }
+        if (val & ~((0xfULL << 40) | (0xffULL << 32) | (1 << 28) | (1ULL << 24)
+                    | (0x0f << 12) | (0xf << 16)
+                    | (0x0f << 20) | (0x0f << 4))) {
+            qemu_log("21272: unhandled value %016"PRIx64" written in MISC\n",
+                     val);
+        }
+        break;
+    case 0x08:
+    case 0x09:
+    case 0x18:
+    case 0x19:
+        s->dim[(reg & 1) | ((reg & 0x10) >> 3)] = val;
+        break;
+    default:
+        qemu_log("21272: unhandled cchip write reg %x (%016"PRIx64")\n",
+                 reg, val);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc *typhoon_cchip_read[] = {
+    &illegal_read,
+    &illegal_read,
+    &typhoon_cchip_readl,
+};
+
+static CPUWriteMemoryFunc *typhoon_cchip_write[] = {
+    &illegal_write,
+    &illegal_write,
+    &typhoon_cchip_writel,
+};
+
+static uint32_t typhoon_dchip_readl (void *opaque, target_phys_addr_t addr)
+{
+    TyphoonState *s = opaque;
+    uint64_t val;
+    int reg;
+
+    /* Handle 64-bits accesses;  */
+    if (addr & 0x04)
+        return s->data;
+
+    reg = addr >> 6;
+    switch (reg) {
+    case 0x20: /* DSC */
+        val = (s->csc & 0x3f) | ((s->csc >> (14 - 6)) & 0x40);
+        val = (val << 8) | val;
+        val = (val << 16) | val;
+        val = (val << 32) | val;
+        break;
+    case 0x21: /* STR */
+        val = s->str;
+        break;
+    case 0x22: /* DREV */
+        val = 0x01 * 0x0101010101010101ULL;
+        break;
+    case 0x23: /* DSC2 */
+        val = 0;
+    default:
+        qemu_log("21272: unhandled dchip read  reg=%x\n", reg);
+        val = 0;
+        break;
+    }
+
+#ifdef DEBUG_DCHIP
+    fprintf(stderr,"typhoon dchip read  reg=%x, val=%016"PRIx64"\n", reg, val);
+#endif
+    s->data = val >> 32;
+    return (uint32_t)val;
+}
+
+static void typhoon_dchip_writel (void *opaque,
+                                  target_phys_addr_t addr, uint32_t value)
+{
+    TyphoonState *s = opaque;
+    int reg;
+    uint64_t val;
+
+#if 0
+    fprintf(stderr,"typhoon write addr="TARGET_FMT_lx", val=%08x\n",
+            addr, value);
+#endif
+
+    /* Handle 64-bits accesses.  LSB first.  */
+    if (!(addr & 0x04)) {
+        s->data = value;
+        return;
+    }
+    else
+        val = ((uint64_t)value << 32) | s->data;
+
+    reg = addr >> 6;
+
+#ifdef DEBUG_DCHIP
+    fprintf(stderr,"typhoon dchip write reg=%x, val=%016"PRIx64"\n", reg, val);
+#endif
+
+    switch (reg) {
+    default:
+        qemu_log("21272: unhandled dchip write reg %x (%016"PRIx64")\n",
+                 reg, val);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc *typhoon_dchip_read[] = {
+    &illegal_read,
+    &illegal_read,
+    &typhoon_dchip_readl,
+};
+
+static CPUWriteMemoryFunc *typhoon_dchip_write[] = {
+    &illegal_write,
+    &illegal_write,
+    &typhoon_dchip_writel,
+};
+
+static uint32_t typhoon_pchip_readl (void *opaque, target_phys_addr_t addr)
+{
+    PchipState *s = opaque;
+    uint64_t val;
+    int reg;
+
+    /* Handle 64-bits accesses;  */
+    if (addr & 0x04)
+        return s->data;
+
+    reg = addr >> 6;
+    switch (reg) {
+    case 0x00:
+    case 0x01:
+    case 0x02:
+        val = s->wsba[reg];
+        break;
+    case 0x03:
+        val = s->wsba3;
+        break;
+    case 0x04:
+    case 0x05:
+    case 0x06:
+        val = s->wsm[reg - 4];
+        break;
+    case 0x07:
+        val = s->wsm3;
+        break;
+    case 0x08:
+    case 0x09:
+    case 0x0a:
+        val = s->tba[reg - 0x8];
+        break;
+    case 0x0b:
+        val = s->tba3;
+        break;
+    case 0x0c: /* pctl  */
+        val = (((uint64_t)(s->num & 3)) << 46)
+            | (((uint64_t)s->ptevrfy) << 44)
+            | (1ULL << 40) /* PCLKX */
+            | (1 << 24) /* Rev */
+            | (s->mwin << 6)
+            | (s->hole << 5)
+            | (s->chaindis << 3);
+        break;
+    case 0x0d: /* plat */
+        val = s->plat;
+        break;
+    case 0x0f: /* PERROR */
+        val = 0;  /* Not emulated.  */
+        break;
+    case 0x10: /* PERRMASK */
+        val = s->perrmask;
+        break;
+    case 0x20: /* WO. */
+        val = 0;
+        break;
+    default:
+        qemu_log("21272: unhandled pchip read  reg=%x\n", reg);
+        val = 0;
+        break;
+    }
+
+#ifdef DEBUG_PCHIP
+    fprintf(stderr,"typhoon pchip%d read  reg=%x, val=%016"PRIx64"\n",
+            s->num, reg, val);
+#endif
+    s->data = val >> 32;
+    return (uint32_t)val;
+}
+
+static void typhoon_pchip_writel (void *opaque,
+                                  target_phys_addr_t addr, uint32_t value)
+{
+    PchipState *s = opaque;
+    int reg;
+    uint64_t val;
+
+    /* Handle 64-bits accesses.  LSB first.  */
+    if (!(addr & 0x04)) {
+        s->data = value;
+        return;
+    }
+    else
+        val = ((uint64_t)value << 32) | s->data;
+
+    reg = addr >> 6;
+
+#ifdef DEBUG_PCHIP
+    fprintf(stderr,"typhoon pchip%d write reg=%x, val=%016"PRIx64"\n",
+            s->num, reg, val);
+#endif
+
+    switch (reg) {
+    case 0:
+    case 1:
+    case 2:
+        s->wsba[reg] = val & 0xfff00003;
+        if (val & 1)
+            qemu_log("21272: enabling wsba%d!\n", reg); /* Not yet emulated */
+        break;
+    case 3:
+        s->wsba3 = val & 0xffffff80fff00003ULL;
+        if (val & 1)
+            qemu_log("21272: enabling wsba3!\n"); /* Not yet emulated */
+        break;
+    case 0x4:
+    case 0x5:
+    case 0x6:
+        s->wsm[reg - 4] = val & 0xfff00000;
+        break;
+    case 0x7:
+        s->wsm3 = val & 0xfff00000;
+        break;
+    case 0x8:
+    case 0x9:
+    case 0xa:
+        s->tba[reg - 0x8] = val & 0x7fffffc00;
+        break;
+    case 0xb:
+        s->tba3 = val & 0x7fffffc00;
+        break;
+    case 0x0c: /* pctl  */
+        s->ptevrfy = (val >> 44) & 1;
+        s->mwin = (val >> 6) & 1;
+        s->hole = (val >> 5) & 1;
+        s->chaindis = (val >> 3) & 1;
+        if (val & ((1ULL << 43) | (1ULL << 42) | (3ULL << 36) | (0x0fULL << 32)
+                   | (0x0f << 20) | (1 << 19) | (0x3f << 8)
+                   | (1 << 2) | (1 << 1)))
+            qemu_log("21272: pchip pctl: unhandled value %016"PRIx64"\n",
+                     val);
+        break;
+    case 0x0d: /* plat */
+        s->plat = val & 0xff00;
+        break;
+    case 0x0f: /* PERROR */
+        break; /* Not emulated.  */
+    case 0x10: /* PERRMASK */
+        s->perrmask = val & 0xfff;
+        break;
+    case 0x13: /* tlbia */
+        /* FIXME: todo */
+        break;
+    case 0x20: /* SPRST */
+        /* Software pci-reset.  FIXME: disable bus?  */
+        break;
+    default:
+        qemu_log("21272: unhandled pchip write reg=%x (%016"PRIx64")\n",
+                 reg, val);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc *typhoon_pchip_read[] = {
+    &illegal_read,
+    &illegal_read,
+    &typhoon_pchip_readl,
+};
+
+static CPUWriteMemoryFunc *typhoon_pchip_write[] = {
+    &illegal_write,
+    &illegal_write,
+    &typhoon_pchip_writel,
+};
+
+
+static void pchip_pci_io_writeb (void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+    cpu_outb(NULL, addr, value);
+}
+
+static uint32_t pchip_pci_io_readb (void *opaque, target_phys_addr_t addr)
+{
+    return cpu_inb(NULL, addr);
+}
+
+static void pchip_pci_io_writew (void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap16(value);
+#endif
+    cpu_outw(NULL, addr, value);
+}
+
+static uint32_t pchip_pci_io_readw (void *opaque, target_phys_addr_t addr)
+{
+    uint32_t ret;
+
+    ret = cpu_inw(NULL, addr);
+#ifdef TARGET_WORDS_BIGENDIAN
+    ret = bswap16(ret);
+#endif
+    return ret;
+}
+
+static void pchip_pci_io_writel (void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
+    cpu_outl(NULL, addr, value);
+}
+
+static uint32_t pchip_pci_io_readl (void *opaque, target_phys_addr_t addr)
+{
+    uint32_t ret;
+
+    ret = cpu_inl(NULL, addr);
+#ifdef TARGET_WORDS_BIGENDIAN
+    ret = bswap32(ret);
+#endif
+    return ret;
+}
+
+static CPUWriteMemoryFunc *pchip_pci_io_write[] = {
+    &pchip_pci_io_writeb,
+    &pchip_pci_io_writew,
+    &pchip_pci_io_writel,
+};
+
+static CPUReadMemoryFunc *pchip_pci_io_read[] = {
+    &pchip_pci_io_readb,
+    &pchip_pci_io_readw,
+    &pchip_pci_io_readl,
+};
+
+static void pchip_pci_cfg_writex (void *opaque, target_phys_addr_t addr,
+                                  uint32_t value, int sz)
+{
+    uint32_t a = addr & 0xffffffU;
+    PchipState *s = opaque;
+
+#ifdef DEBUG_PCICFG
+    fprintf(stderr, "pci_cfg write: addr=%06x, sz=%d %u:%u:%02x, val=%08x\n",
+            a, sz,
+            (a >> 11) & 0x1f, (a >> 8) & 0x7, a & 0xff, value);
+#endif
+
+    pci_data_write(s->pci, a, value, 1 << sz);
+}
+
+static void pchip_pci_cfg_writel (void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
+    pchip_pci_cfg_writex(opaque, addr, value, 2);
+}
+
+static void pchip_pci_cfg_writew (void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap16(value);
+#endif
+    pchip_pci_cfg_writex(opaque, addr, value, 1);
+}
+
+static void pchip_pci_cfg_writeb (void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+    pchip_pci_cfg_writex(opaque, addr, value, 0);
+}
+
+static uint32_t pchip_pci_cfg_readx (void *opaque, target_phys_addr_t addr,
+                                     int sz)
+{
+    uint32_t a = addr & 0xffffffU;
+    PchipState *s = opaque;
+    uint32_t val;
+
+    if (s->num == 0)
+        val = pci_data_read(s->pci, a, 1 << sz);
+    else {
+        switch (sz) {
+        case 0:
+            val = 0xff;
+            break;
+        case 1:
+            val = 0xffff;
+            break;
+        default:
+        case 2:
+            val = 0xffffffff;
+            break;
+        }
+    }
+
+#ifdef DEBUG_PCICFG
+    fprintf(stderr, "pci_cfg  read: addr=%06x, sz=%d %u:%u:%02x, val=%08x\n",
+            a, sz,
+            (a >> 11) & 0x1f, (a >> 8) & 0x7, a & 0xff,
+            val);
+#endif
+
+    return val;
+}
+
+static uint32_t pchip_pci_cfg_readb (void *opaque, target_phys_addr_t addr)
+{
+    return pchip_pci_cfg_readx(opaque, addr, 0);
+}
+
+static uint32_t pchip_pci_cfg_readw (void *opaque, target_phys_addr_t addr)
+{
+    return pchip_pci_cfg_readx(opaque, addr, 1);
+}
+
+static uint32_t pchip_pci_cfg_readl (void *opaque, target_phys_addr_t addr)
+{
+    return pchip_pci_cfg_readx(opaque, addr, 2);
+}
+
+static CPUWriteMemoryFunc *pchip_pci_cfg_write[] = {
+    &pchip_pci_cfg_writeb,
+    &pchip_pci_cfg_writew,
+    &pchip_pci_cfg_writel,
+};
+
+static CPUReadMemoryFunc *pchip_pci_cfg_read[] = {
+    &pchip_pci_cfg_readb,
+    &pchip_pci_cfg_readw,
+    &pchip_pci_cfg_readl,
+};
+
+static void pchip_pci_iack_writex (void *opaque,
+                            target_phys_addr_t addr, uint32_t value)
+{
+    qemu_log("21272: pci iack addr=%08x, val=%08x\n", (uint32_t)addr, value);
+}
+
+static uint32_t pchip_pci_iack_readx (void *opaque, target_phys_addr_t addr)
+{
+    PchipState *s = opaque;
+    uint32_t res;
+
+    /* Ideally we should have a PCIBus interface.  */
+    res = (*s->iack_handler)(s->iack_handler_param);
+    //fprintf(stderr, "21272 iack: addr=%016"PRIx64", res=%d\n", addr, res);
+    return res;
+}
+
+static CPUWriteMemoryFunc *pchip_pci_iack_write[] = {
+    &pchip_pci_iack_writex,
+    &pchip_pci_iack_writex,
+    &pchip_pci_iack_writex,
+};
+
+static CPUReadMemoryFunc *pchip_pci_iack_read[] = {
+    &pchip_pci_iack_readx,
+    &pchip_pci_iack_readx,
+    &pchip_pci_iack_readx,
+};
+
+static void typhoon_reset (void *opaque)
+{
+    TyphoonState *s = opaque;
+
+    s->misc_rev = 8;
+    s->misc_abw = 0;
+}
+
+static void cchip_set_irq(void *opaque, int irq, int level)
+{
+    TyphoonState *s = opaque;
+    uint64_t mask;
+    int i;
+
+#if 0
+    qemu_log("cchip_set_irq: irq=%d level=%d\n", irq, level);
+#endif
+    mask = 1ULL << irq;
+    if (level)
+        s->drir |= mask;
+    else
+        s->drir &= ~mask;
+
+    for (i = 0; i < 4 && s->cpu[i]; i++) {
+        int old = s->b_irq[i];
+        s->dir[i] = s->drir & s->dim[i];
+        if (s->dir[i] >> 58)
+            s->b_irq[i] |= (1 << 0);
+        else
+            s->b_irq[i] &= ~(1 << 0);
+
+        if (s->dir[i] << 8)
+            s->b_irq[i] |= (1 << 1);
+        else
+            s->b_irq[i] &= ~(1 << 1);
+
+#if 0
+        qemu_log("cchip_set_irq: cpu[%d]: drir=%016"PRIx64" dim=%016"PRIx64" "
+                 " dir=%016"PRIx64" birq=%02x\n",
+                 i, s->drir, s->dim[i], s->dir[i], s->b_irq[i]);
+#endif
+        if (s->b_irq[i] != old)
+            cpu_alpha_update_irq(s->cpu[i], s->b_irq[i]);
+    }
+}
+
+static void intim_set_irq(void *opaque, int irq, int level)
+{
+    int i;
+    TyphoonState *s = opaque;
+    unsigned char old;
+
+#if 0
+    {
+        static int cnt;
+        cnt++;
+        if ((cnt % 1024) == 1023)
+            fprintf(stderr, "Clock!\n");
+    }
+#endif
+
+    if (0 && (s->b_irq[0] & 0x04))
+        fprintf(stderr, "!!Interrupt missed\n");
+
+    for (i = 0; i < 4 && s->cpu[i]; i++) {
+        old = s->b_irq[i];
+        if (!(old & (1 << 2))) {
+            s->b_irq[i] |= (1 << 2);
+            cpu_alpha_update_irq(s->cpu[i], s->b_irq[i]);
+        }
+    }
+}
+
+
+static int typhoon_map_irq(PCIDevice *pci_dev, int irq_num)
+{
+    return irq_num;
+}
+
+static void typhoon_set_irq(qemu_irq *pic, int irq_num, int level)
+{
+    /* Never called (yet).  */
+    fprintf(stderr, "typhoon_set_irq: irq_num=%d, level=%d\n", irq_num, level);
+    exit(4);
+}
+
+TyphoonState *typhoon_21272_init (uint64_t *arr, qemu_irq **irqs,
+                                  qemu_irq *intim_irq, void *cpu0)
+{
+    TyphoonState *s;
+    int cchip;
+    int dchip;
+    int pchip;
+    int pci_io;
+    int pci_cfg;
+    int pci_iack;
+    int i;
+
+    s = qemu_mallocz(sizeof(TyphoonState));
+
+    /* Cchip registers.  */
+    cchip = cpu_register_io_memory(0, typhoon_cchip_read,
+                                   typhoon_cchip_write, s);
+    cpu_register_physical_memory(0x801a0000000ULL, 0x0002000, cchip);
+
+    /* Dchip registers.  */
+    dchip = cpu_register_io_memory(0, typhoon_dchip_read,
+                                   typhoon_dchip_write, s);
+    cpu_register_physical_memory(0x801b0000000ULL, 0x0002000, dchip);
+
+    /* Pchip0 registers.  */
+    pchip = cpu_register_io_memory(0, typhoon_pchip_read,
+                                   typhoon_pchip_write, &s->pchip[0]);
+    cpu_register_physical_memory(0x80180000000ULL, 0x0002000, pchip);
+
+    /* Pchip1 registers.  */
+    pchip = cpu_register_io_memory(0, typhoon_pchip_read,
+                                    typhoon_pchip_write, &s->pchip[1]);
+    cpu_register_physical_memory(0x80380000000ULL, 0x0002000, pchip);
+
+    /* Pchip0 PCI I/O  */
+    pci_io = cpu_register_io_memory(0, pchip_pci_io_read,
+                                    pchip_pci_io_write, &s->pchip[0]);
+    cpu_register_physical_memory(0x801fc000000ULL, 0x0010000, pci_io);
+
+    /* Pchip0 PCI cfg  */
+    pci_cfg = cpu_register_io_memory(0, pchip_pci_cfg_read,
+                                    pchip_pci_cfg_write, &s->pchip[0]);
+    cpu_register_physical_memory(0x801fe000000ULL, 0x0010000, pci_cfg);
+
+    /* Pchip0 PCI IntAck  */
+    pci_iack = cpu_register_io_memory(0, pchip_pci_iack_read,
+                                      pchip_pci_iack_write, &s->pchip[0]);
+    cpu_register_physical_memory(0x801f8000000ULL, 0x002000, pci_iack);
+
+    /* Pchip0 PCI cfg  */
+    pci_cfg = cpu_register_io_memory(0, pchip_pci_cfg_read,
+                                    pchip_pci_cfg_write, &s->pchip[1]);
+    cpu_register_physical_memory(0x803fe000000ULL, 0x0010000, pci_cfg);
+
+    s->pchip[0].pci = pci_register_bus(typhoon_set_irq,
+                                       typhoon_map_irq,
+                                       (void *)&s->pchip[0], 0, 64);
+
+    pci_mem_base = 0x80000000000ULL;
+    isa_mem_base = 0x80000000000ULL;
+
+    typhoon_reset(s);
+
+    /* P1 chip present, 8 dchips, 2 memory buses.  */
+    s->csc = (1 << 14) | (3 << 0);
+
+    /* Configure cchip array address.  */
+    for (i = 0; i < 4; i++)
+        s->aar[i] = arr[i];
+
+    s->cpu[0] = cpu0;
+    s->irqs = qemu_allocate_irqs(cchip_set_irq, s, 64);
+    *irqs = s->irqs;
+
+    s->intim_irq = qemu_allocate_irqs(intim_set_irq, s, 1);
+    *intim_irq = s->intim_irq[0];
+
+    qemu_register_reset(&typhoon_reset, s);
+
+    return s;
+}
+
+void typhoon_set_iack_handler(TyphoonState *c, int num,
+                              int (*handler)(void *), void *param)
+{
+    c->pchip[num].iack_handler = handler;
+    c->pchip[num].iack_handler_param = param;
+}
+
+PCIBus *typhoon_get_pci_bus(TyphoonState *c, int num)
+{
+    return c->pchip[num].pci;
+}
diff --git a/hw/pci.h b/hw/pci.h
index e4e0738..4f2496f 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -261,6 +261,14 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
 PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                             qemu_irq *pic, int devfn_min, int nirq);
 
+/* 21272.c */
+typedef struct TyphoonState TyphoonState;
+TyphoonState *typhoon_21272_init (uint64_t *arr, qemu_irq **irqs,
+                                  qemu_irq *intim_irq, void *cpu0);
+void typhoon_set_iack_handler(TyphoonState *c, int num,
+                              int (*handler)(void *), void *param);
+PCIBus *typhoon_get_pci_bus(TyphoonState *c, int num);
+
 /* ali1543.c */
 typedef struct ALI1543State ALI1543State;
 ALI1543State *ali1543_init (PCIBus *bus, int devfn, qemu_irq irq);
-- 
1.6.2

  reply	other threads:[~2009-03-30 14:37 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-30 14:36 [Qemu-devel] [PATCH 0/20]: add alpha es40 system emulation (v4) Tristan Gingold
2009-03-30 14:36 ` [Qemu-devel] [PATCH 01/19] Add support for multi-level phys map Tristan Gingold
2009-03-30 14:36   ` [Qemu-devel] [PATCH 02/19] Increase Alpha physical address size to 44 bits Tristan Gingold
2009-03-30 14:36     ` [Qemu-devel] [PATCH 03/19] Alpha: set target page size to 13 bits Tristan Gingold
2009-03-30 14:36       ` [Qemu-devel] [PATCH 04/19] Allow 5 mmu indexes Tristan Gingold
2009-03-30 14:36         ` [Qemu-devel] [PATCH 05/19] Split cpu_mmu_index into cpu_mmu_index_data and cpu_mmu_index_code Tristan Gingold
2009-03-30 14:36           ` [Qemu-devel] [PATCH 06/19] Bug fix alpha: stop translation if too long Tristan Gingold
2009-03-30 14:36             ` [Qemu-devel] [PATCH 07/19] Alpha bug: fix palcode mask for user pal calls Tristan Gingold
2009-03-30 14:36               ` [Qemu-devel] [PATCH 08/19] Alpha: document more registers used by 21264 Tristan Gingold
2009-03-30 14:36                 ` [Qemu-devel] [PATCH 09/19] Add square wave output support Tristan Gingold
2009-03-30 14:36                   ` [Qemu-devel] [PATCH 10/19] Add ali1543 super IO pci device Tristan Gingold
2009-03-30 14:36                     ` Tristan Gingold [this message]
2009-03-30 14:36                       ` [Qemu-devel] [PATCH 12/19] Add target-alpha/machine.c and hw/es40.c for es40 machine emulation Tristan Gingold
2009-03-30 14:36                         ` [Qemu-devel] [PATCH 13/19] Move softmmu_helper.h from exec.h to op_helper.c on alpha Tristan Gingold
2009-03-30 14:36                           ` [Qemu-devel] [PATCH 14/19] alpha ld helpers now directly return the value Tristan Gingold
2009-03-30 14:36                             ` [Qemu-devel] [PATCH 15/19] Add alpha_cpu_list Tristan Gingold
2009-03-30 14:36                               ` [Qemu-devel] [PATCH 16/19] Alpha: lower parent irq when irq is lowered Tristan Gingold
2009-03-30 14:36                                 ` [Qemu-devel] [PATCH 17/19] Move linux-user pal emulation to linux-user/ Tristan Gingold
2009-03-30 14:36                                   ` [Qemu-devel] [PATCH 18/19] Correctly decode hw_ld/hw_st opcodes for all alpha implementations Tristan Gingold
2009-03-30 14:36                                     ` [Qemu-devel] [PATCH 19/19] Add full emulation for 21264 Tristan Gingold
2009-04-07 21:52                                     ` [Qemu-devel] [PATCH 18/19] Correctly decode hw_ld/hw_st opcodes for all alpha implementations Aurelien Jarno
2009-04-08 12:26                                       ` Tristan Gingold
2009-04-15 14:42                                 ` [Qemu-devel] [PATCH 16/19] Alpha: lower parent irq when irq is lowered Aurelien Jarno
2009-04-07 22:29                   ` [Qemu-devel] [PATCH 09/19] Add square wave output support Aurelien Jarno
2009-04-07 22:32                 ` [Qemu-devel] [PATCH 08/19] Alpha: document more registers used by 21264 Aurelien Jarno
2009-04-07 22:31               ` [Qemu-devel] [PATCH 07/19] Alpha bug: fix palcode mask for user pal calls Aurelien Jarno
2009-04-07 21:44             ` [Qemu-devel] [PATCH 06/19] Bug fix alpha: stop translation if too long Aurelien Jarno
2009-04-15 14:30           ` [Qemu-devel] [PATCH 05/19] Split cpu_mmu_index into cpu_mmu_index_data and cpu_mmu_index_code Aurelien Jarno
2009-04-21 12:10             ` Tristan Gingold
2009-04-07 21:48         ` [Qemu-devel] [PATCH 04/19] Allow 5 mmu indexes Aurelien Jarno
2009-04-07 21:47       ` [Qemu-devel] [PATCH 03/19] Alpha: set target page size to 13 bits Aurelien Jarno
2009-04-15 16:23   ` [Qemu-devel] [PATCH 01/19] Add support for multi-level phys map Aurelien Jarno
2009-04-21 12:11     ` Tristan Gingold
2009-03-30 15:46 ` [Qemu-devel] [PATCH 0/20]: add alpha es40 system emulation (v4) Brian Wheeler
2009-03-30 16:04   ` Tristan Gingold
2009-03-30 16:43     ` Brian Wheeler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1238423794-25455-12-git-send-email-gingold@adacore.com \
    --to=gingold@adacore.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).