qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/4] qdev: isa bus.
@ 2009-07-09 13:02 Gerd Hoffmann
  2009-07-09 13:02 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2009-07-09 13:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

This is a proof-of-concept / RfC patch series to add isa bus support to
qdev.  It adds isa-bus.c and converts one user (pc keyboard+mouse).

I've tried to also handle isa-via-mmio used by certain architectures and
hide that in isa-bus.c, so the individual drivers don't have to care
once everything is converted over to qdev.

Reviews especially from people knowing non-pc archs better than I do are
very welcome.

thanks,
  Gerd

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev.
  2009-07-09 13:02 [Qemu-devel] [PATCH 0/4] qdev: isa bus Gerd Hoffmann
@ 2009-07-09 13:02 ` Gerd Hoffmann
  2009-07-09 13:02 ` [Qemu-devel] [PATCH 2/4] qdev/isa: add qdev support to i8042 (aka ps/2 kbd+mouse) Gerd Hoffmann
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2009-07-09 13:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

The implementation tries to cover both the pc-ish ioport case and the
mmio-based isa port access found in other architectures.  The common
code in isa-bus.c handles mmio internally, so the separate init path for
mmio present in many drivers can go away once all users are switched
over to qdev.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.target |    8 +-
 hw/isa-bus.c    |  216 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/isa.h        |   31 ++++++++
 3 files changed, 251 insertions(+), 4 deletions(-)
 create mode 100644 hw/isa-bus.c

diff --git a/Makefile.target b/Makefile.target
index a593503..1a865fa 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -562,7 +562,7 @@ obj-y += wdt_ib700.o wdt_i6300esb.o
 
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
-obj-y += ide.o pckbd.o vga.o $(sound-obj-y) dma.o
+obj-y += ide.o pckbd.o vga.o $(sound-obj-y) dma.o isa-bus.o
 obj-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
 obj-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o
 obj-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
@@ -572,7 +572,7 @@ endif
 ifeq ($(TARGET_BASE_ARCH), ppc)
 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
 # shared objects
-obj-y += ppc.o ide.o vga.o $(sound-obj-y) dma.o openpic.o
+obj-y += ppc.o ide.o vga.o $(sound-obj-y) dma.o isa-bus.o openpic.o
 # PREP target
 obj-y += pckbd.o serial.o i8259.o i8254.o fdc.o mc146818rtc.o
 obj-y += prep_pci.o ppc_prep.o
@@ -598,7 +598,7 @@ obj-y += mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-y += mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o rc4030.o
 obj-y += g364fb.o jazz_led.o dp8393x.o
 obj-y += ide.o gt64xxx.o pckbd.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o
-obj-y += piix_pci.o parallel.o cirrus_vga.o pcspk.o $(sound-obj-y)
+obj-y += piix_pci.o parallel.o cirrus_vga.o isa-bus.o pcspk.o $(sound-obj-y)
 obj-y += mipsnet.o
 obj-y += pflash_cfi01.o
 obj-y += vmware_vga.o
@@ -634,7 +634,7 @@ obj-y += pflash_cfi02.o
 endif
 ifeq ($(TARGET_BASE_ARCH), sparc)
 ifeq ($(TARGET_ARCH), sparc64)
