From patchwork Sun Aug 1 17:37:06 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Herv=C3=A9_Poussineau?= X-Patchwork-Id: 60471 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 29BAAB70AA for ; Mon, 2 Aug 2010 04:12:53 +1000 (EST) Received: from localhost ([127.0.0.1]:44429 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ofd1m-0006pn-06 for incoming@patchwork.ozlabs.org; Sun, 01 Aug 2010 14:12:50 -0400 Received: from [140.186.70.92] (port=41772 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ofczs-0006o0-C0 for qemu-devel@nongnu.org; Sun, 01 Aug 2010 14:10:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Ofczq-0005u3-LQ for qemu-devel@nongnu.org; Sun, 01 Aug 2010 14:10:52 -0400 Received: from smtp5-g21.free.fr ([212.27.42.5]:43108) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Ofczp-0005tf-S2 for qemu-devel@nongnu.org; Sun, 01 Aug 2010 14:10:50 -0400 Received: from localhost.localdomain (unknown [88.171.126.33]) by smtp5-g21.free.fr (Postfix) with ESMTP id 46CFCD4813F; Sun, 1 Aug 2010 20:10:44 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Sun, 1 Aug 2010 19:37:06 +0200 Message-Id: <1280684242-19611-4-git-send-email-hpoussin@reactos.org> X-Mailer: git-send-email 1.7.1.GIT In-Reply-To: <4C5579DA.8050508@reactos.org> References: <4C5579DA.8050508@reactos.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Subject: [Qemu-devel] [PATCH 04/20] [MIPS] rc4030: convert to qdev X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org rc4030_init() function will be removed later, once all rc4030 devices are converted to qdev Signed-off-by: Hervé Poussineau --- hw/mips.h | 9 --- hw/mips_jazz.c | 3 +- hw/rc4030.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++----- hw/rc4030.h | 41 ++++++++++++++ 4 files changed, 199 insertions(+), 24 deletions(-) create mode 100644 hw/rc4030.h diff --git a/hw/mips.h b/hw/mips.h index 617ea10..55fb701 100644 --- a/hw/mips.h +++ b/hw/mips.h @@ -23,15 +23,6 @@ void mipsnet_init(int base, qemu_irq irq, NICInfo *nd); /* jazz_led.c */ extern void jazz_led_init(target_phys_addr_t base); -/* rc4030.c */ -typedef struct rc4030DMAState *rc4030_dma; -void rc4030_dma_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len, int is_write); -void rc4030_dma_read(void *dma, uint8_t *buf, int len); -void rc4030_dma_write(void *dma, uint8_t *buf, int len); - -void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, - qemu_irq **irqs, rc4030_dma **dmas); - /* dp8393x.c */ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift, qemu_irq irq, void* mem_opaque, diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c index 78ef8f0..c000fd3 100644 --- a/hw/mips_jazz.c +++ b/hw/mips_jazz.c @@ -36,6 +36,7 @@ #include "mips-bios.h" #include "loader.h" #include "mc146818rtc.h" +#include "rc4030.h" enum jazz_model_e { @@ -178,7 +179,7 @@ void mips_jazz_init (ram_addr_t ram_size, } /* Chipset */ - rc4030_opaque = rc4030_init(qdev_get_gpio_in(cpu->parent, 6), qdev_get_gpio_in(cpu->parent, 3), &rc4030, &dmas); + rc4030_opaque = rc4030_init(cpu, &rc4030, &dmas); s_dma_dummy = cpu_register_io_memory(dma_dummy_read, dma_dummy_write, NULL); cpu_register_physical_memory(0x8000d000, 0x00001000, s_dma_dummy); diff --git a/hw/rc4030.c b/hw/rc4030.c index 2231373..3c8cdfa 100644 --- a/hw/rc4030.c +++ b/hw/rc4030.c @@ -23,8 +23,12 @@ */ #include "hw.h" -#include "mips.h" +#include "monitor.h" #include "qemu-timer.h" +#include "rc4030.h" + +/* As long as we can't include mips_cpudevs.h ... */ +void cpu_mips_register(DeviceInfo *info); /********************************************************/ /* debug rc4030 */ @@ -47,6 +51,13 @@ do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } whi /********************************************************/ /* rc4030 emulation */ +struct RC4030Bus { + BusState qbus; + rc4030_dma *dmas; + uint32_t assigned; +}; +static RC4030Bus *rc4030bus; + typedef struct dma_pagetable_entry { int32_t frame; int32_t owner; @@ -65,6 +76,9 @@ typedef struct dma_pagetable_entry { typedef struct rc4030State { + DeviceState busdev; + RC4030Bus bus; + uint32_t config; /* 0x0000: RC4030 config register */ uint32_t revision; /* 0x0008: RC4030 Revision register */ uint32_t invalid_address_register; /* 0x0010: Invalid Address register */ @@ -461,7 +475,8 @@ static void update_jazz_irq(rc4030State *s) static void rc4030_irq_jazz_request(void *opaque, int irq, int level) { - rc4030State *s = opaque; + DeviceState *dev = opaque; + rc4030State *s = container_of(dev, rc4030State, busdev); if (level) { s->isr_jazz |= 1 << irq; @@ -585,9 +600,9 @@ static CPUWriteMemoryFunc * const jazzio_write[3] = { jazzio_writel, }; -static void rc4030_reset(void *opaque) +static void rc4030_reset(DeviceState *d) { - rc4030State *s = opaque; + rc4030State *s = container_of(d, rc4030State, busdev); int i; s->config = 0x410; /* some boards seem to accept 0x104 too */ @@ -797,29 +812,156 @@ static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n) return s; } -void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, - qemu_irq **irqs, rc4030_dma **dmas) +void *rc4030_get_opaque(void) { rc4030State *s; + + if (!rc4030bus) { + hw_error("Tried to get rc4030 pointer with no rc4030 bus present.\n"); + } + s = container_of(rc4030bus, rc4030State, bus); + + return s; +} + +rc4030_dma rc4030_get_dma(int dma) +{ + if (!rc4030bus) { + hw_error("Tried to get rc4030 dma channel %d with no rc4030 bus present.\n", + dma); + } + return rc4030bus->dmas[dma]; +} + +static void rc4030bus_dev_print(Monitor *mon, DeviceState *dev, int indent) +{ + RC4030Device *d = DO_UPCAST(RC4030Device, qdev, dev); + + if (d->rc4030irq[1] != -1) { + monitor_printf(mon, "%*src4030 irqs %d,%d\n", indent, "", + d->rc4030irq[0], d->rc4030irq[1]); + } else if (d->rc4030irq[0] != -1) { + monitor_printf(mon, "%*src4030 irq %d\n", indent, "", + d->rc4030irq[0]); + } +} + +static struct BusInfo rc4030_bus_info = { + .name = "rc4030", + .size = sizeof(RC4030Bus), + .print_dev = rc4030bus_dev_print, +}; + +static int rc4030_init1(DeviceState *dev, DeviceInfo *base) +{ + rc4030State *s = container_of(dev, rc4030State, busdev); int s_chipset, s_jazzio; - s = qemu_mallocz(sizeof(rc4030State)); + if (rc4030bus) { + return 1; + } - *irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16); - *dmas = rc4030_allocate_dmas(s, 4); + qbus_create_inplace(&s->bus.qbus, &rc4030_bus_info, dev, NULL); + qdev_init_gpio_in(dev, rc4030_irq_jazz_request, 16); + s->bus.dmas = rc4030_allocate_dmas(s, 4); s->periodic_timer = qemu_new_timer(vm_clock, rc4030_periodic_timer, s); - s->timer_irq = timer; - s->jazz_bus_irq = jazz_bus; + s->timer_irq = qdev_get_gpio_in(qdev_get_parent_bus(dev)->parent, 6); + s->jazz_bus_irq = qdev_get_gpio_in(qdev_get_parent_bus(dev)->parent, 3); - qemu_register_reset(rc4030_reset, s); register_savevm(NULL, "rc4030", 0, 2, rc4030_save, rc4030_load, s); - rc4030_reset(s); s_chipset = cpu_register_io_memory(rc4030_read, rc4030_write, s); cpu_register_physical_memory(0x80000000, 0x300, s_chipset); s_jazzio = cpu_register_io_memory(jazzio_read, jazzio_write, s); cpu_register_physical_memory(0xf0000000, 0x00001000, s_jazzio); - return s; + rc4030bus = &s->bus; + + return 0; +} + +void rc4030_init_irq(RC4030Device *dev, qemu_irq *p, int rc4030irq) +{ + assert(dev->nirqs < ARRAY_SIZE(dev->rc4030irq)); + if (rc4030bus->assigned & (1 << rc4030irq)) { + RC4030_ERROR("rc4030 irq %d already assigned\n", rc4030irq); + exit(1); + } + rc4030bus->assigned |= (1 << rc4030irq); + dev->rc4030irq[dev->nirqs] = rc4030irq; + *p = qdev_get_gpio_in(rc4030bus->qbus.parent, rc4030irq); + dev->nirqs++; } + +static int rc4030_qdev_init(DeviceState *qdev, DeviceInfo *base) +{ + RC4030Device *dev = DO_UPCAST(RC4030Device, qdev, qdev); + RC4030DeviceInfo *info = DO_UPCAST(RC4030DeviceInfo, qdev, base); + + dev->rc4030irq[0] = -1; + dev->rc4030irq[1] = -1; + + return info->init(dev); +} + +void rc4030_qdev_register(RC4030DeviceInfo *info) +{ + info->qdev.init = rc4030_qdev_init; + info->qdev.bus_info = &rc4030_bus_info; + qdev_register(&info->qdev); +} + +RC4030Device *rc4030_create(const char *name) +{ + DeviceState *dev; + + if (!rc4030bus) { + hw_error("Tried to create rc4030 device %s with no rc4030 bus present.\n", + name); + } + dev = qdev_create(&rc4030bus->qbus, name); + return DO_UPCAST(RC4030Device, qdev, dev); +} + +RC4030Device *rc4030_create_simple(const char *name) +{ + RC4030Device *dev; + + dev = rc4030_create(name); + qdev_init_nofail(&dev->qdev); + return dev; +} + +extern struct BusInfo cpu_bus_info; +static DeviceInfo rc4030_info = { + .name = "rc4030", + .size = sizeof(rc4030State), + .reset = rc4030_reset, + .init = rc4030_init1, +}; + +static void rc4030_register_devices(void) +{ + cpu_mips_register(&rc4030_info); +} + +device_init(rc4030_register_devices) + +void *rc4030_init(BusState *bus, + qemu_irq **irqs, rc4030_dma **dmas) +{ + DeviceState *dev; + rc4030State* rc4030; + + dev = qdev_create(bus, "rc4030"); + qdev_init_nofail(dev); + + rc4030 = DO_UPCAST(rc4030State, busdev, dev); + + *irqs = rc4030->busdev.gpio_in; + *dmas = rc4030->bus.dmas; + + return rc4030; +} + diff --git a/hw/rc4030.h b/hw/rc4030.h new file mode 100644 index 0000000..58522f3 --- /dev/null +++ b/hw/rc4030.h @@ -0,0 +1,41 @@ +#ifndef HW_RC4030_H +#define HW_RC4030_H + +/* RC4030 bus */ + +#include "qdev.h" + +typedef struct RC4030Bus RC4030Bus; +typedef struct RC4030Device RC4030Device; +typedef struct RC4030DeviceInfo RC4030DeviceInfo; + +struct RC4030Device { + DeviceState qdev; + uint32_t rc4030irq[2]; + int nirqs; +}; + +typedef int (*rc4030_qdev_initfn)(RC4030Device *dev); +struct RC4030DeviceInfo { + DeviceInfo qdev; + rc4030_qdev_initfn init; +}; + +void rc4030_init_irq(RC4030Device *dev, qemu_irq *p, int rc4030irq); +void rc4030_qdev_register(RC4030DeviceInfo *info); +RC4030Device *rc4030_create(const char *name); +RC4030Device *rc4030_create_simple(const char *name); + +typedef struct rc4030DMAState *rc4030_dma; +void rc4030_dma_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len, int is_write); +void rc4030_dma_read(void *dma, uint8_t *buf, int len); +void rc4030_dma_write(void *dma, uint8_t *buf, int len); + +void *rc4030_get_opaque(void); +rc4030_dma rc4030_get_dma(int dma); + +/* Non-qdev compatibility stuff... */ +void *rc4030_init(BusState *parent, + qemu_irq **irqs, rc4030_dma **dmas); + +#endif