From patchwork Thu Aug 6 13:45:20 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jes Sorensen X-Patchwork-Id: 30845 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by bilbo.ozlabs.org (Postfix) with ESMTPS id 5B860B6F2B for ; Thu, 6 Aug 2009 23:46:06 +1000 (EST) Received: from localhost ([127.0.0.1]:42516 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MZ3I9-0002VP-AW for incoming@patchwork.ozlabs.org; Thu, 06 Aug 2009 09:46:01 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MZ3Hd-0002UY-Rv for qemu-devel@nongnu.org; Thu, 06 Aug 2009 09:45:29 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MZ3HZ-0002QU-9k for qemu-devel@nongnu.org; Thu, 06 Aug 2009 09:45:29 -0400 Received: from [199.232.76.173] (port=50485 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MZ3HY-0002QP-UN for qemu-devel@nongnu.org; Thu, 06 Aug 2009 09:45:25 -0400 Received: from relay1.sgi.com ([192.48.179.29]:42731 helo=relay.sgi.com) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MZ3HY-0002nK-Aj for qemu-devel@nongnu.org; Thu, 06 Aug 2009 09:45:24 -0400 Received: from eye3.emea.sgi.com (eye3.emea.sgi.com [144.253.156.24]) by relay1.corp.sgi.com (Postfix) with ESMTP id 132338F808E; Thu, 6 Aug 2009 06:45:20 -0700 (PDT) Message-ID: <4A7ADE70.7060204@sgi.com> Date: Thu, 06 Aug 2009 15:45:20 +0200 From: Jes Sorensen User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1b3pre) Gecko/20090513 Fedora/3.0-2.3.beta2.fc11 Thunderbird/3.0b2 MIME-Version: 1.0 To: Anthony Liguori X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: qemu-devel , Gleb Natapov Subject: [Qemu-devel] [PATCH] qemu_reserve_isa_irq() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 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 --- 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;