-obj-y += sun4u.o ide.o pckbd.o vga.o apb_pci.o
+obj-y += sun4u.o ide.o isa-bus.o pckbd.o vga.o apb_pci.o
 obj-y += fdc.o mc146818rtc.o serial.o
 obj-y += cirrus_vga.o parallel.o
 else
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
new file mode 100644
index 0000000..96f95a9
--- /dev/null
+++ b/hw/isa-bus.c
@@ -0,0 +1,216 @@
+#include "hw.h"
+#include "sysemu.h"
+#include "isa.h"
+
+typedef struct ISAMMIO {
+    ISADevice     *dev;
+    ISADeviceInfo *info;
+    int           region;
+    int           io_memory;
+} ISAMMIO;
+
+struct ISABus {
+    BusState qbus;
+    int mmio;
+    int it_shift;
+};
+static ISABus *isabus;
+
+static struct BusInfo isa_bus_info = {
+    .name  = "ISA",
+    .size  = sizeof(ISABus),
+    .props = (Property[]) {
+        {
+            .name   = "iobase",
+            .info   = &qdev_prop_hex32,
+            .offset = offsetof(ISADevice, iobase[0]),
+            .defval = (uint32_t[]) { -1 },
+        },{
+            .name   = "iobase2",
+            .info   = &qdev_prop_hex32,
+            .offset = offsetof(ISADevice, iobase[1]),
+            .defval = (uint32_t[]) { -1 },
+        },
+        {/* end of list */}
+    }
+};
+
+ISABus *isa_bus_new(DeviceState *dev, int mmio, int it_shift)
+{
+    if (isabus) {
+        fprintf(stderr, "Can't create a second ISA bus\n");
+        return NULL;
+    }
+
+    isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, "isa"));
+    isabus->mmio = mmio;
+    isabus->it_shift = it_shift;
+    return isabus;
+}
+
+void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq)
+{
+    assert(n >= 0 && n < dev->nirqs);
+    if (dev->irqs[n])
+        *dev->irqs[n] = irq;
+}
+
+void isa_init_irq(ISADevice *dev, qemu_irq *p)
+{
+    assert(dev->nirqs < ARRAY_SIZE(dev->irqs));
+    dev->irqs[dev->nirqs] = p;
+    dev->nirqs++;
+}
+
+static uint32_t isa_mm_readb(void *opaque, target_phys_addr_t addr)
+{
+    ISAMMIO *mm = opaque;
+    IOPortReadFunc *ioread = mm->info->io[mm->region].read;
+
+    return ioread(mm->dev, addr >> isabus->it_shift) & 0xFF;
+}
+
+static void isa_mm_writeb(void *opaque,
+                          target_phys_addr_t addr, uint32_t value)
+{
+    ISAMMIO *mm = opaque;
+    IOPortWriteFunc *iowrite = mm->info->io[mm->region].write;
+
+    iowrite(mm->dev, addr >> isabus->it_shift, value & 0xFF);
+}
+
+static uint32_t isa_mm_readw(void *opaque, target_phys_addr_t addr)
+{
+    ISAMMIO *mm = opaque;
+    IOPortReadFunc *ioread = mm->info->io[mm->region].read;
+    uint32_t value;
+
+    value = ioread(mm->dev, addr >> isabus->it_shift) & 0xFFFF;
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap16(value);
+#endif
+    return value;
+}
+
+static void isa_mm_writew(void *opaque,
+                       target_phys_addr_t addr, uint32_t value)
+{
+    ISAMMIO *mm = opaque;
+    IOPortWriteFunc *iowrite = mm->info->io[mm->region].write;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap16(value);
+#endif
+    iowrite(mm->dev, addr >> isabus->it_shift, value & 0xFFFF);
+}
+
+static uint32_t isa_mm_readl(void *opaque, target_phys_addr_t addr)
+{
+    ISAMMIO *mm = opaque;
+    IOPortReadFunc *ioread = mm->info->io[mm->region].read;
+    uint32_t value;
+
+    value = ioread(mm->dev, addr >> isabus->it_shift);
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
+    return value;
+}
+
+static void isa_mm_writel(void *opaque,
+                          target_phys_addr_t addr, uint32_t value)
+{
+    ISAMMIO *mm = opaque;
+    IOPortWriteFunc *iowrite = mm->info->io[mm->region].write;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
+    iowrite(mm->dev, addr >> isabus->it_shift, value & 0xFFFF);
+}
+
+static CPUReadMemoryFunc *isa_mm_read[] = {
+    &isa_mm_readb,
+    &isa_mm_readw,
+    &isa_mm_readl,
+};
+
+static CPUWriteMemoryFunc *isa_mm_write[] = {
+    &isa_mm_writeb,
+    &isa_mm_writew,
+    &isa_mm_writel,
+};
+
+static void isa_setup_ioport(ISADevice *dev, ISADeviceInfo *info)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(dev->iobase); i++) {
+        if (!dev->iobase[i])
+            continue;
+        if (info->io[i].read)
+            register_ioport_read(dev->iobase[i], info->io[i].length, 1,
+                                 info->io[i].read, dev);
+        if (info->io[i].write)
+            register_ioport_write(dev->iobase[i], info->io[i].length, 1,
+                                  info->io[i].write, dev);
+        fprintf(stderr, "%s: ioport 0x%x (+%d) %c%c for %s\n", __FUNCTION__,
+                dev->iobase[i], info->io[i].length,
+                info->io[i].read  ? 'r' : '-',
+                info->io[i].write ? 'w' : '-',
+                info->qdev.name);
+    }
+}
+
+static void isa_setup_mmio(ISADevice *dev, ISADeviceInfo *info)
+{
+    struct ISAMMIO *mm;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(dev->iobase); i++) {
+        if (!dev->iobase[i])
+            continue;
+        mm = qemu_mallocz(sizeof(*mm));
+        mm->dev = dev;
+        mm->info = info;
+        mm->region = i;
+        mm->io_memory = cpu_register_io_memory(isa_mm_read, isa_mm_write, mm);
+        cpu_register_physical_memory(dev->iobase[i], info->io[i].length, mm->io_memory);
+     }
+}
+
+static void isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
+{
+    ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev);
+    ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base);
+
+    if (isabus->mmio) {
+        isa_setup_mmio(dev, info);
+    } else {
+        isa_setup_ioport(dev, info);
+    }
+
+    info->init(dev);
+}
+
+void isa_qdev_register(ISADeviceInfo *info)
+{
+    info->qdev.init = isa_qdev_init;
+    info->qdev.bus_info = &isa_bus_info;
+    qdev_register(&info->qdev);
+}
+
+ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2)
+{
+    DeviceState *dev;
+    ISADevice *isa;
+
+    if (!isabus)
+        return NULL;
+    dev = qdev_create(&isabus->qbus, name);
+    isa = DO_UPCAST(ISADevice, qdev, dev);
+    isa->iobase[0] = iobase;
+    isa->iobase[1] = iobase2;
+    qdev_init(dev);
+    return isa;
+}
diff --git a/hw/isa.h b/hw/isa.h
index a8c1a56..941bfe3 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -1,7 +1,38 @@
 #ifndef HW_ISA_H
 #define HW_ISA_H
