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:
parent
3f9cb1c14d
commit
2091ba23e8
49
hw/fdc.c
49
hw/fdc.c
@ -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,
|
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);
|
||||||
DeviceState *dev;
|
fdctrl = &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state);
|
||||||
fdctrl_sysbus_t *sys;
|
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;
|
|
||||||
|
|
||||||
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);
|
||||||
@ -1903,6 +1890,28 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
|
|||||||
return fdctrl;
|
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,
|
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)
|
||||||
{
|
{
|
||||||
|
9
hw/fdc.h
9
hw/fdc.h
@ -3,9 +3,12 @@
|
|||||||
|
|
||||||
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);
|
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,
|
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);
|
||||||
int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
|
int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
|
||||||
|
70
hw/isa-bus.c
70
hw/isa-bus.c
@ -18,17 +18,24 @@
|
|||||||
*/
|
*/
|
||||||
#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),
|
||||||
.props = (Property[]) {
|
.print_dev = isabus_dev_print,
|
||||||
|
.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),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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");
|
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)
|
||||||
|
4
hw/isa.h
4
hw/isa.h
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
8
hw/pc.c
8
hw/pc.c
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user