Add isa_reserve_irq().

Introduce isa_reserve_irq() which marks an irq reserved and returns
the appropriate qemu_irq entry from the i8259 table.

isa_reserve_irq() is a temporary interface to be used to allocate ISA
IRQs for devices which have not yet been converted to qdev, and for
special cases which are not suited for qdev conversions, such as the
'ferr'.

This patch goes on top of Gerd Hoffmann's which makes isa-bus.c own
the ISA irq table.

[ added isa-bus.o to some targets to fix build failures  -- kraxel ]

Signed-off-by: Jes Sorensen <jes@sgi.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Jes Sorensen 2009-08-14 11:36:15 +02:00 committed by Anthony Liguori
parent 2091ba23e8
commit 3a38d437ca
7 changed files with 60 additions and 34 deletions

View File

@ -261,7 +261,7 @@ obj-arm-y += arm-semi.o
obj-arm-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o obj-arm-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
obj-arm-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o obj-arm-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
obj-arm-y += pflash_cfi01.o gumstix.o obj-arm-y += pflash_cfi01.o gumstix.o
obj-arm-y += zaurus.o ide.o serial.o spitz.o tosa.o tc6393xb.o obj-arm-y += zaurus.o ide.o isa-bus.o serial.o spitz.o tosa.o tc6393xb.o
obj-arm-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o obj-arm-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
obj-arm-y += omap2.o omap_dss.o soc_dma.o obj-arm-y += omap2.o omap_dss.o soc_dma.o
obj-arm-y += omap_sx1.o palm.o tsc210x.o obj-arm-y += omap_sx1.o palm.o tsc210x.o
@ -275,7 +275,7 @@ obj-arm-y += syborg_virtio.o
obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o serial.o obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o serial.o
obj-sh4-y += ide.o obj-sh4-y += ide.o isa-bus.o
obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
obj-m68k-y += m68k-semi.o dummy_m68k.o obj-m68k-y += m68k-semi.o dummy_m68k.o

View File

@ -60,10 +60,9 @@ static struct {
typedef struct CSState { typedef struct CSState {
QEMUSoundCard card; QEMUSoundCard card;
qemu_irq *pic; qemu_irq pic;
uint32_t regs[CS_REGS]; uint32_t regs[CS_REGS];
uint8_t dregs[CS_DREGS]; uint8_t dregs[CS_DREGS];
int irq;
int dma; int dma;
int port; int port;
int shift; int shift;
@ -483,7 +482,7 @@ IO_WRITE_PROTO (cs_write)
case Alternate_Feature_Status: case Alternate_Feature_Status:
if ((s->dregs[iaddr] & PI) && !(val & PI)) { if ((s->dregs[iaddr] & PI) && !(val & PI)) {
/* XXX: TI CI */ /* XXX: TI CI */
qemu_irq_lower (s->pic[s->irq]); qemu_irq_lower (s->pic);
s->regs[Status] &= ~INT; s->regs[Status] &= ~INT;
} }
s->dregs[iaddr] = val; s->dregs[iaddr] = val;
@ -503,7 +502,7 @@ IO_WRITE_PROTO (cs_write)
case Status: case Status:
if (s->regs[Status] & INT) { if (s->regs[Status] & INT) {
qemu_irq_lower (s->pic[s->irq]); qemu_irq_lower (s->pic);
} }
s->regs[Status] &= ~INT; s->regs[Status] &= ~INT;
s->dregs[Alternate_Feature_Status] &= ~(PI | CI | TI); s->dregs[Alternate_Feature_Status] &= ~(PI | CI | TI);
@ -588,7 +587,7 @@ static int cs_dma_read (void *opaque, int nchan, int dma_pos, int dma_len)
s->regs[Status] |= INT; s->regs[Status] |= INT;
s->dregs[Alternate_Feature_Status] |= PI; s->dregs[Alternate_Feature_Status] |= PI;
s->transferred = 0; s->transferred = 0;
qemu_irq_raise (s->pic[s->irq]); qemu_irq_raise (s->pic);
} }
else { else {
s->transferred += written; s->transferred += written;
@ -643,8 +642,7 @@ int cs4231a_init (qemu_irq *pic)
s = qemu_mallocz (sizeof (*s)); s = qemu_mallocz (sizeof (*s));
s->pic = pic; s->pic = isa_reserve_irq(conf.irq);
s->irq = conf.irq;
s->dma = conf.dma; s->dma = conf.dma;
s->port = conf.port; s->port = conf.port;

View File

@ -3610,8 +3610,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
pci_register_bar((PCIDevice *)d, 4, 0x10, pci_register_bar((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, bmdma_map); PCI_ADDRESS_SPACE_IO, bmdma_map);
ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]); ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], isa_reserve_irq(14));
ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]); ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], isa_reserve_irq(15));
ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
ide_init_ioport(&d->ide_if[2], 0x170, 0x376); ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
@ -3650,6 +3650,9 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
pci_register_bar((PCIDevice *)d, 4, 0x10, pci_register_bar((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, bmdma_map); PCI_ADDRESS_SPACE_IO, bmdma_map);
/*
* These should call isa_reserve_irq() instead when MIPS supports it
*/
ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]); ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]); ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);