+
 /* ISA bus */
 
+#include "qdev.h"
+
+typedef struct ISABus ISABus;
+typedef struct ISADevice ISADevice;
+typedef struct ISADeviceInfo ISADeviceInfo;
+
+struct ISADevice {
+    DeviceState qdev;
+    uint32_t iobase[2];
+    qemu_irq *irqs[2];
+    int nirqs;
+};
+
+typedef void (*isa_qdev_initfn)(ISADevice *dev);
+struct ISADeviceInfo {
+    DeviceInfo qdev;
+    isa_qdev_initfn init;
+    struct {
+        IOPortReadFunc  *read;
+        IOPortWriteFunc *write;
+        uint32_t        length;
+    } io[2];
+};
+
+ISABus *isa_bus_new(DeviceState *dev, int mmio, int it_shift);
+void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq);
+void isa_init_irq(ISADevice *dev, qemu_irq *p);
+void isa_qdev_register(ISADeviceInfo *info);
+ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2);
+
 extern target_phys_addr_t isa_mem_base;
 
 int register_ioport_read(int start, int length, int size,
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 2/4] qdev/isa: add qdev support to i8042 (aka ps/2 kbd+mouse).
  2009-07-09 13:02 [Qemu-devel] [PATCH 0/4] qdev: isa bus Gerd Hoffmann
  2009-07-09 13:02 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann
