From patchwork Tue May 14 15:33:35 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 16903 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yh0-f72.google.com (mail-yh0-f72.google.com [209.85.213.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 0519725D00 for ; Tue, 14 May 2013 15:42:00 +0000 (UTC) Received: by mail-yh0-f72.google.com with SMTP id z6sf1044387yhz.7 for ; Tue, 14 May 2013 08:41:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:mime-version:x-beenthere:x-received:received-spf :x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe; bh=zm3ahHDRW6tXhurLfgDpcoNLfAdLks6Ij1kKXzv+048=; b=Q5MG594HbTQ9HLk3O9qus5THLhelZbxZ9y+n+rdQ55qZ3BxNvaNY65ddPzmpWGzMNG HTGaJY3bpTFoHmApWQo/YBsf3CM7xLyFWn8jp9mgZ7+ydHFUIl+haf46fHAcTcUh4kGH cmcoSLTyCmfb6qGuwOZHKGuuatxuEkHmfJheQ+KK3tZFxdLGcDYDfo61AVCtrnMaqcuL lRSHEZ/L75AGKVUMalEQyfO8CCcalhKLKdm/T5DTDndjl9tyzN3ZxPEY6i59BWlukBqA FeL8D0xnKHf/tWUKs/P2qq4GvlGlMJJ7t688ntsY3zAU2L1J9WbG7Rt2xKAVg6datNiE AnNw== X-Received: by 10.224.200.202 with SMTP id ex10mr21337306qab.8.1368546085966; Tue, 14 May 2013 08:41:25 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.18.168 with SMTP id x8ls285060qed.75.gmail; Tue, 14 May 2013 08:41:25 -0700 (PDT) X-Received: by 10.52.75.71 with SMTP id a7mr18843614vdw.104.1368546085773; Tue, 14 May 2013 08:41:25 -0700 (PDT) Received: from mail-ve0-x234.google.com (mail-ve0-x234.google.com [2607:f8b0:400c:c01::234]) by mx.google.com with ESMTPS id gr7si10861856vdc.116.2013.05.14.08.41.25 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 14 May 2013 08:41:25 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c01::234 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c01::234; Received: by mail-ve0-f180.google.com with SMTP id pa12so783526veb.25 for ; Tue, 14 May 2013 08:41:25 -0700 (PDT) X-Received: by 10.52.108.201 with SMTP id hm9mr4522346vdb.75.1368546085652; Tue, 14 May 2013 08:41:25 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.217.15 with SMTP id hk15csp68054vcb; Tue, 14 May 2013 08:41:24 -0700 (PDT) X-Received: by 10.180.185.44 with SMTP id ez12mr7609546wic.7.1368545639043; Tue, 14 May 2013 08:33:59 -0700 (PDT) Received: from mnementh.archaic.org.uk (1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id n6si5566348wie.122.2013.05.14.08.33.57 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 14 May 2013 08:33:59 -0700 (PDT) Received-SPF: neutral (google.com: 2001:8b0:1d0::1 is neither permitted nor denied by best guess record for domain of pm215@archaic.org.uk) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1UcHEO-0005ot-Uv; Tue, 14 May 2013 16:33:36 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Anthony Liguori , Arnd Bergmann , "Michael S. Tsirkin" , Will Deacon , Aurelien Jarno , Linus Walleij , =?UTF-8?q?Andreas=20F=C3=A4rber?= , Joss Reeves Subject: [PATCH for-1.5 2/3] hw/pci-host/versatile.c: Update autodetect to detect newer kernels Date: Tue, 14 May 2013 16:33:35 +0100 Message-Id: <1368545616-22344-3-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1368545616-22344-1-git-send-email-peter.maydell@linaro.org> References: <1368545616-22344-1-git-send-email-peter.maydell@linaro.org> X-Gm-Message-State: ALoCoQlsubXY13JAMKav6TL24h6OIr9SPO4O5YbSe/7S0njZQ/2KBQ8hDHX7k1yLr2HVdApLiSLf X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c01::234 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Newer versatilepb kernels still don't get the IRQ mapping right for the PCI controller, but they get it differently wrong (they add a fixed +64 offset to everything they write to PCI_INTERRUPT_LINE). Update the autodetection to handle these too, and include a more detailed comment on the various different behaviours that might be present. Signed-off-by: Peter Maydell --- hw/pci-host/versatile.c | 69 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c index 2bb09fa..f19e2f5 100644 --- a/hw/pci-host/versatile.c +++ b/hw/pci-host/versatile.c @@ -28,6 +28,32 @@ * this allows a newer kernel to use the INTERRUPT_LINE * registers arbitrarily once it has indicated that it isn't * broken in its init code somewhere. + * + * Unfortunately we have to cope with multiple different + * variants on the broken kernel behaviour: + * phase I (before kernel commit 1bc39ac5d) kernels assume old + * QEMU behaviour, so they use IRQ 27 for all slots + * phase II (1bc39ac5d and later, but before e3e92a7be6) kernels + * swizzle IRQs between slots, but do it wrongly, so they + * work only for every fourth PCI card, and only if (like old + * QEMU) the PCI host device is at slot 0 rather than where + * the h/w actually puts it + * phase III (e3e92a7be6 and later) kernels still swizzle IRQs between + * slots wrongly, but add a fixed offset of 64 to everything + * they write to PCI_INTERRUPT_LINE. + * + * We live in hope of a mythical phase IV kernel which might + * actually behave in ways that work on the hardware. Such a + * kernel should probably start off by writing some value neither + * 27 nor 91 to slot zero's PCI_INTERRUPT_LINE register to + * disable the autodetection. After that it can do what it likes. + * + * Slot % 4 | hw | I | II | III + * ------------------------------- + * 0 | 29 | 27 | 27 | 91 + * 1 | 30 | 27 | 28 | 92 + * 2 | 27 | 27 | 29 | 93 + * 3 | 28 | 27 | 30 | 94 */ enum { PCI_VPB_IRQMAP_ASSUME_OK, @@ -214,6 +240,41 @@ static const MemoryRegionOps pci_vpb_reg_ops = { }, }; +static int pci_vpb_broken_irq(int slot, int irq) +{ + /* Determine whether this IRQ value for this slot represents a + * known broken Linux kernel behaviour for this slot. + * Return one of the PCI_VPB_IRQMAP_ constants: + * BROKEN : if this definitely looks like a broken kernel + * FORCE_OK : if this definitely looks good + * ASSUME_OK : if we can't tell + */ + slot %= PCI_NUM_PINS; + + if (irq == 27) { + if (slot == 2) { + /* Might be a Phase I kernel, or might be a fixed kernel, + * since slot 2 is where we expect this IRQ. + */ + return PCI_VPB_IRQMAP_ASSUME_OK; + } + /* Phase I kernel */ + return PCI_VPB_IRQMAP_BROKEN; + } + if (irq == slot + 27) { + /* Phase II kernel */ + return PCI_VPB_IRQMAP_BROKEN; + } + if (irq == slot + 27 + 64) { + /* Phase III kernel */ + return PCI_VPB_IRQMAP_BROKEN; + } + /* Anything else must be a fixed kernel, possibly using an + * arbitrary irq map. + */ + return PCI_VPB_IRQMAP_FORCE_OK; +} + static void pci_vpb_config_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -221,13 +282,7 @@ static void pci_vpb_config_write(void *opaque, hwaddr addr, if (!s->realview && (addr & 0xff) == PCI_INTERRUPT_LINE && s->irq_mapping == PCI_VPB_IRQMAP_ASSUME_OK) { uint8_t devfn = addr >> 8; - if ((PCI_SLOT(devfn) % PCI_NUM_PINS) != 2) { - if (val == 27) { - s->irq_mapping = PCI_VPB_IRQMAP_BROKEN; - } else { - s->irq_mapping = PCI_VPB_IRQMAP_FORCE_OK; - } - } + s->irq_mapping = pci_vpb_broken_irq(PCI_SLOT(devfn), val); } pci_data_write(&s->pci_bus, addr, val, size); }