View File

@ -76,6 +76,27 @@ void isa_connect_irq(ISADevice *dev, int devnr, int isairq)
} }
} }
/*
* isa_reserve_irq() reserves the ISA irq and returns the corresponding
* qemu_irq entry for the i8259.
*
* This function is only for special cases such as the 'ferr', and
* temporary use for normal devices until they are converted to qdev.
*/
qemu_irq isa_reserve_irq(int isairq)
{
if (isairq < 0 || isairq > 15) {
fprintf(stderr, "isa irq %d invalid\n", isairq);
exit(1);
}
if (isabus->assigned & (1 << isairq)) {
fprintf(stderr, "isa irq %d already assigned\n", isairq);
exit(1);
}
isabus->assigned |= (1 << isairq);
return isabus->irqs[isairq];
}
void isa_init_irq(ISADevice *dev, qemu_irq *p) void isa_init_irq(ISADevice *dev, qemu_irq *p)
{ {
assert(dev->nirqs < ARRAY_SIZE(dev->irqs)); assert(dev->nirqs < ARRAY_SIZE(dev->irqs));

View File

@ -27,6 +27,7 @@ struct ISADeviceInfo {
ISABus *isa_bus_new(DeviceState *dev); ISABus *isa_bus_new(DeviceState *dev);
void isa_bus_irqs(qemu_irq *irqs); void isa_bus_irqs(qemu_irq *irqs);
void isa_connect_irq(ISADevice *dev, int devirq, int isairq); void isa_connect_irq(ISADevice *dev, int devirq, int isairq);
qemu_irq isa_reserve_irq(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);

24
hw/pc.c
View File

@ -1043,13 +1043,14 @@ static void audio_init (PCIBus *pci_bus, qemu_irq *pic)
} }
#endif #endif
static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic) static void pc_init_ne2k_isa(NICInfo *nd)
{ {
static int nb_ne2k = 0; static int nb_ne2k = 0;
if (nb_ne2k == NE2000_NB_MAX) if (nb_ne2k == NE2000_NB_MAX)
return; return;
isa_ne2000_init(ne2000_io[nb_ne2k], pic[ne2000_irq[nb_ne2k]], nd); isa_ne2000_init(ne2000_io[nb_ne2k],
isa_reserve_irq(ne2000_irq[nb_ne2k]), nd);
nb_ne2k++; nb_ne2k++;
} }
@ -1276,7 +1277,6 @@ static void pc_init1(ram_addr_t ram_size,
isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state)); isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
isa_irq_state->i8259 = i8259; isa_irq_state->i8259 = i8259;
isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24); isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
ferr_irq = isa_irq[13];
if (pci_enabled) { if (pci_enabled) {
pci_bus = i440fx_init(&i440fx_state, isa_irq); pci_bus = i440fx_init(&i440fx_state, isa_irq);
@ -1287,6 +1287,8 @@ static void pc_init1(ram_addr_t ram_size,
} }
isa_bus_irqs(isa_irq); isa_bus_irqs(isa_irq);
ferr_irq = isa_reserve_irq(13);
/* 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);
@ -1311,7 +1313,7 @@ static void pc_init1(ram_addr_t ram_size,
} }
} }
rtc_state = rtc_init(0x70, isa_irq[8], 2000); rtc_state = rtc_init(0x70, isa_reserve_irq(8), 2000);
qemu_register_boot_set(pc_boot_set, rtc_state); qemu_register_boot_set(pc_boot_set, rtc_state);
@ -1321,7 +1323,7 @@ static void pc_init1(ram_addr_t ram_size,
if (pci_enabled) { if (pci_enabled) {
isa_irq_state->ioapic = ioapic_init(); isa_irq_state->ioapic = ioapic_init();
} }
pit = pit_init(0x40, isa_irq[0]); pit = pit_init(0x40, isa_reserve_irq(0));
pcspk_init(pit); pcspk_init(pit);
if (!no_hpet) { if (!no_hpet) {
hpet_init(isa_irq); hpet_init(isa_irq);
@ -1329,14 +1331,14 @@ static void pc_init1(ram_addr_t ram_size,
for(i = 0; i < MAX_SERIAL_PORTS; i++) { for(i = 0; i < MAX_SERIAL_PORTS; i++) {
if (serial_hds[i]) { if (serial_hds[i]) {
serial_init(serial_io[i], isa_irq[serial_irq[i]], 115200, serial_init(serial_io[i], isa_reserve_irq(serial_irq[i]), 115200,
serial_hds[i]); serial_hds[i]);
} }
} }
for(i = 0; i < MAX_PARALLEL_PORTS; i++) { for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
if (parallel_hds[i]) { if (parallel_hds[i]) {
parallel_init(parallel_io[i], isa_irq[parallel_irq[i]], parallel_init(parallel_io[i], isa_reserve_irq(parallel_irq[i]),
parallel_hds[i]); parallel_hds[i]);
} }
} }
@ -1347,7 +1349,7 @@ static void pc_init1(ram_addr_t ram_size,
NICInfo *nd = &nd_table[i]; NICInfo *nd = &nd_table[i];
if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
pc_init_ne2k_isa(nd, isa_irq); pc_init_ne2k_isa(nd);
else else
pci_nic_init(nd, "e1000", NULL); pci_nic_init(nd, "e1000", NULL);
} }
@ -1368,7 +1370,8 @@ static void pc_init1(ram_addr_t ram_size,
pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, isa_irq); pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, isa_irq);
} else { } else {
for(i = 0; i < MAX_IDE_BUS; i++) { for(i = 0; i < MAX_IDE_BUS; i++) {
isa_ide_init(ide_iobase[i], ide_iobase2[i], isa_irq[ide_irq[i]], isa_ide_init(ide_iobase[i], ide_iobase2[i],
isa_reserve_irq(ide_irq[i]),
hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
} }
} }
@ -1398,7 +1401,8 @@ static void pc_init1(ram_addr_t ram_size,
i2c_bus *smbus; i2c_bus *smbus;
/* TODO: Populate SPD eeprom data. */ /* TODO: Populate SPD eeprom data. */
smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, isa_irq[9]); smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
isa_reserve_irq(9));
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
DeviceState *eeprom; DeviceState *eeprom;
eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");