@ 2009-07-09 13:02 ` Gerd Hoffmann
  2009-07-09 13:02 ` [Qemu-devel] [PATCH 3/4] qdev/isa: make the piix isa bridge register an isa bus Gerd Hoffmann
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2009-07-09 13:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pckbd.c |   38 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/hw/pckbd.c b/hw/pckbd.c
index d50cd6e..3f2023c 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -113,6 +113,7 @@
 #define KBD_PENDING_AUX         2
 
 typedef struct KBDState {
+    ISADevice dev;
     uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
     uint8_t status;
     uint8_t mode;
@@ -440,3 +441,40 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
 #endif
     qemu_register_reset(kbd_reset, s);
 }
+
+static void i8042_initfn(ISADevice *dev)
+{
+    KBDState *s = DO_UPCAST(KBDState, dev, dev);
+
+    isa_init_irq(dev, &s->irq_kbd);
+    isa_init_irq(dev, &s->irq_mouse);
+
+    kbd_reset(s);
+    register_savevm("pckbd", 0, 3, kbd_save, kbd_load, s);
+
+    s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
+    s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
+#ifdef TARGET_I386
+    vmmouse_init(s->mouse);
+#endif
+    qemu_register_reset(kbd_reset, s);
+}
+
+static ISADeviceInfo i8042_info = {
+    .qdev.name     = "i8042",
+    .qdev.size     = sizeof(KBDState),
+    .qdev.no_user  = 1,
+    .init          = i8042_initfn,
+    .io[0].read    = kbd_read_data,
+    .io[0].write   = kbd_write_data,
+    .io[0].length  = 1,
+    .io[1].read    = kbd_read_status,
+    .io[1].write   = kbd_write_command,
+    .io[1].length  = 1,
+};
+
+static void i8042_register(void)
+{
+    isa_qdev_register(&i8042_info);
+}
+device_init(i8042_register)
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 3/4] qdev/isa: make the piix isa bridge register an isa bus.
  2009-07-09 13:02 [Qemu-devel] [PATCH 0/4] qdev: isa bus Gerd Hoffmann
  2009-07-09 13:02 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann
  2009-07-09 13:02 ` [Qemu-devel] [PATCH 2/4] qdev/isa: add qdev support to i8042 (aka ps/2 kbd+mouse) Gerd Hoffmann
@ 2009-07-09 13:02 ` Gerd Hoffmann
  2009-07-09 13:02 ` [Qemu-devel] [PATCH 4/4] qdev/isa: make pc use qdev for i8042 setup Gerd Hoffmann
  2009-07-09 14:18 ` [Qemu-devel] [PATCH 0/4] qdev: isa bus Paul Brook
  4 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2009-07-09 13:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/piix_pci.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index a5d42d1..bc65086 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -25,6 +25,7 @@
 #include "hw.h"
 #include "pc.h"
 #include "pci.h"
+#include "isa.h"
 #include "sysbus.h"
 
 typedef uint32_t pci_addr_t;
