All of lore.kernel.org
 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

* [Qemu-devel] Re: [PATCH] qemu_reserve_isa_irq()
  2009-08-06 13:45 [Qemu-devel] [PATCH] qemu_reserve_isa_irq() Jes Sorensen
@ 2009-08-07  9:13 ` Gleb Natapov
  2009-08-10 18:57 ` [Qemu-devel] " Anthony Liguori
  1 sibling, 0 replies; 19+ messages in thread
From: Gleb Natapov @ 2009-08-07  9:13 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel

On Thu, Aug 06, 2009 at 03:45:20PM +0200, Jes Sorensen wrote:
> 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.
>
Looks good to me. I don't know qdev enough to tell if the same can be done 
as part of qdev infrastructure.

--
			Gleb.

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

* Re: [Qemu-devel] [PATCH] qemu_reserve_isa_irq()
  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 ` Anthony Liguori
  2009-08-11 11:32   ` Jes Sorensen
  1 sibling, 1 reply; 19+ messages in thread
From: Anthony Liguori @ 2009-08-10 18:57 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov, Gerd Hoffmann

Jes Sorensen wrote:
> 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.

Given the new isa qdev support, maybe it would be better to hook into 
isa_connect_irq?

> Thanks,
> Jes
>

Regards,

Anthony Liguori

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

* Re: [Qemu-devel] [PATCH] qemu_reserve_isa_irq()
  2009-08-10 18:57 ` [Qemu-devel] " Anthony Liguori
@ 2009-08-11 11:32   ` Jes Sorensen
  2009-08-11 14:08     ` Gerd Hoffmann
  0 siblings, 1 reply; 19+ messages in thread
From: Jes Sorensen @ 2009-08-11 11:32 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov, Gerd Hoffmann

On 08/10/2009 08:57 PM, Anthony Liguori wrote:
> Jes Sorensen wrote:
>> 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.
>
> Given the new isa qdev support, maybe it would be better to hook into
> isa_connect_irq?

Hi Anthony,

In principle that would be good, the problem is just that the most of
the code still brute force messages with the i8259 array directly,
including the new ISA code. It really needs to be fixed to reference
the ISA IRQ number and not the i8259 array directly :-(

Jes

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

* Re: [Qemu-devel] [PATCH] qemu_reserve_isa_irq()
  2009-08-11 11:32   ` Jes Sorensen
@ 2009-08-11 14:08     ` Gerd Hoffmann
  2009-08-11 14:45       ` Jes Sorensen
  0 siblings, 1 reply; 19+ messages in thread
From: Gerd Hoffmann @ 2009-08-11 14:08 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/11/09 13:32, Jes Sorensen wrote:
> On 08/10/2009 08:57 PM, Anthony Liguori wrote:
>> Given the new isa qdev support, maybe it would be better to hook into
>> isa_connect_irq?
>
> Hi Anthony,
>
> In principle that would be good, the problem is just that the most of
> the code still brute force messages with the i8259 array directly,
> including the new ISA code. It really needs to be fixed to reference
> the ISA IRQ number and not the i8259 array directly :-(

How about making isa-bus.c own the i8259 array then?  We could pass it 
to isa_bus_new.  Then switch over to reference isa irqs by number.  That 
allows isa-bus to keep track of the allocations.  Maybe it makes sense 
to kill the sysbus-style isa_{init,connect}_irq split and have a irq bus 
property then.

cheers,
   Gerd

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

* Re: [Qemu-devel] [PATCH] qemu_reserve_isa_irq()
  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
  0 siblings, 2 replies; 19+ messages in thread
From: Jes Sorensen @ 2009-08-11 14:45 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/11/2009 04:08 PM, Gerd Hoffmann wrote:
> On 08/11/09 13:32, Jes Sorensen wrote:
>> In principle that would be good, the problem is just that the most of
>> the code still brute force messages with the i8259 array directly,
>> including the new ISA code. It really needs to be fixed to reference
>> the ISA IRQ number and not the i8259 array directly :-(
>
> How about making isa-bus.c own the i8259 array then? We could pass it to
> isa_bus_new. Then switch over to reference isa irqs by number. That
> allows isa-bus to keep track of the allocations. Maybe it makes sense to
> kill the sysbus-style isa_{init,connect}_irq split and have a irq bus
> property then.

Hi Gerd,

I would like to see that. I was looking into how much it would be, but I
got lost in the qdev dependencies :(

Cheers,
Jes

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

* Re: [Qemu-devel] [PATCH] qemu_reserve_isa_irq()
  2009-08-11 14:45       ` Jes Sorensen
@ 2009-08-11 16:16         ` Gerd Hoffmann
  2009-08-11 20:36         ` Gerd Hoffmann
  1 sibling, 0 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2009-08-11 16:16 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/11/09 16:45, Jes Sorensen wrote:
> I would like to see that. I was looking into how much it would be, but I
> got lost in the qdev dependencies :(

I'll try to have a look tomorrow.

cheers,
   Gerd

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

* Re: [Qemu-devel] [PATCH] qemu_reserve_isa_irq()
  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-14  8:40           ` [Qemu-devel] [PATCH] qemu_reserve_isa_irq() Markus Armbruster
  1 sibling, 2 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2009-08-11 20:36 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

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

On 08/11/09 16:45, Jes Sorensen wrote:
> On 08/11/2009 04:08 PM, Gerd Hoffmann wrote:
>> On 08/11/09 13:32, Jes Sorensen wrote:
>>> In principle that would be good, the problem is just that the most of
>>> the code still brute force messages with the i8259 array directly,
>>> including the new ISA code. It really needs to be fixed to reference
>>> the ISA IRQ number and not the i8259 array directly :-(
>>
>> How about making isa-bus.c own the i8259 array then? We could pass it to
>> isa_bus_new. Then switch over to reference isa irqs by number. That
>> allows isa-bus to keep track of the allocations. Maybe it makes sense to
>> kill the sysbus-style isa_{init,connect}_irq split and have a irq bus
>> property then.
>
> Hi Gerd,
>
> I would like to see that. I was looking into how much it would be, but I
> got lost in the qdev dependencies :(

Attached a patch.  It will:

   (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.

cheers,
   Gerd

[-- Attachment #2: 0001-isabus-fixes.patch --]
[-- Type: text/plain, Size: 10379 bytes --]

>From d5bbd89ee65d5a29816d5f126425d1f26cfeaafe Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 11 Aug 2009 22:27:38 +0200
Subject: [PATCH] isabus fixes


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/fdc.c        |   47 ++++++++++++++++++++++---------------
 hw/fdc.h        |    9 ++++--
 hw/isa-bus.c    |   70 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 hw/isa.h        |    4 ++-
 hw/mips_jazz.c  |    2 +-
 hw/mips_malta.c |    2 +-
 hw/pc.c         |    8 ++++--
 hw/ppc_prep.c   |    2 +-
 hw/sun4u.c      |    2 +-
 9 files changed, 109 insertions(+), 37 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index c55560f..4011cc3 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1871,33 +1871,42 @@ 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 = isa_create_simple("isa-fdc", io_base, 0);
+    fdctrl = &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state);
+    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;
+    fdctrl->dma_chann = dma_chann;
+    DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
 
-        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_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;
+    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;
diff --git a/hw/fdc.h b/hw/fdc.h
index 7b6a9de..04d64ea 100644
--- a/hw/fdc.h
+++ b/hw/fdc.h
@@ -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);
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 8c14b1d..fdc42c4 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -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[]) {
         {
             .name   = "iobase",
             .info   = &qdev_prop_hex32,
@@ -50,16 +57,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)
@@ -74,6 +97,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);
 }
 
@@ -100,3 +125,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)
diff --git a/hw/isa.h b/hw/isa.h
index 49c58f8..1a3bb5b 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -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);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index e09a6b2..e283b7a 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -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);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 4e51c8d..1ac4c41 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -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
diff --git a/hw/pc.c b/hw/pc.c
index cc6e7e8..88a9ef8 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1272,7 +1272,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(i8259);
 
     /* init basic PC hardware */
     register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
