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>
This commit is contained in:
Gerd Hoffmann 2009-08-14 11:36:14 +02:00 committed by Anthony Liguori
parent 3f9cb1c14d
commit 2091ba23e8
9 changed files with 110 additions and 38 deletions

View File

@ -1871,13 +1871,30 @@ static void fdctrl_connect_drives(fdctrl_t *fdctrl, BlockDriverState **fds)
} }
} }
fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped, fdctrl_t *fdctrl_init_isa(int isairq, int dma_chann,
target_phys_addr_t io_base, uint32_t io_base,
BlockDriverState **fds) BlockDriverState **fds)
{ {
fdctrl_t *fdctrl; fdctrl_t *fdctrl;
ISADevice *dev;
if (mem_mapped) { dev = isa_create_simple("isa-fdc", io_base, 0);
fdctrl = &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state);
isa_connect_irq(dev, 0, isairq);
fdctrl->dma_chann = dma_chann;
DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
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; DeviceState *dev;
fdctrl_sysbus_t *sys; fdctrl_sysbus_t *sys;
@ -1886,18 +1903,10 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
sys = DO_UPCAST(fdctrl_sysbus_t, busdev.qdev, dev); sys = DO_UPCAST(fdctrl_sysbus_t, busdev.qdev, dev);
fdctrl = &sys->state; fdctrl = &sys->state;
sysbus_connect_irq(&sys->busdev, 0, irq); sysbus_connect_irq(&sys->busdev, 0, irq);
sysbus_mmio_map(&sys->busdev, 0, io_base); sysbus_mmio_map(&sys->busdev, 0, mmio_base);
} else {
ISADevice *dev;
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->dma_chann = dma_chann; fdctrl->dma_chann = dma_chann;
DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl); DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
fdctrl_connect_drives(fdctrl, fds); fdctrl_connect_drives(fdctrl, fds);
return fdctrl; return fdctrl;

View File

@ -3,8 +3,11 @@
typedef struct fdctrl_t fdctrl_t; typedef struct fdctrl_t fdctrl_t;
fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped, fdctrl_t *fdctrl_init_isa(int isairq, int dma_chann,
target_phys_addr_t io_base, 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); BlockDriverState **fds);
fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base, fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
BlockDriverState **fds, qemu_irq *fdc_tc); BlockDriverState **fds, qemu_irq *fdc_tc);

View File

@ -18,16 +18,23 @@
*/ */
#include "hw.h" #include "hw.h"
#include "sysemu.h" #include "sysemu.h"
#include "monitor.h"
#include "sysbus.h"
#include "isa.h" #include "isa.h"
struct ISABus { struct ISABus {
BusState qbus; BusState qbus;
qemu_irq *irqs;
uint32_t assigned;
}; };
static ISABus *isabus; static ISABus *isabus;
static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
static struct BusInfo isa_bus_info = { static struct BusInfo isa_bus_info = {
.name = "ISA", .name = "ISA",
.size = sizeof(ISABus), .size = sizeof(ISABus),
.print_dev = isabus_dev_print,
.props = (Property[]) { .props = (Property[]) {
DEFINE_PROP_HEX32("iobase", ISADevice, iobase[0], -1), DEFINE_PROP_HEX32("iobase", ISADevice, iobase[0], -1),
DEFINE_PROP_HEX32("iobase2", ISADevice, iobase[1], -1), DEFINE_PROP_HEX32("iobase2", ISADevice, iobase[1], -1),
@ -41,16 +48,32 @@ ISABus *isa_bus_new(DeviceState *dev)
fprintf(stderr, "Can't create a second ISA bus\n"); fprintf(stderr, "Can't create a second ISA bus\n");
return NULL; 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)); isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, NULL));
return isabus; 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); isabus->irqs = irqs;
if (dev->irqs[n]) }
*dev->irqs[n] = irq;
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) 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); ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev);
ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base); ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base);
dev->isairq[0] = -1;
dev->isairq[1] = -1;
info->init(dev); info->init(dev);
} }
@ -91,3 +116,34 @@ ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2
qdev_init(dev); qdev_init(dev);
return isa; 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)

View File

@ -13,6 +13,7 @@ typedef struct ISADeviceInfo ISADeviceInfo;
struct ISADevice { struct ISADevice {
DeviceState qdev; DeviceState qdev;
uint32_t iobase[2]; uint32_t iobase[2];
uint32_t isairq[2];
qemu_irq *irqs[2]; qemu_irq *irqs[2];
int nirqs; int nirqs;
}; };
@ -24,7 +25,8 @@ struct ISADeviceInfo {
}; };
ISABus *isa_bus_new(DeviceState *dev); 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_init_irq(ISADevice *dev, qemu_irq *p);
void isa_qdev_register(ISADeviceInfo *info); void isa_qdev_register(ISADeviceInfo *info);
ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2); ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2);

View File

@ -238,7 +238,7 @@ void mips_jazz_init (ram_addr_t ram_size,
DriveInfo *dinfo = drive_get(IF_FLOPPY, 0, n); DriveInfo *dinfo = drive_get(IF_FLOPPY, 0, n);
fds[n] = dinfo ? dinfo->bdrv : NULL; 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 */ /* Real time clock */
rtc_init(0x70, i8259[8], 1980); rtc_init(0x70, i8259[8], 1980);

View File

@ -929,7 +929,7 @@ void mips_malta_init (ram_addr_t ram_size,
dinfo = drive_get(IF_FLOPPY, 0, i); dinfo = drive_get(IF_FLOPPY, 0, i);
fd[i] = dinfo ? dinfo->bdrv : NULL; 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 */ /* Sound card */
#ifdef HAS_AUDIO #ifdef HAS_AUDIO

View File

@ -1283,7 +1283,9 @@ static void pc_init1(ram_addr_t ram_size,
piix3_devfn = piix3_init(pci_bus, -1); piix3_devfn = piix3_init(pci_bus, -1);
} else { } else {
pci_bus = NULL; pci_bus = NULL;
isa_bus_new(NULL);
} }
isa_bus_irqs(isa_irq);
/* init basic PC hardware */ /* init basic PC hardware */
register_ioport_write(0x80, 1, 1, ioport80_write, NULL); 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_dev = isa_create_simple("i8042", 0x60, 0x64);
isa_connect_irq(isa_dev, 0, isa_irq[1]); isa_connect_irq(isa_dev, 0, 1);
isa_connect_irq(isa_dev, 1, isa_irq[12]); isa_connect_irq(isa_dev, 1, 12);
DMA_init(0); DMA_init(0);
#ifdef HAS_AUDIO #ifdef HAS_AUDIO
audio_init(pci_enabled ? pci_bus : NULL, isa_irq); 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); dinfo = drive_get(IF_FLOPPY, 0, i);
fd[i] = dinfo ? dinfo->bdrv : NULL; 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); cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd);

View File

@ -719,7 +719,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
dinfo = drive_get(IF_FLOPPY, 0, i); dinfo = drive_get(IF_FLOPPY, 0, i);
fd[i] = dinfo ? dinfo->bdrv : NULL; 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 speaker port */
register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL); register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);

View File

@ -618,7 +618,7 @@ static void sun4uv_init(ram_addr_t RAM_size,
dinfo = drive_get(IF_FLOPPY, 0, i); dinfo = drive_get(IF_FLOPPY, 0, i);
fd[i] = dinfo ? dinfo->bdrv : NULL; 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); nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59);
initrd_size = 0; initrd_size = 0;