@@ -342,6 +343,7 @@ static void piix3_initfn(PCIDevice *d)
 {
     uint8_t *pci_conf;
 
+    isa_bus_new(&d->qdev, 0, 0);
     register_savevm("PIIX3", 0, 2, piix_save, piix_load, d);
 
     pci_conf = d->config;
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 4/4] qdev/isa: make pc use qdev for i8042 setup.
  2009-07-09 13:02 [Qemu-devel] [PATCH 0/4] qdev: isa bus Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2009-07-09 13:02 ` [Qemu-devel] [PATCH 3/4] qdev/isa: make the piix isa bridge register an isa bus Gerd Hoffmann
@ 2009-07-09 13:02 ` Gerd Hoffmann
  2009-07-09 14:18 ` [Qemu-devel] [PATCH 0/4] qdev: isa bus Paul Brook
  4 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2009-07-09 13:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pc.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index ecb618d..51e2768 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1095,6 +1095,7 @@ static void pc_init1(ram_addr_t ram_size,
     int bios_size, isa_bios_size, oprom_area_size;
     PCIBus *pci_bus;
     DeviceState *qdev;
+    ISADevice *isa_dev;
     int piix3_devfn = -1;
     CPUState *env;
     qemu_irq *cpu_irq;
@@ -1344,7 +1345,9 @@ static void pc_init1(ram_addr_t ram_size,
         }
     }
 
-    i8042_init(i8259[1], i8259[12], 0x60);
+    isa_dev = isa_create_simple("i8042", 0x60, 0x64);
+    isa_connect_irq(isa_dev, 0, i8259[1]);
+    isa_connect_irq(isa_dev, 1, i8259[12]);
     DMA_init(0);
 #ifdef HAS_AUDIO
     audio_init(pci_enabled ? pci_bus : NULL, i8259);
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] qdev: isa bus.
  2009-07-09 13:02 [Qemu-devel] [PATCH 0/4] qdev: isa bus Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2009-07-09 13:02 ` [Qemu-devel] [PATCH 4/4] qdev/isa: make pc use qdev for i8042 setup Gerd Hoffmann