@@ -1364,8 +1366,8 @@ static void pc_init1(ram_addr_t ram_size,
     }
 
     isa_dev = isa_create_simple("i8042", 0x60, 0x64);
-    isa_connect_irq(isa_dev, 0, i8259[1]);
-    isa_connect_irq(isa_dev, 1, i8259[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, i8259);
@@ -1375,7 +1377,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(i8259[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);
 
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 97190a2..51a3df9 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -708,7 +708,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);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 77164ca..6a3a1f9 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -616,7 +616,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;
-- 
1.6.2.5


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

* [Qemu-devel] [PATCH] isa_reserve_irq()
  2009-08-11 20:36         ` Gerd Hoffmann
@ 2009-08-12 14:42           ` Jes Sorensen
  2009-08-12 14:58             ` [Qemu-devel] " Gerd Hoffmann
  2009-08-14  8:40           ` [Qemu-devel] [PATCH] qemu_reserve_isa_irq() Markus Armbruster
  1 sibling, 1 reply; 19+ messages in thread
From: Jes Sorensen @ 2009-08-12 14:42 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

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

On 08/11/2009 10:36 PM, Gerd Hoffmann wrote:
> Attached a patch. It will:
>
> (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.

Hi Gerd,

This looks great! I have implemented isa_reserve_irq() on top of this.
It allows one to reserve ISA irqs without converting them to qdev, which
for certain interrupts makes sense, and I have also made the other users
call it until they are converted to qdev.

Let me know what you think. With this I get what I am after.

Cheers,
Jes




[-- Attachment #2: 0002-isabus-reserve-irq.patch --]
[-- Type: text/x-patch, Size: 11937 bytes --]

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

isa_reserve_irq() is to be used to allocate ISA IRQs for devices which
have not yet, or are not meant to be converted to qdev. Like the ferr
irq.

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

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

---
 hw/cs4231a.c |   12 +++++-------
 hw/hpet.c    |    5 +++++
 hw/ide.c     |    7 +++++--
 hw/isa-bus.c |   14 ++++++++++++++
 hw/isa.h     |    1 +
 hw/pc.c      |   23 +++++++++++++----------
 hw/sb16.c    |   25 ++++++++++++-------------
 7 files changed, 55 insertions(+), 32 deletions(-)

Index: qemu/hw/cs4231a.c
===================================================================
--- qemu.orig/hw/cs4231a.c
+++ qemu/hw/cs4231a.c
@@ -60,10 +60,9 @@ static struct {
 
 typedef struct CSState {
     QEMUSoundCard card;
-    qemu_irq *pic;
+    qemu_irq pic;
     uint32_t regs[CS_REGS];
     uint8_t dregs[CS_DREGS];
-    int irq;
     int dma;
     int port;
     int shift;
@@ -483,7 +482,7 @@ IO_WRITE_PROTO (cs_write)
         case Alternate_Feature_Status:
             if ((s->dregs[iaddr] & PI) && !(val & PI)) {
                 /* XXX: TI CI */
-                qemu_irq_lower (s->pic[s->irq]);
+                qemu_irq_lower (s->pic);
                 s->regs[Status] &= ~INT;
             }
             s->dregs[iaddr] = val;
@@ -503,7 +502,7 @@ IO_WRITE_PROTO (cs_write)
 
     case Status:
         if (s->regs[Status] & INT) {
-            qemu_irq_lower (s->pic[s->irq]);
+            qemu_irq_lower (s->pic);
         }
         s->regs[Status] &= ~INT;
         s->dregs[Alternate_Feature_Status] &= ~(PI | CI | TI);
@@ -588,7 +587,7 @@ static int cs_dma_read (void *opaque, in
         s->regs[Status] |= INT;
         s->dregs[Alternate_Feature_Status] |= PI;
         s->transferred = 0;
-        qemu_irq_raise (s->pic[s->irq]);
+        qemu_irq_raise (s->pic);
     }
     else {
         s->transferred += written;
@@ -643,8 +642,7 @@ int cs4231a_init (qemu_irq *pic)
 
     s = qemu_mallocz (sizeof (*s));
 
-    s->pic = pic;
-    s->irq = conf.irq;
+    s->pic = isa_reserve_irq(conf.irq);
     s->dma = conf.dma;
     s->port = conf.port;
 
Index: qemu/hw/hpet.c
===================================================================
--- qemu.orig/hw/hpet.c
+++ qemu/hw/hpet.c
@@ -29,6 +29,7 @@
 #include "console.h"
 #include "qemu-timer.h"
 #include "hpet_emul.h"
+#include "isa.h"
 
 //#define HPET_DEBUG
 #ifdef HPET_DEBUG
@@ -574,6 +575,10 @@ void hpet_init(qemu_irq *irq) {
     s = qemu_mallocz(sizeof(HPETState));
     hpet_statep = s;
     s->irqs = irq;
+    /*
+     * Rely on irq2 being used by HPET
+     */
+    isa_reserve_irq(2);
     for (i=0; i<HPET_NUM_TIMERS; i++) {
         HPETTimer *timer = &s->timer[i];
         timer->qemu_timer = qemu_new_timer(vm_clock, hpet_timer, timer);
Index: qemu/hw/ide.c
===================================================================
--- qemu.orig/hw/ide.c
+++ qemu/hw/ide.c
@@ -3414,8 +3414,8 @@ 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_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], isa_reserve_irq(15));
     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
 
@@ -3454,6 +3454,9 @@ void pci_piix4_ide_init(PCIBus *bus, Blo
     pci_register_bar((PCIDevice *)d, 4, 0x10,
                            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[2], hd_table[2], hd_table[3], pic[15]);
     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
Index: qemu/hw/isa-bus.c
===================================================================
--- qemu.orig/hw/isa-bus.c
+++ qemu/hw/isa-bus.c
@@ -85,6 +85,20 @@ void isa_connect_irq(ISADevice *dev, int
     }
 }
 
+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)
 {
     assert(dev->nirqs < ARRAY_SIZE(dev->irqs));
Index: qemu/hw/isa.h
===================================================================
--- qemu.orig/hw/isa.h
+++ qemu/hw/isa.h
@@ -27,6 +27,7 @@ struct ISADeviceInfo {
 ISABus *isa_bus_new(DeviceState *dev);
 void isa_bus_irqs(qemu_irq *irqs);
 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_qdev_register(ISADeviceInfo *info);
 ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2);
Index: qemu/hw/pc.c
===================================================================
--- qemu.orig/hw/pc.c
+++ qemu/hw/pc.c
@@ -1037,13 +1037,14 @@ static void audio_init (PCIBus *pci_bus,
 }
 #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;
 
     if (nb_ne2k == NE2000_NB_MAX)
         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++;
 }
 
@@ -1265,7 +1266,6 @@ 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]);
-    ferr_irq = i8259[13];
 
     if (pci_enabled) {
         pci_bus = i440fx_init(&i440fx_state, i8259);
@@ -1275,6 +1275,7 @@ static void pc_init1(ram_addr_t ram_size
         isa_bus_new(NULL);
     }
     isa_bus_irqs(i8259);
+    ferr_irq = isa_reserve_irq(13);
 
     /* init basic PC hardware */
     register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
@@ -1300,7 +1301,7 @@ static void pc_init1(ram_addr_t ram_size
         }
     }
 
-    rtc_state = rtc_init(0x70, i8259[8], 2000);
+    rtc_state = rtc_init(0x70, isa_reserve_irq(8), 2000);
 
     qemu_register_boot_set(pc_boot_set, rtc_state);
 
@@ -1310,7 +1311,7 @@ static void pc_init1(ram_addr_t ram_size
     if (pci_enabled) {
         ioapic = ioapic_init();
     }
-    pit = pit_init(0x40, i8259[0]);
+    pit = pit_init(0x40, isa_reserve_irq(0));
     pcspk_init(pit);
     if (!no_hpet) {
         hpet_init(i8259);
@@ -1321,14 +1322,14 @@ 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_init(serial_io[i], isa_reserve_irq(serial_irq[i]), 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_init(parallel_io[i], isa_reserve_irq(parallel_irq[i]),
                           parallel_hds[i]);
         }
     }
@@ -1339,7 +1340,7 @@ static void pc_init1(ram_addr_t ram_size
         NICInfo *nd = &nd_table[i];
 
         if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
-            pc_init_ne2k_isa(nd, i8259);
+            pc_init_ne2k_isa(nd);
         else
             pci_nic_init(nd, "ne2k_pci", NULL);
     }
@@ -1360,7 +1361,8 @@ 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]],
+            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]);
         }
     }
