sim-card
/
qemu
Archived
10
0
Fork 0

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,29 +1871,16 @@ 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 = 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;
dev = isa_create_simple("isa-fdc", io_base, 0);
fdctrl = &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state);
isa_connect_irq(dev, 0, irq);
}
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);
@ -1903,6 +1890,28 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
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;
}
fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
BlockDriverState **fds, qemu_irq *fdc_tc)
{

View File

@ -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);

View File

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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;