@ 2009-07-09 14:18 ` Paul Brook
  4 siblings, 0 replies; 9+ messages in thread
From: Paul Brook @ 2009-07-09 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

> I've tried to also handle isa-via-mmio used by certain architectures and
> hide that in isa-bus.c, so the individual drivers don't have to care
> once everything is converted over to qdev.

ISA-via-mmio is actually something different. This is a feature of the host 
bridge, and implemented in isa_mmio.c.

The devices you're talking about are devices that have both ISA and "SysBus" 
incarnations with very similar programming interfaces, in the same way that 
some devices have both ISA and PCI variants.

Paul

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev.
  2009-07-15 12:56 [Qemu-devel] [PATCH 0/4] qdev: add isa bus support Gerd Hoffmann
@ 2009-07-15 12:56 ` Gerd Hoffmann
  2009-07-17 18:12   ` Filip Navara
  0 siblings, 1 reply; 9+ messages in thread
From: Gerd Hoffmann @ 2009-07-15 12:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Wrong mmio stuff from previous version ripped out.
Pretty simple and straigt forward now.
IRQs modeled simliar to sysbus.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.target |    8 +++---
 hw/isa-bus.c    |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/isa.h        |   25 +++++++++++++++++
 3 files changed, 111 insertions(+), 4 deletions(-)
 create mode 100644 hw/isa-bus.c

diff --git a/Makefile.target b/Makefile.target
index 1a71f3a..3395dee 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -563,7 +563,7 @@ obj-y += wdt_ib700.o wdt_i6300esb.o
 
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
-obj-y += ide.o pckbd.o vga.o $(sound-obj-y) dma.o
+obj-y += ide.o pckbd.o vga.o $(sound-obj-y) dma.o isa-bus.o
 obj-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
 obj-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o
 obj-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
@@ -573,7 +573,7 @@ endif
 ifeq ($(TARGET_BASE_ARCH), ppc)
 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
 # shared objects
-obj-y += ppc.o ide.o vga.o $(sound-obj-y) dma.o openpic.o
+obj-y += ppc.o ide.o vga.o $(sound-obj-y) dma.o isa-bus.o openpic.o
 # PREP target
 obj-y += pckbd.o serial.o i8259.o i8254.o fdc.o mc146818rtc.o
 obj-y += prep_pci.o ppc_prep.o
@@ -599,7 +599,7 @@ obj-y += mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-y += mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o rc4030.o
 obj-y += g364fb.o jazz_led.o dp8393x.o
 obj-y += ide.o gt64xxx.o pckbd.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o
-obj-y += piix_pci.o parallel.o cirrus_vga.o pcspk.o $(sound-obj-y)
+obj-y += piix_pci.o parallel.o cirrus_vga.o isa-bus.o pcspk.o $(sound-obj-y)
 obj-y += mipsnet.o
 obj-y += pflash_cfi01.o
 obj-y += vmware_vga.o
@@ -635,7 +635,7 @@ obj-y += pflash_cfi02.o
 endif
 ifeq ($(TARGET_BASE_ARCH), sparc)
 ifeq ($(TARGET_ARCH), sparc64)
-obj-y += sun4u.o ide.o pckbd.o vga.o apb_pci.o
+obj-y += sun4u.o ide.o isa-bus.o pckbd.o vga.o apb_pci.o
 obj-y += fdc.o mc146818rtc.o serial.o
 obj-y += cirrus_vga.o parallel.o
 else
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
new file mode 100644
index 0000000..c0a6447
--- /dev/null
+++ b/hw/isa-bus.c
@@ -0,0 +1,82 @@
+#include "hw.h"
+#include "sysemu.h"
+#include "isa.h"
+
+struct ISABus {
+    BusState qbus;
+};
+static ISABus *isabus;
+
+static struct BusInfo isa_bus_info = {
+    .name  = "ISA",
+    .size  = sizeof(ISABus),
+    .props = (Property[]) {
+        {
+            .name   = "iobase",
+            .info   = &qdev_prop_hex32,
+            .offset = offsetof(ISADevice, iobase[0]),
+            .defval = (uint32_t[]) { -1 },
+        },{
+            .name   = "iobase2",
+            .info   = &qdev_prop_hex32,
+            .offset = offsetof(ISADevice, iobase[1]),
+            .defval = (uint32_t[]) { -1 },
+        },
+        {/* end of list */}
+    }
+};
+
+ISABus *isa_bus_new(DeviceState *dev)
+{
+    if (isabus) {
+        fprintf(stderr, "Can't create a second ISA bus\n");
+        return NULL;
+    }
+
+    isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, NULL));
+    return isabus;
+}
+
+void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq)
+{
+    assert(n >= 0 && n < dev->nirqs);
+    if (dev->irqs[n])
+        *dev->irqs[n] = irq;
+}
+
+void isa_init_irq(ISADevice *dev, qemu_irq *p)
+{
+    assert(dev->nirqs < ARRAY_SIZE(dev->irqs));
+    dev->irqs[dev->nirqs] = p;
+    dev->nirqs++;
+}
+
+static void isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
+{
+    ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev);
+    ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base);
+
+    info->init(dev);
+}
+
+void isa_qdev_register(ISADeviceInfo *info)
+{
+    info->qdev.init = isa_qdev_init;
+    info->qdev.bus_info = &isa_bus_info;
+    qdev_register(&info->qdev);
+}
+
+ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2)
+{
+    DeviceState *dev;
+    ISADevice *isa;
+
+    if (!isabus)
+        return NULL;
+    dev = qdev_create(&isabus->qbus, name);
+    isa = DO_UPCAST(ISADevice, qdev, dev);
+    isa->iobase[0] = iobase;
+    isa->iobase[1] = iobase2;
+    qdev_init(dev);
+    return isa;
+}
diff --git a/hw/isa.h b/hw/isa.h
index f126ecc..49c58f8 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -1,8 +1,33 @@
 #ifndef HW_ISA_H
 #define HW_ISA_H
+
 /* ISA bus */
 
 #include "ioport.h"
+#include "qdev.h"
+
+typedef struct ISABus ISABus;
+typedef struct ISADevice ISADevice;
+typedef struct ISADeviceInfo ISADeviceInfo;
+
+struct ISADevice {
+    DeviceState qdev;
+    uint32_t iobase[2];
+    qemu_irq *irqs[2];
+    int nirqs;
+};
+
+typedef void (*isa_qdev_initfn)(ISADevice *dev);
+struct ISADeviceInfo {
+    DeviceInfo qdev;
+    isa_qdev_initfn init;
+};
+
+ISABus *isa_bus_new(DeviceState *dev);
+void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq);
+void isa_init_irq(ISADevice *dev, qemu_irq *p);
+void isa_qdev_register(ISADeviceInfo *info);
+ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2);
 
 extern target_phys_addr_t isa_mem_base;
 
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev.
  2009-07-15 12:56 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann
@ 2009-07-17 18:12   ` Filip Navara
  2009-07-21  7:11     ` Gerd Hoffmann
  0 siblings, 1 reply; 9+ messages in thread
From: Filip Navara @ 2009-07-17 18:12 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

2009/7/15 Gerd Hoffmann <kraxel@redhat.com>:
> +static struct BusInfo isa_bus_info = {
> +    .name  = "ISA",
> +    .size  = sizeof(ISABus),
> +    .props = (Property[]) {
> +        {
> +            .name   = "iobase",
> +            .info   = &qdev_prop_hex32,
> +            .offset = offsetof(ISADevice, iobase[0]),
> +            .defval = (uint32_t[]) { -1 },
> +        },{
> +            .name   = "iobase2",
> +            .info   = &qdev_prop_hex32,
> +            .offset = offsetof(ISADevice, iobase[1]),
> +            .defval = (uint32_t[]) { -1 },
> +        },
> +        {/* end of list */}
> +    }
> +};

Why exactly two IO bases? That sounds like bad design to me. IMHO it
should be handled more like sysbus_init_mmio (or sysbus_init_mmio_cb)
and sysbus_mmio_map and the number of IO bases should be virtually
unlimited (something like QDEV_MAX_MMIO is acceptable).

Best regards,
Filip Navara

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev.
  2009-07-17 18:12   ` Filip Navara
