From patchwork Fri Feb 15 21:11:41 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 220872 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 788C42C0082 for ; Sat, 16 Feb 2013 08:11:58 +1100 (EST) Received: from localhost ([::1]:46640 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U6SZY-0000gm-FN for incoming@patchwork.ozlabs.org; Fri, 15 Feb 2013 16:11:56 -0500 Received: from eggs.gnu.org ([208.118.235.92]:46677) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U6SZM-0000Z9-MV for qemu-devel@nongnu.org; Fri, 15 Feb 2013 16:11:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U6SZL-0005HC-8x for qemu-devel@nongnu.org; Fri, 15 Feb 2013 16:11:44 -0500 Received: from mx1.redhat.com ([209.132.183.28]:19758) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U6SZK-0005Gx-QZ for qemu-devel@nongnu.org; Fri, 15 Feb 2013 16:11:42 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r1FLBgn2023879 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 15 Feb 2013 16:11:42 -0500 Received: from bling.home (ovpn-113-86.phx2.redhat.com [10.3.113.86]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r1FLBfTf024839; Fri, 15 Feb 2013 16:11:41 -0500 To: seabios@seabios.org From: Alex Williamson Date: Fri, 15 Feb 2013 14:11:41 -0700 Message-ID: <20130215211141.5990.92169.stgit@bling.home> In-Reply-To: <20130215210807.5990.82992.stgit@bling.home> References: <20130215210807.5990.82992.stgit@bling.home> User-Agent: StGit/0.16 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: qemu-devel@nongnu.org Subject: [Qemu-devel] [RESEND PATCH v2 2/2] seabios q35: Add new PCI slot to irq routing function X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org q35/ich9 doesn't use the same interrupt mapping function as i440fx/piix. PIRQA:D and PIRQE:H are programmed identically, but we start at index 0, not index -1. Slots 25 through 31 are also programmed independently. When running qemu w/o this patch, a device at address 0:6.0 will have its PCI interrupt line register programmed with irq 10 (as seen by info pci), but it actually uses irq 11 (as reported the guest). Half of the interrupt lines are misprogrammedi like this. Functionally, a fully emulated qemu guest doesn't care much, but when we try to use device assignment, we really need to know the correct irqs. Signed-off-by: Alex Williamson --- src/pciinit.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/pciinit.c b/src/pciinit.c index 05c0fe8..4cdc777 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -91,8 +91,10 @@ const u8 pci_irqs[4] = { 10, 10, 11, 11 }; +static int (*pci_slot_get_irq)(struct pci_device *pci, int pin); + // Return the global irq number corresponding to a host bus device irq pin. -static int pci_slot_get_irq(struct pci_device *pci, int pin) +static int piix_pci_slot_get_irq(struct pci_device *pci, int pin) { int slot_addend = 0; @@ -104,6 +106,31 @@ static int pci_slot_get_irq(struct pci_device *pci, int pin) return pci_irqs[(pin - 1 + slot_addend) & 3]; } +static int mch_pci_slot_get_irq(struct pci_device *pci, int pin) +{ + int irq, slot, pin_addend = 0; + + while (pci->parent != NULL) { + pin_addend += pci_bdf_to_dev(pci->bdf); + pci = pci->parent; + } + slot = pci_bdf_to_dev(pci->bdf); + + switch (slot) { + /* Slots 0-24 rotate slot:pin mapping similar to piix above, but + with a different starting index - see q35-acpi-dsdt.dsl */ + case 0 ... 24: + irq = pci_irqs[(pin - 1 + pin_addend + slot) & 3]; + break; + /* Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H) */ + case 25 ... 31: + irq = pci_irqs[(pin - 1 + pin_addend) & 3]; + break; + } + + return irq; +} + /* PIIX3/PIIX4 PCI to ISA bridge */ static void piix_isa_bridge_setup(struct pci_device *pci, void *arg) { @@ -292,6 +319,8 @@ void i440fx_mem_addr_setup(struct pci_device *dev, void *arg) pcimem_start = 0x80000000; else if (RamSize <= 0xc0000000) pcimem_start = 0xc0000000; + + pci_slot_get_irq = piix_pci_slot_get_irq; } void mch_mem_addr_setup(struct pci_device *dev, void *arg) @@ -310,6 +339,8 @@ void mch_mem_addr_setup(struct pci_device *dev, void *arg) /* setup pci i/o window (above mmconfig) */ pcimem_start = addr + size; + + pci_slot_get_irq = mch_pci_slot_get_irq; } static const struct pci_device_id pci_platform_tbl[] = {