View File

@ -56,7 +56,7 @@ static struct {
typedef struct SB16State { typedef struct SB16State {
QEMUSoundCard card; QEMUSoundCard card;
qemu_irq *pic; qemu_irq pic;
int irq; int irq;
int dma; int dma;
int hdma; int hdma;
@ -190,7 +190,7 @@ static void aux_timer (void *opaque)
{ {
SB16State *s = opaque; SB16State *s = opaque;
s->can_write = 1; s->can_write = 1;
qemu_irq_raise (s->pic[s->irq]); qemu_irq_raise (s->pic);
} }
#define DMA8_AUTO 1 #define DMA8_AUTO 1
@ -598,7 +598,7 @@ static void command (SB16State *s, uint8_t cmd)
case 0xf3: case 0xf3:
dsp_out_data (s, 0xaa); dsp_out_data (s, 0xaa);
s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2; s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
qemu_irq_raise (s->pic[s->irq]); qemu_irq_raise (s->pic);
break; break;
case 0xf9: case 0xf9:
@ -766,7 +766,7 @@ static void complete (SB16State *s)
bytes = samples << s->fmt_stereo << (s->fmt_bits == 16); bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
ticks = (bytes * ticks_per_sec) / freq; ticks = (bytes * ticks_per_sec) / freq;
if (ticks < ticks_per_sec / 1024) { if (ticks < ticks_per_sec / 1024) {
qemu_irq_raise (s->pic[s->irq]); qemu_irq_raise (s->pic);
} }
else { else {
if (s->aux_ts) { if (s->aux_ts) {
@ -858,10 +858,10 @@ static void legacy_reset (SB16State *s)
static void reset (SB16State *s) static void reset (SB16State *s)
{ {
qemu_irq_lower (s->pic[s->irq]); qemu_irq_lower (s->pic);
if (s->dma_auto) { if (s->dma_auto) {
qemu_irq_raise (s->pic[s->irq]); qemu_irq_raise (s->pic);
qemu_irq_lower (s->pic[s->irq]); qemu_irq_lower (s->pic);
} }
s->mixer_regs[0x82] = 0; s->mixer_regs[0x82] = 0;
@ -897,7 +897,7 @@ static IO_WRITE_PROTO (dsp_write)
if (s->v2x6 == 1) { if (s->v2x6 == 1) {
if (0 && s->highspeed) { if (0 && s->highspeed) {
s->highspeed = 0; s->highspeed = 0;
qemu_irq_lower (s->pic[s->irq]); qemu_irq_lower (s->pic);
control (s, 0); control (s, 0);
} }
else { else {
@ -1008,7 +1008,7 @@ static IO_READ_PROTO (dsp_read)
if (s->mixer_regs[0x82] & 1) { if (s->mixer_regs[0x82] & 1) {
ack = 1; ack = 1;
s->mixer_regs[0x82] &= 1; s->mixer_regs[0x82] &= 1;
qemu_irq_lower (s->pic[s->irq]); qemu_irq_lower (s->pic);
} }
break; break;
@ -1017,7 +1017,7 @@ static IO_READ_PROTO (dsp_read)
if (s->mixer_regs[0x82] & 2) { if (s->mixer_regs[0x82] & 2) {
ack = 1; ack = 1;
s->mixer_regs[0x82] &= 2; s->mixer_regs[0x82] &= 2;
qemu_irq_lower (s->pic[s->irq]); qemu_irq_lower (s->pic);
} }
break; break;
@ -1231,7 +1231,7 @@ static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
if (s->left_till_irq <= 0) { if (s->left_till_irq <= 0) {
s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1; s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
qemu_irq_raise (s->pic[s->irq]); qemu_irq_raise (s->pic);
if (0 == s->dma_auto) { if (0 == s->dma_auto) {
control (s, 0); control (s, 0);
speaker (s, 0); speaker (s, 0);
@ -1408,8 +1408,7 @@ int SB16_init (qemu_irq *pic)
s = qemu_mallocz (sizeof (*s)); s = qemu_mallocz (sizeof (*s));
s->cmd = -1; s->cmd = -1;
s->pic = pic; s->pic = isa_reserve_irq(conf.irq);
s->irq = conf.irq;
s->dma = conf.dma; s->dma = conf.dma;
s->hdma = conf.hdma; s->hdma = conf.hdma;
s->port = conf.port; s->port = conf.port;