@ 2009-07-21  7:11     ` Gerd Hoffmann
  0 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2009-07-21  7:11 UTC (permalink / raw)
  To: Filip Navara; +Cc: qemu-devel

On 07/17/09 20:12, Filip Navara wrote:
> 2009/7/15 Gerd Hoffmann<kraxel@redhat.com>:
>> +static struct BusInfo isa_bus_info = {
>> +    .name  = "ISA",
>> +    .size  = sizeof(ISABus),
>> +    .props = (Property[]) {
>> +        {
>> +            .name   = "iobase",
>> +            .name   = "iobase2",
>
> Why exactly two IO bases? That sounds like bad design to me. IMHO it
> should be handled more like sysbus_init_mmio (or sysbus_init_mmio_cb)
> and sysbus_mmio_map and the number of IO bases should be virtually
> unlimited (something like QDEV_MAX_MMIO is acceptable).

Do we really need that?  As new isa devices most likely wouldn't show up 
looking at the existing ones should give us a pretty complete picture ;)

Most devices use one iobase.  A few (ide, ps/2) need two.  Any devices 
which need more?

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-07-21  7:11 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-09 13:02 [Qemu-devel] [PATCH 0/4] qdev: isa bus Gerd Hoffmann
2009-07-09 13:02 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann
2009-07-09 13:02 ` [Qemu-devel] [PATCH 2/4] qdev/isa: add qdev support to i8042 (aka ps/2 kbd+mouse) Gerd Hoffmann
2009-07-09 13:02 ` [Qemu-devel] [PATCH 3/4] qdev/isa: make the piix isa bridge register an isa bus Gerd Hoffmann
2009-07-09 13:02 ` [Qemu-devel] [PATCH 4/4] qdev/isa: make pc use qdev for i8042 setup Gerd Hoffmann
2009-07-09 14:18 ` [Qemu-devel] [PATCH 0/4] qdev: isa bus Paul Brook
  -- strict thread matches above, loose matches on Subject: below --
2009-07-15 12:56 [Qemu-devel] [PATCH 0/4] qdev: add isa bus support Gerd Hoffmann
2009-07-15 12:56 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann
2009-07-17 18:12   ` Filip Navara
2009-07-21  7:11     ` Gerd Hoffmann

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).