qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] qemu_reserve_isa_irq()
@ 2009-08-06 13:45 Jes Sorensen
  2009-08-07  9:13 ` [Qemu-devel] " Gleb Natapov
  2009-08-10 18:57 ` [Qemu-devel] " Anthony Liguori
  0 siblings, 2 replies; 19+ messages in thread
From: Jes Sorensen @ 2009-08-06 13:45 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, Gleb Natapov

[-- Attachment #1: Type: text/plain, Size: 313 bytes --]

Hi

As part of trying to provide the BIOS with information about PCI
interrupt availability, I have added qemu_reserve_isa_irq() to try
and keep track of which IRQs are claimed for ISA.

If we can agree on this approach, then I'll be using it to pass info
on to the guest BIOS in a follow on patch.

Thanks,
Jes


[-- Attachment #2: 0011-qemu-register-isa-irq.patch --]
[-- Type: text/x-patch, Size: 8039 bytes --]

Implement qemu_reserve_isa_irq() and fix the code to call it whenever
an ISA IRQ is claimed.

The old QEMU code simply claimed ISA IRQs without keeping track of it
in any way. This patch tries to catch the culprits and make them call
qemu_reserve_isa_irq() where appropriate.

This allows us to keep track of which IRQs are available for PCI and
later pass that on to the BIOS.

Note that on non PC architectures, this should have zero effect.

Signed-off-by: Jes Sorensen <jes@sgi.com>

---
 hw/cs4231a.c |    3 +++
 hw/gus.c     |    3 +++
 hw/ide.c     |   24 ++++++++++++++++--------
 hw/irq.c     |   12 ++++++++++++
 hw/irq.h     |    2 ++
 hw/pc.c      |   38 ++++++++++++++++++++++++++++++--------
 hw/sb16.c    |    3 +++
 7 files changed, 69 insertions(+), 16 deletions(-)

Index: qemu/hw/cs4231a.c
===================================================================
--- qemu.orig/hw/cs4231a.c
+++ qemu/hw/cs4231a.c
@@ -641,6 +641,9 @@ int cs4231a_init (qemu_irq *pic)
     int i;
     CSState *s;
 
+    if (qemu_reserve_isa_irq(conf.irq))
+        return -1;
+
     s = qemu_mallocz (sizeof (*s));
 
     s->pic = pic;
Index: qemu/hw/gus.c
===================================================================
--- qemu.orig/hw/gus.c
+++ qemu/hw/gus.c
@@ -255,6 +255,9 @@ int GUS_init (qemu_irq *pic)
     GUSState *s;
     struct audsettings as;
 
+    if (qemu_reserve_isa_irq(conf.irq))
+        return -1;
+
     s = qemu_mallocz (sizeof (*s));
 
     AUD_register_card ("gus", &s->card);
Index: qemu/hw/ide.c
===================================================================
--- qemu.orig/hw/ide.c
+++ qemu/hw/ide.c
@@ -3405,10 +3405,14 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
     pci_register_bar((PCIDevice *)d, 4, 0x10,
                            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[2], hd_table[2], hd_table[3], pic[15]);
-    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
-    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+    if (!qemu_reserve_isa_irq(14)) {
+        ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
+        ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
+    }
+    if (!qemu_reserve_isa_irq(15)) {
+        ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
+        ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+    }
 
     for (i = 0; i < 4; i++)
         if (hd_table[i])
@@ -3445,10 +3449,14 @@ void pci_piix4_ide_init(PCIBus *bus, Blo
     pci_register_bar((PCIDevice *)d, 4, 0x10,
                            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[2], hd_table[2], hd_table[3], pic[15]);
-    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
-    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+    if (!qemu_reserve_isa_irq(14)) {
+        ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
+        ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
+    }
+    if (!qemu_reserve_isa_irq(15)) {
+        ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
+        ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+    }
 
     register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
 }
Index: qemu/hw/irq.c
===================================================================
--- qemu.orig/hw/irq.c
+++ qemu/hw/irq.c
@@ -30,6 +30,18 @@ struct IRQState {
     int n;
 };
 
+uint16_t isa_reserved_irqs = 0;
+
+int qemu_reserve_isa_irq(int irq)
+{
+    if (isa_reserved_irqs & (1 << irq)) {
+        fprintf(stderr, "qemu: failed to reserve isa irq %i\n", irq);
+        return -1;
+    }
+    isa_reserved_irqs |= (1 << irq);
+    return 0;
+}
+
 void qemu_set_irq(qemu_irq irq, int level)
 {
     if (!irq)
Index: qemu/hw/irq.h
===================================================================
--- qemu.orig/hw/irq.h
+++ qemu/hw/irq.h
@@ -7,6 +7,8 @@
 typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
 typedef void SetIRQFunc(void *opaque, int irq_num, int level);
 
+extern uint16_t isa_reserved_irqs;
+int qemu_reserve_isa_irq(int irq);
 void qemu_set_irq(qemu_irq irq, int level);
 
 static inline void qemu_irq_raise(qemu_irq irq)
Index: qemu/hw/pc.c
===================================================================
--- qemu.orig/hw/pc.c
+++ qemu/hw/pc.c
@@ -1047,10 +1047,14 @@ static void audio_init (PCIBus *pci_bus,
 static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic)
 {
     static int nb_ne2k = 0;
+    int irq = ne2000_irq[nb_ne2k];
 
     if (nb_ne2k == NE2000_NB_MAX)
         return;
-    isa_ne2000_init(ne2000_io[nb_ne2k], pic[ne2000_irq[nb_ne2k]], nd);
+    if (qemu_reserve_isa_irq(irq)) {
+        return;
+    }
+    isa_ne2000_init(ne2000_io[nb_ne2k], pic[irq], nd);
     nb_ne2k++;
 }
 
@@ -1271,6 +1275,9 @@ static void pc_init1(ram_addr_t ram_size
 
     cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);
     i8259 = i8259_init(cpu_irq[0]);
+    if (qemu_reserve_isa_irq(13)) {
+        exit(1);
+    }
     ferr_irq = i8259[13];
 
     if (pci_enabled) {
@@ -1304,6 +1311,9 @@ static void pc_init1(ram_addr_t ram_size
         }
     }
 
+    if (qemu_reserve_isa_irq(8)) {
+        exit(1);
+    }
     rtc_state = rtc_init(0x70, i8259[8], 2000);
 
     qemu_register_boot_set(pc_boot_set, rtc_state);
@@ -1314,6 +1324,9 @@ static void pc_init1(ram_addr_t ram_size
     if (pci_enabled) {
         ioapic = ioapic_init();
     }
+    if (qemu_reserve_isa_irq(0)) {
+        exit(1);
+    }
     pit = pit_init(0x40, i8259[0]);
     pcspk_init(pit);
     if (!no_hpet) {
@@ -1325,15 +1338,19 @@ static void pc_init1(ram_addr_t ram_size
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_hds[i]) {
-            serial_init(serial_io[i], i8259[serial_irq[i]], 115200,
-                        serial_hds[i]);
+            int irq = serial_irq[i];
+            if (qemu_reserve_isa_irq(irq))
+                break;
+            serial_init(serial_io[i], i8259[irq], 115200, serial_hds[i]);
         }
     }
 
     for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
         if (parallel_hds[i]) {
-            parallel_init(parallel_io[i], i8259[parallel_irq[i]],
-                          parallel_hds[i]);
+            int irq = parallel_irq[i];
+            if (qemu_reserve_isa_irq(irq))
+                break;
+            parallel_init(parallel_io[i], i8259[irq], parallel_hds[i]);
         }
     }
 
@@ -1364,11 +1381,15 @@ static void pc_init1(ram_addr_t ram_size
         pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, i8259);
     } else {
         for(i = 0; i < MAX_IDE_BUS; i++) {
-            isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
-	                 hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
+            int irq = ide_irq[i];
+            if (!qemu_reserve_isa_irq(irq))
+                isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[irq],
+                             hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
         }
     }
 
+    if (qemu_reserve_isa_irq(1) || qemu_reserve_isa_irq(12))
+        exit(1);
     i8042_init(i8259[1], i8259[12], 0x60);
     DMA_init(0);
 #ifdef HAS_AUDIO
@@ -1379,7 +1400,8 @@ 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(i8259[6], 2, 0, 0x3f0, fd);
+    if (!qemu_reserve_isa_irq(6))
+        floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
 
     cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd);
 
Index: qemu/hw/sb16.c
===================================================================
--- qemu.orig/hw/sb16.c
+++ qemu/hw/sb16.c
@@ -1405,6 +1405,9 @@ int SB16_init (qemu_irq *pic)
     static const uint8_t dsp_write_ports[] = {0x6, 0xc};
     static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
 
+    if (qemu_reserve_isa_irq(conf.irq))
+        return -1;
+
     s = qemu_mallocz (sizeof (*s));
 
     s->cmd = -1;

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2009-08-14  8:55 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-06 13:45 [Qemu-devel] [PATCH] qemu_reserve_isa_irq() Jes Sorensen
2009-08-07  9:13 ` [Qemu-devel] " Gleb Natapov
2009-08-10 18:57 ` [Qemu-devel] " Anthony Liguori
2009-08-11 11:32   ` Jes Sorensen
2009-08-11 14:08     ` Gerd Hoffmann
2009-08-11 14:45       ` Jes Sorensen
2009-08-11 16:16         ` Gerd Hoffmann
2009-08-11 20:36         ` Gerd Hoffmann
2009-08-12 14:42           ` [Qemu-devel] [PATCH] isa_reserve_irq() Jes Sorensen
2009-08-12 14:58             ` [Qemu-devel] " Gerd Hoffmann
2009-08-12 15:10               ` Jes Sorensen
2009-08-12 15:28                 ` Gerd Hoffmann
2009-08-12 15:31                   ` Jes Sorensen
2009-08-12 15:41                     ` Gerd Hoffmann
2009-08-12 15:41                   ` [Qemu-devel] [PATCH] isa_reserve_irq() v4 Jes Sorensen
2009-08-12 15:55                     ` [Qemu-devel] " Gerd Hoffmann
2009-08-14  8:55                     ` Gerd Hoffmann
2009-08-12 15:18               ` [Qemu-devel] Re: [PATCH] isa_reserve_irq() Jes Sorensen
2009-08-14  8:40           ` [Qemu-devel] [PATCH] qemu_reserve_isa_irq() Markus Armbruster

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).