aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2009-08-14 11:36:14 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-08-27 20:30:11 -0500
commit2091ba23e838c3a8773c246238d7381333789852 (patch)
treef0fe63782f1532c1d193a92a701d11e1544e1fde /hw
parent3f9cb1c14dc368f41447db5f78d6248c4f100ad4 (diff)
isa bus irq changes and fixes.
Changes: (1) make isa-bus maintain isa irqs, complain when allocating already taken irqs. (2) note that (1) works only for isa devices converted to qdev already (floppy and ps2/kbd/mouse right now), so more work is needed to make this really useful. (3) split floppy init into isa and sysbus versions. (4) add sysbus->isa bridge & fix -M isapc breakage. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/fdc.c47
-rw-r--r--hw/fdc.h9
-rw-r--r--hw/isa-bus.c70
-rw-r--r--hw/isa.h4
-rw-r--r--hw/mips_jazz.c2
-rw-r--r--hw/mips_malta.c2
-rw-r--r--hw/pc.c8
-rw-r--r--hw/ppc_prep.c2
-rw-r--r--hw/sun4u.c2
9 files changed, 109 insertions, 37 deletions
diff --git a/hw/fdc.c b/hw/fdc.c
index dabbf3a010..0ece6db231 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1871,33 +1871,42 @@ static void fdctrl_connect_drives(fdctrl_t *fdctrl, BlockDriverState **fds)
}
}
-fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
- target_phys_addr_t io_base,
- BlockDriverState **fds)
+fdctrl_t *fdctrl_init_isa(int isairq, int dma_chann,
+ uint32_t io_base,
+ BlockDriverState **fds)
{
fdctrl_t *fdctrl;
+ ISADevice *dev;
- if (mem_mapped) {
- DeviceState *dev;
- fdctrl_sysbus_t *sys;
+ dev = isa_create_simple("isa-fdc", io_base, 0);
+ fdctrl = &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state);
+ isa_connect_irq(dev, 0, isairq);
- dev = qdev_create(NULL, "sysbus-fdc");
- qdev_init(dev);
- sys = DO_UPCAST(fdctrl_sysbus_t, busdev.qdev, dev);
- fdctrl = &sys->state;
- sysbus_connect_irq(&sys->busdev, 0, irq);
- sysbus_mmio_map(&sys->busdev, 0, io_base);
- } else {
- ISADevice *dev;
+ fdctrl->dma_chann = dma_chann;
+ DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
- dev = isa_create_simple("isa-fdc", io_base, 0);
- fdctrl = &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state);
- isa_connect_irq(dev, 0, irq);
- }
+ fdctrl_connect_drives(fdctrl, fds);
+
+ return fdctrl;
+}
+
+fdctrl_t *fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
+ target_phys_addr_t mmio_base,
+ BlockDriverState **fds)
+{
+ fdctrl_t *fdctrl;
+ DeviceState *dev;
+ fdctrl_sysbus_t *sys;
+
+ dev = qdev_create(NULL, "sysbus-fdc");
+ qdev_init(dev);
+ sys = DO_UPCAST(fdctrl_sysbus_t, busdev.qdev, dev);
+ fdctrl = &sys->state;
+ sysbus_connect_irq(&sys->busdev, 0, irq);
+ sysbus_mmio_map(&sys->busdev, 0, mmio_base);
fdctrl->dma_chann = dma_chann;
DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
-
fdctrl_connect_drives(fdctrl, fds);
return fdctrl;
diff --git a/hw/fdc.h b/hw/fdc.h
index 7b6a9ded8e..04d64ea961 100644
--- a/hw/fdc.h
+++ b/hw/fdc.h
@@ -3,9 +3,12 @@
typedef struct fdctrl_t fdctrl_t;
-fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
- target_phys_addr_t io_base,
- BlockDriverState **fds);
+fdctrl_t *fdctrl_init_isa(int isairq, int dma_chann,
+ uint32_t io_base,
+ BlockDriverState **fds);
+fdctrl_t *fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
+ target_phys_addr_t mmio_base,
+ BlockDriverState **fds);
fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
BlockDriverState **fds, qemu_irq *fdc_tc);
int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 315efbbeca..90a171d996 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -18,17 +18,24 @@
*/
#include "hw.h"
#include "sysemu.h"
+#include "monitor.h"
+#include "sysbus.h"
#include "isa.h"
struct ISABus {
BusState qbus;
+ qemu_irq *irqs;
+ uint32_t assigned;
};
static ISABus *isabus;
+static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+
static struct BusInfo isa_bus_info = {
- .name = "ISA",
- .size = sizeof(ISABus),
- .props = (Property[]) {
+ .name = "ISA",
+ .size = sizeof(ISABus),
+ .print_dev = isabus_dev_print,
+ .props = (Property[]) {
DEFINE_PROP_HEX32("iobase", ISADevice, iobase[0], -1),
DEFINE_PROP_HEX32("iobase2", ISADevice, iobase[1], -1),
DEFINE_PROP_END_OF_LIST(),
@@ -41,16 +48,32 @@ ISABus *isa_bus_new(DeviceState *dev)
fprintf(stderr, "Can't create a second ISA bus\n");
return NULL;
}
+ if (NULL == dev) {
+ dev = qdev_create(NULL, "isabus-bridge");
+ qdev_init(dev);
+ }
isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, NULL));
return isabus;
}
-void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq)
+void isa_bus_irqs(qemu_irq *irqs)
{
- assert(n >= 0 && n < dev->nirqs);
- if (dev->irqs[n])
- *dev->irqs[n] = irq;
+ isabus->irqs = irqs;
+}
+
+void isa_connect_irq(ISADevice *dev, int devnr, int isairq)
+{
+ assert(devnr >= 0 && devnr < dev->nirqs);
+ if (isabus->assigned & (1 << isairq)) {
+ fprintf(stderr, "isa irq %d already assigned\n", isairq);
+ exit(1);
+ }
+ if (dev->irqs[devnr]) {
+ isabus->assigned |= (1 << isairq);
+ dev->isairq[devnr] = isairq;
+ *dev->irqs[devnr] = isabus->irqs[isairq];
+ }
}
void isa_init_irq(ISADevice *dev, qemu_irq *p)
@@ -65,6 +88,8 @@ static void isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev);
ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base);
+ dev->isairq[0] = -1;
+ dev->isairq[1] = -1;
info->init(dev);
}
@@ -91,3 +116,34 @@ ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2
qdev_init(dev);
return isa;
}
+
+static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
+{
+ ISADevice *d = DO_UPCAST(ISADevice, qdev, dev);
+
+ if (d->isairq[1] != -1) {
+ monitor_printf(mon, "%*sisa irqs %d,%d\n", indent, "",
+ d->isairq[0], d->isairq[1]);
+ } else if (d->isairq[0] != -1) {
+ monitor_printf(mon, "%*sisa irq %d\n", indent, "",
+ d->isairq[0]);
+ }
+}
+
+static void isabus_bridge_init(SysBusDevice *dev)
+{
+ /* nothing */
+}
+
+static SysBusDeviceInfo isabus_bridge_info = {
+ .init = isabus_bridge_init,
+ .qdev.name = "isabus-bridge",
+ .qdev.size = sizeof(SysBusDevice),
+};
+
+static void isabus_register_devices(void)
+{
+ sysbus_register_withprop(&isabus_bridge_info);
+}
+
+device_init(isabus_register_devices)
diff --git a/hw/isa.h b/hw/isa.h
index 49c58f84fa..1a3bb5b12f 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -13,6 +13,7 @@ typedef struct ISADeviceInfo ISADeviceInfo;
struct ISADevice {
DeviceState qdev;
uint32_t iobase[2];
+ uint32_t isairq[2];
qemu_irq *irqs[2];
int nirqs;
};
@@ -24,7 +25,8 @@ struct ISADeviceInfo {
};
ISABus *isa_bus_new(DeviceState *dev);
-void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq);
+void isa_bus_irqs(qemu_irq *irqs);
+void isa_connect_irq(ISADevice *dev, int devirq, int isairq);
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);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 9740d728c9..1cbd947fe7 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -238,7 +238,7 @@ void mips_jazz_init (ram_addr_t ram_size,
DriveInfo *dinfo = drive_get(IF_FLOPPY, 0, n);
fds[n] = dinfo ? dinfo->bdrv : NULL;
}
- fdctrl_init(rc4030[1], 0, 1, 0x80003000, fds);
+ fdctrl_init_sysbus(rc4030[1], 0, 0x80003000, fds);
/* Real time clock */
rtc_init(0x70, i8259[8], 1980);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index d8fa26437c..6d41450355 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -929,7 +929,7 @@ void mips_malta_init (ram_addr_t ram_size,
dinfo = drive_get(IF_FLOPPY, 0, i);
fd[i] = dinfo ? dinfo->bdrv : NULL;
}
- floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
+ floppy_controller = fdctrl_init_isa(6, 2, 0x3f0, fd);
/* Sound card */
#ifdef HAS_AUDIO
diff --git a/hw/pc.c b/hw/pc.c
index 11b8618aa3..abb735622e 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1283,7 +1283,9 @@ static void pc_init1(ram_addr_t ram_size,
piix3_devfn = piix3_init(pci_bus, -1);
} else {
pci_bus = NULL;
+ isa_bus_new(NULL);
}
+ isa_bus_irqs(isa_irq);
/* init basic PC hardware */
register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
@@ -1372,8 +1374,8 @@ static void pc_init1(ram_addr_t ram_size,
}
isa_dev = isa_create_simple("i8042", 0x60, 0x64);
- isa_connect_irq(isa_dev, 0, isa_irq[1]);
- isa_connect_irq(isa_dev, 1, isa_irq[12]);
+ isa_connect_irq(isa_dev, 0, 1);
+ isa_connect_irq(isa_dev, 1, 12);
DMA_init(0);
#ifdef HAS_AUDIO
audio_init(pci_enabled ? pci_bus : NULL, isa_irq);
@@ -1383,7 +1385,7 @@ static void pc_init1(ram_addr_t ram_size,
dinfo = drive_get(IF_FLOPPY, 0, i);
fd[i] = dinfo ? dinfo->bdrv : NULL;
}
- floppy_controller = fdctrl_init(isa_irq[6], 2, 0, 0x3f0, fd);
+ floppy_controller = fdctrl_init_isa(6, 2, 0x3f0, fd);
cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd);
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 223ca61931..7665cb7dd7 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -719,7 +719,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
dinfo = drive_get(IF_FLOPPY, 0, i);
fd[i] = dinfo ? dinfo->bdrv : NULL;
}
- fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
+ fdctrl_init_isa(6, 2, 0x3f0, fd);
/* Register speaker port */
register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index bc832557dc..09027e2f91 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -618,7 +618,7 @@ static void sun4uv_init(ram_addr_t RAM_size,
dinfo = drive_get(IF_FLOPPY, 0, i);
fd[i] = dinfo ? dinfo->bdrv : NULL;
}
- floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd);
+ floppy_controller = fdctrl_init_isa(6, 2, 0x3f0, fd);
nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59);
initrd_size = 0;