@@ -1390,7 +1392,8 @@ static void pc_init1(ram_addr_t ram_size
         i2c_bus *smbus;
 
         /* TODO: Populate SPD eeprom data.  */
-        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]);
+        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
+                              isa_reserve_irq(9));
         for (i = 0; i < 8; i++) {
             DeviceState *eeprom;
             eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
Index: qemu/hw/sb16.c
===================================================================
--- qemu.orig/hw/sb16.c
+++ qemu/hw/sb16.c
@@ -56,7 +56,7 @@ static struct {
 
 typedef struct SB16State {
     QEMUSoundCard card;
-    qemu_irq *pic;
+    qemu_irq pic;
     int irq;
     int dma;
     int hdma;
@@ -190,7 +190,7 @@ static void aux_timer (void *opaque)
 {
     SB16State *s = opaque;
     s->can_write = 1;
-    qemu_irq_raise (s->pic[s->irq]);
+    qemu_irq_raise (s->pic);
 }
 
 #define DMA8_AUTO 1
@@ -598,7 +598,7 @@ static void command (SB16State *s, uint8
         case 0xf3:
             dsp_out_data (s, 0xaa);
             s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
-            qemu_irq_raise (s->pic[s->irq]);
+            qemu_irq_raise (s->pic);
             break;
 
         case 0xf9:
@@ -766,7 +766,7 @@ static void complete (SB16State *s)
                 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
                 ticks = (bytes * ticks_per_sec) / freq;
                 if (ticks < ticks_per_sec / 1024) {
-                    qemu_irq_raise (s->pic[s->irq]);
+                    qemu_irq_raise (s->pic);
                 }
                 else {
                     if (s->aux_ts) {
@@ -858,10 +858,10 @@ static void legacy_reset (SB16State *s)
 
 static void reset (SB16State *s)
 {
-    qemu_irq_lower (s->pic[s->irq]);
+    qemu_irq_lower (s->pic);
     if (s->dma_auto) {
-        qemu_irq_raise (s->pic[s->irq]);
-        qemu_irq_lower (s->pic[s->irq]);
+        qemu_irq_raise (s->pic);
+        qemu_irq_lower (s->pic);
     }
 
     s->mixer_regs[0x82] = 0;
@@ -897,7 +897,7 @@ static IO_WRITE_PROTO (dsp_write)
             if (s->v2x6 == 1) {
                 if (0 && s->highspeed) {
                     s->highspeed = 0;
-                    qemu_irq_lower (s->pic[s->irq]);
+                    qemu_irq_lower (s->pic);
                     control (s, 0);
                 }
                 else {
@@ -1008,7 +1008,7 @@ static IO_READ_PROTO (dsp_read)
         if (s->mixer_regs[0x82] & 1) {
             ack = 1;
             s->mixer_regs[0x82] &= 1;
-            qemu_irq_lower (s->pic[s->irq]);
+            qemu_irq_lower (s->pic);
         }
         break;
 
@@ -1017,7 +1017,7 @@ static IO_READ_PROTO (dsp_read)
         if (s->mixer_regs[0x82] & 2) {
             ack = 1;
             s->mixer_regs[0x82] &= 2;
-            qemu_irq_lower (s->pic[s->irq]);
+            qemu_irq_lower (s->pic);
         }
         break;
 
@@ -1231,7 +1231,7 @@ static int SB_read_DMA (void *opaque, in
 
     if (s->left_till_irq <= 0) {
         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) {
             control (s, 0);
             speaker (s, 0);
@@ -1408,8 +1408,7 @@ int SB16_init (qemu_irq *pic)
     s = qemu_mallocz (sizeof (*s));
 
     s->cmd = -1;
-    s->pic = pic;
-    s->irq = conf.irq;
+    s->pic = isa_reserve_irq(conf.irq);
     s->dma = conf.dma;
     s->hdma = conf.hdma;
     s->port = conf.port;

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

* [Qemu-devel] Re: [PATCH] isa_reserve_irq()
  2009-08-12 14:42           ` [Qemu-devel] [PATCH] isa_reserve_irq() Jes Sorensen
@ 2009-08-12 14:58             ` Gerd Hoffmann
  2009-08-12 15:10               ` Jes Sorensen
  2009-08-12 15:18               ` [Qemu-devel] Re: [PATCH] isa_reserve_irq() Jes Sorensen
  0 siblings, 2 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2009-08-12 14:58 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/12/09 16:42, Jes Sorensen wrote:
> Hi Gerd,
>
> This looks great! I have implemented isa_reserve_irq() on top of this.
> It allows one to reserve ISA irqs without converting them to qdev, which
> for certain interrupts makes sense,

which ones?

> and I have also made the other users
> call it until they are converted to qdev.

I think that deserves a comment clearly stating that this interface is a 
(temporary?) thing for not-yet converted devices.

Otherwise it looks fine to me.

cheers,
   Gerd

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

* [Qemu-devel] Re: [PATCH] isa_reserve_irq()
  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:18               ` [Qemu-devel] Re: [PATCH] isa_reserve_irq() Jes Sorensen
  1 sibling, 1 reply; 19+ messages in thread
From: Jes Sorensen @ 2009-08-12 15:10 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/12/2009 04:58 PM, Gerd Hoffmann wrote:
> On 08/12/09 16:42, Jes Sorensen wrote:
>> Hi Gerd,
>>
>> This looks great! I have implemented isa_reserve_irq() on top of this.
>> It allows one to reserve ISA irqs without converting them to qdev, which
>> for certain interrupts makes sense,
>
> which ones?

ferr

>> and I have also made the other users
>> call it until they are converted to qdev.
>
> I think that deserves a comment clearly stating that this interface is a
> (temporary?) thing for not-yet converted devices.
>
> Otherwise it looks fine to me.

If you think it makes sense to convert ferr as well, then I'll be happy
to add the comment.

Anthony also pointed out that hpet shouldn't be on the list - it makes
sense. The BIOS can filter out irq2 based on the irq0override flag, so I
will take out the hpet bits too.

Cheers,
Jes

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

* [Qemu-devel] Re: [PATCH] isa_reserve_irq()
  2009-08-12 14:58             ` [Qemu-devel] " Gerd Hoffmann
  2009-08-12 15:10               ` Jes Sorensen
@ 2009-08-12 15:18               ` Jes Sorensen
  1 sibling, 0 replies; 19+ messages in thread
From: Jes Sorensen @ 2009-08-12 15:18 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

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

On 08/12/2009 04:58 PM, Gerd Hoffmann wrote:
> On 08/12/09 16:42, Jes Sorensen wrote:
>> and I have also made the other users
>> call it until they are converted to qdev.
>
> I think that deserves a comment clearly stating that this interface is a
> (temporary?) thing for not-yet converted devices.

Hi Gerd,

Thought about it a bit more, I think the only real one is ferr, and I
guess we can implement that as a fake device in qdev if needed.

Updated patch without hpet and with the temporary comment included.

Cheers,
Jes

[-- Attachment #2: 0002-isabus-reserve-irq.patch --]
[-- Type: text/x-patch, Size: 11235 bytes --]

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.

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

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

---
 hw/cs4231a.c |   12 +++++-------
 hw/ide.c     |    7 +++++--
 hw/isa-bus.c |   14 ++++++++++++++
 hw/isa.h     |    1 +
 hw/pc.c      |   23 +++++++++++++----------
 hw/sb16.c    |   25 ++++++++++++-------------
 6 files changed, 50 insertions(+), 32 deletions(-)

Index: qemu/hw/cs4231a.c
===================================================================
--- qemu.orig/hw/cs4231a.c
+++ qemu/hw/cs4231a.c
@@ -60,10 +60,9 @@ static struct {
 
 typedef struct CSState {
     QEMUSoundCard card;
-    qemu_irq *pic;
+    qemu_irq pic;
     uint32_t regs[CS_REGS];
     uint8_t dregs[CS_DREGS];
-    int irq;
     int dma;
     int port;
     int shift;
@@ -483,7 +482,7 @@ IO_WRITE_PROTO (cs_write)
         case Alternate_Feature_Status:
             if ((s->dregs[iaddr] & PI) && !(val & PI)) {
                 /* XXX: TI CI */
-                qemu_irq_lower (s->pic[s->irq]);
+                qemu_irq_lower (s->pic);
                 s->regs[Status] &= ~INT;
             }
             s->dregs[iaddr] = val;
@@ -503,7 +502,7 @@ IO_WRITE_PROTO (cs_write)
 
     case Status:
         if (s->regs[Status] & INT) {
-            qemu_irq_lower (s->pic[s->irq]);
+            qemu_irq_lower (s->pic);
         }
         s->regs[Status] &= ~INT;
         s->dregs[Alternate_Feature_Status] &= ~(PI | CI | TI);
@@ -588,7 +587,7 @@ static int cs_dma_read (void *opaque, in
         s->regs[Status] |= INT;
         s->dregs[Alternate_Feature_Status] |= PI;
         s->transferred = 0;
-        qemu_irq_raise (s->pic[s->irq]);
+        qemu_irq_raise (s->pic);
     }
     else {
         s->transferred += written;
@@ -643,8 +642,7 @@ int cs4231a_init (qemu_irq *pic)
 
     s = qemu_mallocz (sizeof (*s));
 
-    s->pic = pic;
-    s->irq = conf.irq;
+    s->pic = isa_reserve_irq(conf.irq);
     s->dma = conf.dma;
     s->port = conf.port;
 
Index: qemu/hw/ide.c
===================================================================
--- qemu.orig/hw/ide.c
+++ qemu/hw/ide.c
@@ -3414,8 +3414,8 @@ 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_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], isa_reserve_irq(15));
     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
 
@@ -3454,6 +3454,9 @@ void pci_piix4_ide_init(PCIBus *bus, Blo
     pci_register_bar((PCIDevice *)d, 4, 0x10,
                            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[2], hd_table[2], hd_table[3], pic[15]);
     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
Index: qemu/hw/isa-bus.c
===================================================================
--- qemu.orig/hw/isa-bus.c
+++ qemu/hw/isa-bus.c
@@ -85,6 +85,20 @@ void isa_connect_irq(ISADevice *dev, int
     }
 }
 
+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)
 {
     assert(dev->nirqs < ARRAY_SIZE(dev->irqs));
Index: qemu/hw/isa.h
===================================================================
--- qemu.orig/hw/isa.h
+++ qemu/hw/isa.h
@@ -27,6 +27,7 @@ struct ISADeviceInfo {
 ISABus *isa_bus_new(DeviceState *dev);
 void isa_bus_irqs(qemu_irq *irqs);
 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_qdev_register(ISADeviceInfo *info);
 ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2);
Index: qemu/hw/pc.c
===================================================================
--- qemu.orig/hw/pc.c
+++ qemu/hw/pc.c
@@ -1037,13 +1037,14 @@ static void audio_init (PCIBus *pci_bus,
 }
 #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;
 
     if (nb_ne2k == NE2000_NB_MAX)
         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++;
 }
 
@@ -1265,7 +1266,6 @@ 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]);
-    ferr_irq = i8259[13];
 
     if (pci_enabled) {
         pci_bus = i440fx_init(&i440fx_state, i8259);
@@ -1275,6 +1275,7 @@ static void pc_init1(ram_addr_t ram_size
         isa_bus_new(NULL);
     }
     isa_bus_irqs(i8259);
+    ferr_irq = isa_reserve_irq(13);
 
     /* init basic PC hardware */
     register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
@@ -1300,7 +1301,7 @@ static void pc_init1(ram_addr_t ram_size
         }
     }
 
-    rtc_state = rtc_init(0x70, i8259[8], 2000);
+    rtc_state = rtc_init(0x70, isa_reserve_irq(8), 2000);
 
     qemu_register_boot_set(pc_boot_set, rtc_state);
 
@@ -1310,7 +1311,7 @@ static void pc_init1(ram_addr_t ram_size
     if (pci_enabled) {
         ioapic = ioapic_init();
     }
-    pit = pit_init(0x40, i8259[0]);
+    pit = pit_init(0x40, isa_reserve_irq(0));
     pcspk_init(pit);
     if (!no_hpet) {
         hpet_init(i8259);
@@ -1321,14 +1322,14 @@ 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_init(serial_io[i], isa_reserve_irq(serial_irq[i]), 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_init(parallel_io[i], isa_reserve_irq(parallel_irq[i]),
                           parallel_hds[i]);
         }
     }
@@ -1339,7 +1340,7 @@ static void pc_init1(ram_addr_t ram_size
         NICInfo *nd = &nd_table[i];
 
         if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
-            pc_init_ne2k_isa(nd, i8259);
+            pc_init_ne2k_isa(nd);
         else
             pci_nic_init(nd, "ne2k_pci", NULL);
     }
@@ -1360,7 +1361,8 @@ 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]],
+            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]);
         }
     }
@@ -1390,7 +1392,8 @@ static void pc_init1(ram_addr_t ram_size
         i2c_bus *smbus;
 
         /* TODO: Populate SPD eeprom data.  */
-        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]);
+        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
+                              isa_reserve_irq(9));
         for (i = 0; i < 8; i++) {
             DeviceState *eeprom;
             eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
Index: qemu/hw/sb16.c
===================================================================
--- qemu.orig/hw/sb16.c
+++ qemu/hw/sb16.c
@@ -56,7 +56,7 @@ static struct {
 
 typedef struct SB16State {
     QEMUSoundCard card;
-    qemu_irq *pic;
+    qemu_irq pic;
     int irq;
     int dma;
     int hdma;
@@ -190,7 +190,7 @@ static void aux_timer (void *opaque)
 {
     SB16State *s = opaque;
     s->can_write = 1;
-    qemu_irq_raise (s->pic[s->irq]);
+    qemu_irq_raise (s->pic);
 }
 
 #define DMA8_AUTO 1
@@ -598,7 +598,7 @@ static void command (SB16State *s, uint8
         case 0xf3:
             dsp_out_data (s, 0xaa);
             s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
-            qemu_irq_raise (s->pic[s->irq]);
+            qemu_irq_raise (s->pic);
             break;
 
         case 0xf9:
@@ -766,7 +766,7 @@ static void complete (SB16State *s)
                 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
                 ticks = (bytes * ticks_per_sec) / freq;
                 if (ticks < ticks_per_sec / 1024) {
-                    qemu_irq_raise (s->pic[s->irq]);
+                    qemu_irq_raise (s->pic);
                 }
                 else {
                     if (s->aux_ts) {
@@ -858,10 +858,10 @@ static void legacy_reset (SB16State *s)
 
 static void reset (SB16State *s)
 {
-    qemu_irq_lower (s->pic[s->irq]);
+    qemu_irq_lower (s->pic);
     if (s->dma_auto) {
-        qemu_irq_raise (s->pic[s->irq]);
-        qemu_irq_lower (s->pic[s->irq]);
+        qemu_irq_raise (s->pic);
+        qemu_irq_lower (s->pic);
     }
 
     s->mixer_regs[0x82] = 0;
@@ -897,7 +897,7 @@ static IO_WRITE_PROTO (dsp_write)
             if (s->v2x6 == 1) {
                 if (0 && s->highspeed) {
                     s->highspeed = 0;
-                    qemu_irq_lower (s->pic[s->irq]);
+                    qemu_irq_lower (s->pic);
                     control (s, 0);
                 }
                 else {
@@ -1008,7 +1008,7 @@ static IO_READ_PROTO (dsp_read)
         if (s->mixer_regs[0x82] & 1) {
             ack = 1;
             s->mixer_regs[0x82] &= 1;
-            qemu_irq_lower (s->pic[s->irq]);
+            qemu_irq_lower (s->pic);
         }
         break;
 
@@ -1017,7 +1017,7 @@ static IO_READ_PROTO (dsp_read)
         if (s->mixer_regs[0x82] & 2) {
             ack = 1;
             s->mixer_regs[0x82] &= 2;
-            qemu_irq_lower (s->pic[s->irq]);
+            qemu_irq_lower (s->pic);
         }
         break;
 
@@ -1231,7 +1231,7 @@ static int SB_read_DMA (void *opaque, in
 
     if (s->left_till_irq <= 0) {
         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) {
             control (s, 0);
             speaker (s, 0);
@@ -1408,8 +1408,7 @@ int SB16_init (qemu_irq *pic)
     s = qemu_mallocz (sizeof (*s));
 
     s->cmd = -1;
-    s->pic = pic;
-    s->irq = conf.irq;
+    s->pic = isa_reserve_irq(conf.irq);
     s->dma = conf.dma;
     s->hdma = conf.hdma;
     s->port = conf.port;

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

* [Qemu-devel] Re: [PATCH] isa_reserve_irq()
  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                   ` [Qemu-devel] [PATCH] isa_reserve_irq() v4 Jes Sorensen
  0 siblings, 2 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2009-08-12 15:28 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/12/09 17:10, Jes Sorensen wrote:
> On 08/12/2009 04:58 PM, Gerd Hoffmann wrote:
>> On 08/12/09 16:42, Jes Sorensen wrote:
>>> Hi Gerd,
>>>
>>> This looks great! I have implemented isa_reserve_irq() on top of this.
>>> It allows one to reserve ISA irqs without converting them to qdev, which
>>> for certain interrupts makes sense,
>>
>> which ones?
>
> ferr

Ah, that one.

>> I think that deserves a comment clearly stating that this interface is a
>> (temporary?) thing for not-yet converted devices.
>>
>> Otherwise it looks fine to me.
>
> If you think it makes sense to convert ferr as well, then I'll be happy
> to add the comment.

Hmm, I don't think it makes sense to pull a dummy device out of thin 
air, isa_reserve_irq() will do fine.  But it should be be clearly 
documented that this is for this special case and not-yet converted 
devices.  qdev-ified devices should use the other isa_*_irq functions 
instead.

cheers,
   Gerd

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

* [Qemu-devel] Re: [PATCH] isa_reserve_irq()
  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
  1 sibling, 1 reply; 19+ messages in thread
From: Jes Sorensen @ 2009-08-12 15:31 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/12/2009 05:28 PM, Gerd Hoffmann wrote:
> Hmm, I don't think it makes sense to pull a dummy device out of thin
> air, isa_reserve_irq() will do fine. But it should be be clearly
> documented that this is for this special case and not-yet converted
> devices. qdev-ified devices should use the other isa_*_irq functions
> instead.

Ok - do you want me to update the documentation, or is it fine as is
then?

Cheers,
Jes

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

* [Qemu-devel] [PATCH] isa_reserve_irq() v4
  2009-08-12 15:28                 ` Gerd Hoffmann
  2009-08-12 15:31                   ` Jes Sorensen
@ 2009-08-12 15:41                   ` Jes Sorensen
  2009-08-12 15:55                     ` [Qemu-devel] " Gerd Hoffmann
  2009-08-14  8:55                     ` Gerd Hoffmann
  1 sibling, 2 replies; 19+ messages in thread
From: Jes Sorensen @ 2009-08-12 15:41 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

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

Hi,

Guess it's v4 by now - I have added comments to the code making it clear
that the interface is for special cases such as 'ferr' and otherwise for
temporary use until qdev-ification.

Hope this covers what you were after.

Cheers,
Jes



[-- Attachment #2: 0002-isabus-reserve-irq-v4.patch --]
[-- Type: text/x-patch, Size: 11586 bytes --]

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.

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

---
 hw/cs4231a.c |   12 +++++-------
 hw/ide.c     |    7 +++++--
 hw/isa-bus.c |   21 +++++++++++++++++++++
 hw/isa.h     |    1 +
 hw/pc.c      |   23 +++++++++++++----------
 hw/sb16.c    |   25 ++++++++++++-------------
 6 files changed, 57 insertions(+), 32 deletions(-)

Index: qemu/hw/cs4231a.c
===================================================================
--- qemu.orig/hw/cs4231a.c
+++ qemu/hw/cs4231a.c
@@ -60,10 +60,9 @@ static struct {
 
 typedef struct CSState {
     QEMUSoundCard card;
-    qemu_irq *pic;
+    qemu_irq pic;
     uint32_t regs[CS_REGS];
     uint8_t dregs[CS_DREGS];
-    int irq;
     int dma;
     int port;
     int shift;
@@ -483,7 +482,7 @@ IO_WRITE_PROTO (cs_write)
         case Alternate_Feature_Status:
             if ((s->dregs[iaddr] & PI) && !(val & PI)) {
                 /* XXX: TI CI */
-                qemu_irq_lower (s->pic[s->irq]);
+                qemu_irq_lower (s->pic);
                 s->regs[Status] &= ~INT;
             }
             s->dregs[iaddr] = val;
@@ -503,7 +502,7 @@ IO_WRITE_PROTO (cs_write)
 
     case Status:
         if (s->regs[Status] & INT) {
-            qemu_irq_lower (s->pic[s->irq]);
+            qemu_irq_lower (s->pic);
         }
         s->regs[Status] &= ~INT;
         s->dregs[Alternate_Feature_Status] &= ~(PI | CI | TI);
@@ -588,7 +587,7 @@ static int cs_dma_read (void *opaque, in
         s->regs[Status] |= INT;
         s->dregs[Alternate_Feature_Status] |= PI;
         s->transferred = 0;
-        qemu_irq_raise (s->pic[s->irq]);
+        qemu_irq_raise (s->pic);
     }
     else {
         s->transferred += written;
@@ -643,8 +642,7 @@ int cs4231a_init (qemu_irq *pic)
 
     s = qemu_mallocz (sizeof (*s));
 
-    s->pic = pic;
-    s->irq = conf.irq;
+    s->pic = isa_reserve_irq(conf.irq);
     s->dma = conf.dma;
     s->port = conf.port;
 
Index: qemu/hw/ide.c
===================================================================
--- qemu.orig/hw/ide.c
+++ qemu/hw/ide.c
@@ -3414,8 +3414,8 @@ 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_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], isa_reserve_irq(15));
     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
 
@@ -3454,6 +3454,9 @@ void pci_piix4_ide_init(PCIBus *bus, Blo
     pci_register_bar((PCIDevice *)d, 4, 0x10,
                            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[2], hd_table[2], hd_table[3], pic[15]);
     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
Index: qemu/hw/isa-bus.c
===================================================================
--- qemu.orig/hw/isa-bus.c
+++ qemu/hw/isa-bus.c
@@ -85,6 +85,27 @@ void isa_connect_irq(ISADevice *dev, int
     }
 }
 
+/*
+ * 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)
 {
     assert(dev->nirqs < ARRAY_SIZE(dev->irqs));
Index: qemu/hw/isa.h
===================================================================
--- qemu.orig/hw/isa.h
+++ qemu/hw/isa.h
@@ -27,6 +27,7 @@ struct ISADeviceInfo {
 ISABus *isa_bus_new(DeviceState *dev);
 void isa_bus_irqs(qemu_irq *irqs);
 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_qdev_register(ISADeviceInfo *info);
 ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2);
Index: qemu/hw/pc.c
===================================================================
--- qemu.orig/hw/pc.c
+++ qemu/hw/pc.c
@@ -1037,13 +1037,14 @@ static void audio_init (PCIBus *pci_bus,
 }
 #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;
 
     if (nb_ne2k == NE2000_NB_MAX)
         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++;
 }
 
@@ -1265,7 +1266,6 @@ 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]);
-    ferr_irq = i8259[13];
 
     if (pci_enabled) {
         pci_bus = i440fx_init(&i440fx_state, i8259);
@@ -1275,6 +1275,7 @@ static void pc_init1(ram_addr_t ram_size
         isa_bus_new(NULL);
     }
     isa_bus_irqs(i8259);
+    ferr_irq = isa_reserve_irq(13);
 
     /* init basic PC hardware */
     register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
@@ -1300,7 +1301,7 @@ static void pc_init1(ram_addr_t ram_size
         }
     }
 
-    rtc_state = rtc_init(0x70, i8259[8], 2000);
+    rtc_state = rtc_init(0x70, isa_reserve_irq(8), 2000);
 
     qemu_register_boot_set(pc_boot_set, rtc_state);
 
@@ -1310,7 +1311,7 @@ static void pc_init1(ram_addr_t ram_size
     if (pci_enabled) {
         ioapic = ioapic_init();
     }
-    pit = pit_init(0x40, i8259[0]);
+    pit = pit_init(0x40, isa_reserve_irq(0));
     pcspk_init(pit);
     if (!no_hpet) {
         hpet_init(i8259);
@@ -1321,14 +1322,14 @@ 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_init(serial_io[i], isa_reserve_irq(serial_irq[i]), 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_init(parallel_io[i], isa_reserve_irq(parallel_irq[i]),
                           parallel_hds[i]);
         }
     }
@@ -1339,7 +1340,7 @@ static void pc_init1(ram_addr_t ram_size
         NICInfo *nd = &nd_table[i];
 
         if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
-            pc_init_ne2k_isa(nd, i8259);
+            pc_init_ne2k_isa(nd);
         else
             pci_nic_init(nd, "ne2k_pci", NULL);
     }
@@ -1360,7 +1361,8 @@ 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]],
+            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]);
         }
     }
@@ -1390,7 +1392,8 @@ static void pc_init1(ram_addr_t ram_size
         i2c_bus *smbus;
 
         /* TODO: Populate SPD eeprom data.  */
-        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]);
+        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
+                              isa_reserve_irq(9));
         for (i = 0; i < 8; i++) {
             DeviceState *eeprom;
             eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
Index: qemu/hw/sb16.c
===================================================================
--- qemu.orig/hw/sb16.c
+++ qemu/hw/sb16.c
@@ -56,7 +56,7 @@ static struct {
 
 typedef struct SB16State {
     QEMUSoundCard card;
-    qemu_irq *pic;
+    qemu_irq pic;
     int irq;
     int dma;
     int hdma;
@@ -190,7 +190,7 @@ static void aux_timer (void *opaque)
 {
     SB16State *s = opaque;
     s->can_write = 1;
-    qemu_irq_raise (s->pic[s->irq]);
+    qemu_irq_raise (s->pic);
 }
 
 #define DMA8_AUTO 1
@@ -598,7 +598,7 @@ static void command (SB16State *s, uint8
         case 0xf3:
             dsp_out_data (s, 0xaa);
             s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
-            qemu_irq_raise (s->pic[s->irq]);
+            qemu_irq_raise (s->pic);
             break;
 
         case 0xf9:
@@ -766,7 +766,7 @@ static void complete (SB16State *s)
                 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
                 ticks = (bytes * ticks_per_sec) / freq;
                 if (ticks < ticks_per_sec / 1024) {
-                    qemu_irq_raise (s->pic[s->irq]);
+                    qemu_irq_raise (s->pic);
                 }
                 else {
                     if (s->aux_ts) {
@@ -858,10 +858,10 @@ static void legacy_reset (SB16State *s)
 
 static void reset (SB16State *s)
 {
-    qemu_irq_lower (s->pic[s->irq]);
+    qemu_irq_lower (s->pic);
     if (s->dma_auto) {
-        qemu_irq_raise (s->pic[s->irq]);
-        qemu_irq_lower (s->pic[s->irq]);
+        qemu_irq_raise (s->pic);
+        qemu_irq_lower (s->pic);
     }
 
     s->mixer_regs[0x82] = 0;
@@ -897,7 +897,7 @@ static IO_WRITE_PROTO (dsp_write)
             if (s->v2x6 == 1) {
                 if (0 && s->highspeed) {
                     s->highspeed = 0;
-                    qemu_irq_lower (s->pic[s->irq]);
+                    qemu_irq_lower (s->pic);
                     control (s, 0);
                 }
                 else {
@@ -1008,7 +1008,7 @@ static IO_READ_PROTO (dsp_read)
         if (s->mixer_regs[0x82] & 1) {
             ack = 1;
             s->mixer_regs[0x82] &= 1;
-            qemu_irq_lower (s->pic[s->irq]);
+            qemu_irq_lower (s->pic);
         }
         break;
 
@@ -1017,7 +1017,7 @@ static IO_READ_PROTO (dsp_read)
         if (s->mixer_regs[0x82] & 2) {
             ack = 1;
             s->mixer_regs[0x82] &= 2;
-            qemu_irq_lower (s->pic[s->irq]);
+            qemu_irq_lower (s->pic);
         }
         break;
 
@@ -1231,7 +1231,7 @@ static int SB_read_DMA (void *opaque, in
 
     if (s->left_till_irq <= 0) {
         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) {
             control (s, 0);
             speaker (s, 0);
@@ -1408,8 +1408,7 @@ int SB16_init (qemu_irq *pic)
     s = qemu_mallocz (sizeof (*s));
 
     s->cmd = -1;
-    s->pic = pic;
-    s->irq = conf.irq;
+    s->pic = isa_reserve_irq(conf.irq);
     s->dma = conf.dma;
     s->hdma = conf.hdma;
     s->port = conf.port;

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

* [Qemu-devel] Re: [PATCH] isa_reserve_irq()
  2009-08-12 15:31                   ` Jes Sorensen
@ 2009-08-12 15:41                     ` Gerd Hoffmann
  0 siblings, 0 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2009-08-12 15:41 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/12/09 17:31, Jes Sorensen wrote:
> On 08/12/2009 05:28 PM, Gerd Hoffmann wrote:
>> Hmm, I don't think it makes sense to pull a dummy device out of thin
>> air, isa_reserve_irq() will do fine. But it should be be clearly
>> documented that this is for this special case and not-yet converted
>> devices. qdev-ified devices should use the other isa_*_irq functions
>> instead.
>
> Ok - do you want me to update the documentation, or is it fine as is
> then?

Would be great to update the commit message and also place a comment 
into the source code.

thanks,
   Gerd

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

* [Qemu-devel] Re: [PATCH] isa_reserve_irq() v4
  2009-08-12 15:41                   ` [Qemu-devel] [PATCH] isa_reserve_irq() v4 Jes Sorensen
@ 2009-08-12 15:55                     ` Gerd Hoffmann
  2009-08-14  8:55                     ` Gerd Hoffmann
  1 sibling, 0 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2009-08-12 15:55 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/12/09 17:41, Jes Sorensen wrote:
> Hi,
>
> Guess it's v4 by now - I have added comments to the code making it clear
> that the interface is for special cases such as 'ferr' and otherwise for
> temporary use until qdev-ification.
>
> Hope this covers what you were after.

Looks good, thanks.

Acked-by: Gerd Hoffmann <kraxel@redhat.com>

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

* Re: [Qemu-devel] [PATCH] qemu_reserve_isa_irq()
  2009-08-11 20:36         ` Gerd Hoffmann
  2009-08-12 14:42           ` [Qemu-devel] [PATCH] isa_reserve_irq() Jes Sorensen
@ 2009-08-14  8:40           ` Markus Armbruster
  1 sibling, 0 replies; 19+ messages in thread
From: Markus Armbruster @ 2009-08-14  8:40 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, Jes Sorensen, qemu-devel, Gleb Natapov

Gerd Hoffmann <kraxel@redhat.com> writes:

> Attached a patch.  It will:
>
>   (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.

It fixes this:

$ qemu tmp.qcow2 -S -M isapc
Tried to create isa device i8042 with no isa bus present.
Segmentation fault (core dumped)

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

* [Qemu-devel] Re: [PATCH] isa_reserve_irq() v4
  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
  1 sibling, 0 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2009-08-14  8:55 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Anthony Liguori, qemu-devel, Gleb Natapov

On 08/12/09 17:41, Jes Sorensen wrote:
> Hi,
>
> Guess it's v4 by now - I have added comments to the code making it clear
> that the interface is for special cases such as 'ferr' and otherwise for
> temporary use until qdev-ification.

Funny build errors, part 42:

ide.o: In function `pci_piix3_ide_init':
/home/kraxel/projects/qemu/hw/ide.c:3418: undefined reference to 
`isa_reserve_irq'
/home/kraxel/projects/qemu/hw/ide.c:3419: undefined reference to 
`isa_reserve_irq'
collect2: ld returned 1 exit status
make[1]: *** [qemu-system-arm] Error 1

didn't know arm has piix3 ;)

I'll go fix it up and re-post all pending isa-bus bits as patch series.

cheers,
   Gerd

^ 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.