From patchwork Sat Dec 8 13:44:37 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 204649 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 069502C0147 for ; Sun, 9 Dec 2012 00:47:17 +1100 (EST) Received: from localhost ([::1]:39110 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ThKkN-0007SP-4K for incoming@patchwork.ozlabs.org; Sat, 08 Dec 2012 08:47:15 -0500 Received: from eggs.gnu.org ([208.118.235.92]:58109) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ThKiq-0005SI-0Q for qemu-devel@nongnu.org; Sat, 08 Dec 2012 08:45:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ThKie-0002GL-M2 for qemu-devel@nongnu.org; Sat, 08 Dec 2012 08:45:39 -0500 Received: from cantor2.suse.de ([195.135.220.15]:36554 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ThKie-0002Ef-4h; Sat, 08 Dec 2012 08:45:28 -0500 Received: from relay1.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id C2BBAA500D; Sat, 8 Dec 2012 14:44:48 +0100 (CET) From: Alexander Graf To: "qemu-ppc@nongnu.org List" Date: Sat, 8 Dec 2012 14:44:37 +0100 Message-Id: <1354974282-1915-15-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1354974282-1915-1-git-send-email-agraf@suse.de> References: <1354974282-1915-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 195.135.220.15 Cc: qemu-devel qemu-devel Subject: [Qemu-devel] [PATCH 14/19] openpic: convert to qdev X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch converts the OpenPIC device to qdev. Along the way it renames the "openpic" target to "raven" and the "mpic" target to "mpc8544", to better reflect the actual models they implement. This way we have a generic OpenPIC device now that can handle different flavors of the OpenPIC specification. Signed-off-by: Alexander Graf --- hw/openpic.c | 278 ++++++++++++++++++++++++++--------------------------- hw/openpic.h | 8 +- hw/ppc/e500.c | 24 ++++- hw/ppc_newworld.c | 25 +++++- 4 files changed, 180 insertions(+), 155 deletions(-) diff --git a/hw/openpic.c b/hw/openpic.c index 321c6d4..6aac4b8 100644 --- a/hw/openpic.c +++ b/hw/openpic.c @@ -37,6 +37,7 @@ #include "ppc_mac.h" #include "pci.h" #include "openpic.h" +#include "sysbus.h" //#define DEBUG_OPENPIC @@ -53,30 +54,10 @@ #define MAX_IPI 4 #define VID 0x03 /* MPIC version ID */ -enum { - IRQ_IPVP = 0, - IRQ_IDE, -}; - -/* OpenPIC */ -#define OPENPIC_MAX_CPU 2 -#define OPENPIC_MAX_IRQ 64 -#define OPENPIC_EXT_IRQ 48 -#define OPENPIC_MAX_TMR MAX_TMR -#define OPENPIC_MAX_IPI MAX_IPI - -/* Interrupt definitions */ -#define OPENPIC_IRQ_FE (OPENPIC_EXT_IRQ) /* Internal functional IRQ */ -#define OPENPIC_IRQ_ERR (OPENPIC_EXT_IRQ + 1) /* Error IRQ */ -#define OPENPIC_IRQ_TIM0 (OPENPIC_EXT_IRQ + 2) /* First timer IRQ */ -#if OPENPIC_MAX_IPI > 0 -#define OPENPIC_IRQ_IPI0 (OPENPIC_IRQ_TIM0 + OPENPIC_MAX_TMR) /* First IPI IRQ */ -#define OPENPIC_IRQ_DBL0 (OPENPIC_IRQ_IPI0 + (OPENPIC_MAX_CPU * OPENPIC_MAX_IPI)) /* First doorbell IRQ */ -#else -#define OPENPIC_IRQ_DBL0 (OPENPIC_IRQ_TIM0 + OPENPIC_MAX_TMR) /* First doorbell IRQ */ -#define OPENPIC_IRQ_MBX0 (OPENPIC_IRQ_DBL0 + OPENPIC_MAX_DBL) /* First mailbox IRQ */ -#endif +/* OpenPIC capability flags */ +#define OPENPIC_FLAG_IDE_CRIT (1 << 0) +/* OpenPIC address map */ #define OPENPIC_GLB_REG_START 0x0 #define OPENPIC_GLB_REG_SIZE 0x10F0 #define OPENPIC_TMR_REG_START 0x10F0 @@ -86,31 +67,37 @@ enum { #define OPENPIC_CPU_REG_START 0x20000 #define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) -/* MPIC */ -#define MPIC_MAX_CPU 1 -#define MPIC_MAX_EXT 12 -#define MPIC_MAX_INT 64 -#define MPIC_MAX_IRQ MAX_IRQ +/* Raven */ +#define RAVEN_MAX_CPU 2 +#define RAVEN_MAX_EXT 48 +#define RAVEN_MAX_IRQ 64 +#define RAVEN_MAX_TMR MAX_TMR +#define RAVEN_MAX_IPI MAX_IPI + +/* Interrupt definitions */ +#define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */ +#define RAVEN_ERR_IRQ (RAVEN_MAX_EXT + 1) /* Error IRQ */ +#define RAVEN_TMR_IRQ (RAVEN_MAX_EXT + 2) /* First timer IRQ */ +#define RAVEN_IPI_IRQ (RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */ +/* First doorbell IRQ */ +#define RAVEN_DBL_IRQ (RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI)) + +/* MPC8544 */ +#define MPC8544_MAX_CPU 1 +#define MPC8544_MAX_EXT 12 +#define MPC8544_MAX_INT 64 +#define MPC8544_MAX_IRQ MAX_IRQ /* Interrupt definitions */ /* IRQs, accessible through the IRQ region */ -#define MPIC_EXT_IRQ 0x00 -#define MPIC_INT_IRQ 0x10 -#define MPIC_MSG_IRQ 0xb0 -#define MPIC_MSI_IRQ 0xe0 +#define MPC8544_EXT_IRQ 0x00 +#define MPC8544_INT_IRQ 0x10 +#define MPC8544_MSG_IRQ 0xb0 +#define MPC8544_MSI_IRQ 0xe0 /* These are available through separate regions, but for simplicity's sake mapped into the same number space */ -#define MPIC_TMR_IRQ 0xf3 -#define MPIC_IPI_IRQ 0xfb - -#define MPIC_GLB_REG_START 0x0 -#define MPIC_GLB_REG_SIZE 0x10F0 -#define MPIC_TMR_REG_START 0x10F0 -#define MPIC_TMR_REG_SIZE 0x220 -#define MPIC_SRC_REG_START 0x10000 -#define MPIC_SRC_REG_SIZE (MAX_IRQ * 0x20) -#define MPIC_CPU_REG_START 0x20000 -#define MPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) +#define MPC8544_TMR_IRQ 0xf3 +#define MPC8544_IPI_IRQ 0xfb /* * Block Revision Register1 (BRR1): QEMU does not fully emulate @@ -128,6 +115,7 @@ enum { #define FREP_VID_SHIFT 0 #define VID_REVISION_1_2 2 +#define VID_REVISION_1_3 3 #define VENI_GENERIC 0x00000000 /* Generic Vendor ID */ @@ -204,10 +192,11 @@ typedef struct IRQ_dst_t { } IRQ_dst_t; typedef struct OpenPICState { - PCIDevice pci_dev; + SysBusDevice busdev; MemoryRegion mem; /* Behavior control */ + uint32_t model; uint32_t flags; uint32_t nb_irqs; uint32_t vid; @@ -230,15 +219,15 @@ typedef struct OpenPICState { IRQ_src_t src[MAX_IRQ]; /* Local registers per output pin */ IRQ_dst_t dst[MAX_CPU]; - int nb_cpus; + uint32_t nb_cpus; /* Timer registers */ struct { uint32_t ticc; /* Global timer current count register */ uint32_t tibc; /* Global timer base count register */ } timers[MAX_TMR]; - int max_irq; - int irq_ipi0; - int irq_tim0; + uint32_t max_irq; + uint32_t irq_ipi0; + uint32_t irq_tim0; } OpenPICState; static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQ_src_t *src); @@ -410,9 +399,9 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level) openpic_update_irq(opp, n_IRQ); } -static void openpic_reset (void *opaque) +static void openpic_reset(DeviceState *d) { - OpenPICState *opp = (OpenPICState *)opaque; + OpenPICState *opp = FROM_SYSBUS(typeof (*opp), sysbus_from_qdev(d)); int i; opp->glbc = 0x80000000; @@ -505,7 +494,7 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val, break; case 0x1020: /* GLBC */ if (val & 0x80000000) { - openpic_reset(opp); + openpic_reset(&opp->busdev.qdev); } break; case 0x1080: /* VENI */ @@ -970,7 +959,7 @@ static void openpic_save(QEMUFile* f, void *opaque) qemu_put_sbe32s(f, &opp->src[i].pending); } - qemu_put_sbe32s(f, &opp->nb_cpus); + qemu_put_be32s(f, &opp->nb_cpus); for (i = 0; i < opp->nb_cpus; i++) { qemu_put_be32s(f, &opp->dst[i].pctp); @@ -983,8 +972,6 @@ static void openpic_save(QEMUFile* f, void *opaque) qemu_put_be32s(f, &opp->timers[i].ticc); qemu_put_be32s(f, &opp->timers[i].tibc); } - - pci_device_save(&opp->pci_dev, f); } static void openpic_load_IRQ_queue(QEMUFile* f, IRQ_queue_t *q) @@ -1019,7 +1006,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id) qemu_get_sbe32s(f, &opp->src[i].pending); } - qemu_get_sbe32s(f, &opp->nb_cpus); + qemu_get_be32s(f, &opp->nb_cpus); for (i = 0; i < opp->nb_cpus; i++) { qemu_get_be32s(f, &opp->dst[i].pctp); @@ -1033,7 +1020,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id) qemu_get_be32s(f, &opp->timers[i].tibc); } - return pci_device_load(&opp->pci_dev, f); + return 0; } static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQ_src_t *src) @@ -1047,17 +1034,18 @@ static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQ_src_t *src) } } -qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus, - qemu_irq **irqs) +struct memreg { + const char *name; + MemoryRegionOps const *ops; + hwaddr start_addr; + ram_addr_t size; +}; + +static int openpic_init(SysBusDevice *dev) { - OpenPICState *opp; - int i; - struct { - const char *name; - MemoryRegionOps const *ops; - hwaddr start_addr; - ram_addr_t size; - } const list[] = { + OpenPICState *opp = FROM_SYSBUS(typeof (*opp), dev); + int i, j; + const struct memreg list_le[] = { {"glb", &openpic_glb_ops_le, OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE}, {"tmr", &openpic_tmr_ops_le, OPENPIC_TMR_REG_START, @@ -1067,16 +1055,57 @@ qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus, {"cpu", &openpic_cpu_ops_le, OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE}, }; + const struct memreg list_be[] = { + {"glb", &openpic_glb_ops_be, OPENPIC_GLB_REG_START, + OPENPIC_GLB_REG_SIZE}, + {"tmr", &openpic_tmr_ops_be, OPENPIC_TMR_REG_START, + OPENPIC_TMR_REG_SIZE}, + {"src", &openpic_src_ops_be, OPENPIC_SRC_REG_START, + OPENPIC_SRC_REG_SIZE}, + {"cpu", &openpic_cpu_ops_be, OPENPIC_CPU_REG_START, + OPENPIC_CPU_REG_SIZE}, + }; + struct memreg const *list; - /* XXX: for now, only one CPU is supported */ - if (nb_cpus != 1) - return NULL; - opp = g_malloc0(sizeof(OpenPICState)); + switch (opp->model) { + case OPENPIC_MODEL_MPC8544: + default: + opp->flags |= OPENPIC_FLAG_IDE_CRIT; + opp->nb_irqs = 80; + opp->vid = VID_REVISION_1_2; + opp->veni = VENI_GENERIC; + opp->spve_mask = 0xFFFF; + opp->tifr_reset = 0x00000000; + opp->ipvp_reset = 0x80000000; + opp->ide_reset = 0x00000001; + opp->max_irq = MPC8544_MAX_IRQ; + opp->irq_ipi0 = MPC8544_IPI_IRQ; + opp->irq_tim0 = MPC8544_TMR_IRQ; + list = list_be; + break; + case OPENPIC_MODEL_RAVEN: + opp->nb_irqs = RAVEN_MAX_EXT; + opp->vid = VID_REVISION_1_3; + opp->veni = VENI_GENERIC; + opp->spve_mask = 0xFF; + opp->tifr_reset = 0x003F7A00; + opp->ipvp_reset = 0xA0000000; + opp->ide_reset = 0x00000000; + opp->max_irq = RAVEN_MAX_IRQ; + opp->irq_ipi0 = RAVEN_IPI_IRQ; + opp->irq_tim0 = RAVEN_TMR_IRQ; + list = list_le; + + /* Only UP supported today */ + if (opp->nb_cpus != 1) { + return -EINVAL; + } + break; + } memory_region_init(&opp->mem, "openpic", 0x40000); - for (i = 0; i < ARRAY_SIZE(list); i++) { - + for (i = 0; i < ARRAY_SIZE(list_le); i++) { memory_region_init_io(&opp->sub_io_mem[i], list[i].ops, opp, list[i].name, list[i].size); @@ -1084,83 +1113,48 @@ qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus, &opp->sub_io_mem[i]); } - // isu_base &= 0xFFFC0000; - opp->nb_cpus = nb_cpus; - opp->nb_irqs = OPENPIC_EXT_IRQ; - opp->vid = VID; - opp->veni = VENI_GENERIC; - opp->spve_mask = 0xFF; - opp->tifr_reset = 0x003F7A00; - opp->max_irq = OPENPIC_MAX_IRQ; - opp->irq_ipi0 = OPENPIC_IRQ_IPI0; - opp->irq_tim0 = OPENPIC_IRQ_TIM0; - - for (i = 0; i < nb_cpus; i++) - opp->dst[i].irqs = irqs[i]; - - register_savevm(&opp->pci_dev.qdev, "openpic", 0, 2, + for (i = 0; i < opp->nb_cpus; i++) { + opp->dst[i].irqs = g_new(qemu_irq, OPENPIC_OUTPUT_NB); + for (j = 0; j < OPENPIC_OUTPUT_NB; j++) { + sysbus_init_irq(dev, &opp->dst[i].irqs[j]); + } + } + + register_savevm(&opp->busdev.qdev, "openpic", 0, 2, openpic_save, openpic_load, opp); - qemu_register_reset(openpic_reset, opp); - if (pmem) - *pmem = &opp->mem; + sysbus_init_mmio(dev, &opp->mem); + qdev_init_gpio_in(&dev->qdev, openpic_set_irq, opp->max_irq); - return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq); + return 0; } -qemu_irq *mpic_init (MemoryRegion *address_space, hwaddr base, - int nb_cpus, qemu_irq **irqs) -{ - OpenPICState *mpp; - int i; - struct { - const char *name; - MemoryRegionOps const *ops; - hwaddr start_addr; - ram_addr_t size; - } const list[] = { - {"glb", &openpic_glb_ops_be, MPIC_GLB_REG_START, MPIC_GLB_REG_SIZE}, - {"tmr", &openpic_tmr_ops_be, MPIC_TMR_REG_START, MPIC_TMR_REG_SIZE}, - {"src", &openpic_src_ops_be, MPIC_SRC_REG_START, MPIC_SRC_REG_SIZE}, - {"cpu", &openpic_cpu_ops_be, MPIC_CPU_REG_START, MPIC_CPU_REG_SIZE}, - }; - - mpp = g_malloc0(sizeof(OpenPICState)); - - memory_region_init(&mpp->mem, "mpic", 0x40000); - memory_region_add_subregion(address_space, base, &mpp->mem); +static Property openpic_properties[] = { + DEFINE_PROP_UINT32("model", OpenPICState, model, OPENPIC_MODEL_MPC8544), + DEFINE_PROP_UINT32("nb_cpus", OpenPICState, nb_cpus, 1), + DEFINE_PROP_END_OF_LIST(), +}; - for (i = 0; i < sizeof(list)/sizeof(list[0]); i++) { +static void openpic_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - memory_region_init_io(&mpp->sub_io_mem[i], list[i].ops, mpp, - list[i].name, list[i].size); + k->init = openpic_init; + dc->props = openpic_properties; + dc->reset = openpic_reset; +} - memory_region_add_subregion(&mpp->mem, list[i].start_addr, - &mpp->sub_io_mem[i]); - } +static TypeInfo openpic_info = { + .name = "openpic", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(OpenPICState), + .class_init = openpic_class_init, +}; - mpp->nb_cpus = nb_cpus; - /* 12 external sources, 48 internal sources , 4 timer sources, - 4 IPI sources, 4 messaging sources, and 8 Shared MSI sources */ - mpp->nb_irqs = 80; - mpp->vid = VID_REVISION_1_2; - mpp->veni = VENI_GENERIC; - mpp->spve_mask = 0xFFFF; - mpp->tifr_reset = 0x00000000; - mpp->ipvp_reset = 0x80000000; - mpp->ide_reset = 0x00000001; - mpp->max_irq = MPIC_MAX_IRQ; - mpp->irq_ipi0 = MPIC_IPI_IRQ; - mpp->irq_tim0 = MPIC_TMR_IRQ; - - for (i = 0; i < nb_cpus; i++) - mpp->dst[i].irqs = irqs[i]; - - /* Enable critical interrupt support */ - mpp->flags |= OPENPIC_FLAG_IDE_CRIT; - - register_savevm(NULL, "mpic", 0, 2, openpic_save, openpic_load, mpp); - qemu_register_reset(openpic_reset, mpp); - - return qemu_allocate_irqs(openpic_set_irq, mpp, mpp->max_irq); +static void openpic_register_types(void) +{ + type_register_static(&openpic_info); } + +type_init(openpic_register_types) diff --git a/hw/openpic.h b/hw/openpic.h index 8a68f20..824609c 100644 --- a/hw/openpic.h +++ b/hw/openpic.h @@ -11,11 +11,7 @@ enum { OPENPIC_OUTPUT_NB, }; -/* OpenPIC capability flags */ -#define OPENPIC_FLAG_IDE_CRIT (1 << 0) +#define OPENPIC_MODEL_RAVEN 0 +#define OPENPIC_MODEL_MPC8544 1 -qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus, - qemu_irq **irqs); -qemu_irq *mpic_init (MemoryRegion *address_space, hwaddr base, - int nb_cpus, qemu_irq **irqs); #endif /* __OPENPIC_H__ */ diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 3f6d58c..f9893ad 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -418,7 +418,7 @@ void ppce500_init(PPCE500Params *params) target_ulong dt_base = 0; target_ulong initrd_base = 0; target_long initrd_size=0; - int i=0; + int i = 0, j, k; unsigned int pci_irq_nrs[4] = {1, 2, 3, 4}; qemu_irq **irqs, *mpic; DeviceState *dev; @@ -492,13 +492,27 @@ void ppce500_init(PPCE500Params *params) ccsr_addr_space); /* MPIC */ - mpic = mpic_init(ccsr_addr_space, MPC8544_MPIC_REGS_OFFSET, - smp_cpus, irqs); + mpic = g_new(qemu_irq, 256); + dev = qdev_create(NULL, "openpic"); + qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus); + qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_MPC8544); + qdev_init_nofail(dev); + s = sysbus_from_qdev(dev); + + k = 0; + for (i = 0; i < smp_cpus; i++) { + for (j = 0; j < OPENPIC_OUTPUT_NB; j++) { + sysbus_connect_irq(s, k++, irqs[i][j]); + } + } - if (!mpic) { - cpu_abort(env, "MPIC failed to initialize\n"); + for (i = 0; i < 256; i++) { + mpic[i] = qdev_get_gpio_in(dev, i); } + memory_region_add_subregion(ccsr_addr_space, MPC8544_MPIC_REGS_OFFSET, + s->mmio[0].memory); + /* Serial */ if (serial_hds[0]) { serial_mm_init(ccsr_addr_space, MPC8544_SERIAL0_REGS_OFFSET, diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index b9c2cd8..8c2114e 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -67,6 +67,7 @@ #include "hw/usb.h" #include "blockdev.h" #include "exec-memory.h" +#include "sysbus.h" #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf0000510 @@ -141,7 +142,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) char *filename; qemu_irq *pic, **openpic_irqs; MemoryRegion *unin_memory = g_new(MemoryRegion, 1); - int linux_boot, i; + int linux_boot, i, j, k; MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1); hwaddr kernel_base, initrd_base, cmdline_base = 0; long kernel_size, initrd_size; @@ -156,6 +157,8 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) void *fw_cfg; void *dbdma; int machine_arch; + SysBusDevice *s; + DeviceState *dev; linux_boot = (kernel_filename != NULL); @@ -320,7 +323,25 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) exit(1); } } - pic = openpic_init(&pic_mem, smp_cpus, openpic_irqs); + + pic = g_new(qemu_irq, 64); + + dev = qdev_create(NULL, "openpic"); + qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_RAVEN); + qdev_init_nofail(dev); + s = sysbus_from_qdev(dev); + pic_mem = s->mmio[0].memory; + k = 0; + for (i = 0; i < smp_cpus; i++) { + for (j = 0; j < OPENPIC_OUTPUT_NB; j++) { + sysbus_connect_irq(s, k++, openpic_irqs[i][j]); + } + } + + for (i = 0; i < 64; i++) { + pic[i] = qdev_get_gpio_in(dev, i); + } + if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());