changeset 1635:1b2017d3ecf5

Undo random arm IRQ routing breakage du jour, yet again.
author Rob Landley <rob@landley.net>
date Sat, 26 Oct 2013 14:07:48 -0500
parents 23b9782e7ab0
children 36064844d3e1
files sources/patches/linux-arm-qemuirq.patch sources/patches/linux-arm.patch
diffstat 2 files changed, 63 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sources/patches/linux-arm-qemuirq.patch	Sat Oct 26 14:07:48 2013 -0500
@@ -0,0 +1,63 @@
+Modify arm IRQ setup to work with all versions of qemu since 1.0.
+
+For many years, the kernel's versatile board setup expected all devices
+to share IRQ 27, and QEMU 1.2 helpfully emulated hardware that did that
+(or used IRQ 59 if the IRQ controller was told to shift everything up 32
+places). This wasn't what the actual hardware did, but nobody noticed for
+over a decade because this reference board was long-gone and only useful
+as a base for virtualization.
+
+Then the kernel developers noticed that the default IRQ range could
+(theoretically) use IRQ 0 as an actual IRQ, so they poked the "move everything
+up 32 places" register... and got the math wrong calculating the new IRQ
+to expect stuff on. (Because just adding 32 wouldn't be the right thing to
+do, you've gotta do a multi-stage process going through three different
+functions with a callback.)
+
+When informed they'd broken qemu, they looked up old Versatile documentation
+and realized what they'd done had never matched real hardware, and adjusted
+it to some other random value: still getting the math wrong. Then they finally
+fixed the wrong math, but it turns out the documentation they were using
+didn't match what actual hardware was doing, or something. All in all they
+changed the IRQ mapping at least _4_TIMES_ before finally unearthing an
+actual Versatile board out of some landfill or other to test it out on.
+Needless to say, "this breaks QEMU" was not considered a valid data point.
+
+Meanwhile, QEMU 1.2 and earlier only supported the "everything on irq 27" mode,
+and the next several releases supported random potluck things the kernel du
+jour did, but current ones don't.
+
+BUT: if you the kernel requests irq 27 from the controller as
+its first action, QEMU thinks you're running an old "everying on 27" kernel
+and triggers an emulation mode that puts everything on IRQ 27 (or 59 if
+you flip the add 32 bit in the controller, meaning current kernels aren't
+bothered by IRQ 0 being potentially used). And this runs on all the qemu
+versions since 1.0. (Although you still don't want to use QEMU 1.3 and 1.4
+because they had a bug in TCG that got the size of translated blocks wrong
+causing spurious but highly intermittent segfaults...)
+
+Note, I broke this patch out of the big arm patch after the FIFTH time
+they made changes that prevented this patch from cleanly applying.
+
+diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
+index c97be4e..da0342d 100644
+--- a/arch/arm/mach-versatile/pci.c
++++ b/arch/arm/mach-versatile/pci.c
+@@ -305,7 +305,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
+ 	 * real hardware behaviour and it need not be backwards
+ 	 * compatible for us. This write is harmless on real hardware.
+ 	 */
+-	__raw_writel(0, VERSATILE_PCI_VIRT_BASE+PCI_INTERRUPT_LINE);
++	__raw_writel(27, VERSATILE_PCI_VIRT_BASE+PCI_INTERRUPT_LINE);
+ 
+ 	/*
+ 	 * Do not to map Versatile FPGA PCI device into memory space
+@@ -346,7 +346,7 @@ static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+ 	 * 30	PCI0	PCI1	PCI2	PCI3
+ 	 * 29	PCI3	PCI0	PCI1	PCI2
+ 	 */
+-	irq = IRQ_SIC_PCI0 + ((slot + 2 + pin - 1) & 3);
++	irq = 59;
+ 
+ 	return irq;
+ }
--- a/sources/patches/linux-arm.patch	Thu Oct 17 02:15:26 2013 -0500
+++ b/sources/patches/linux-arm.patch	Sat Oct 26 14:07:48 2013 -0500
@@ -1,10 +1,6 @@
 Make the "Arm Versatile" board even more versatile, for QEMU, which can
 stick weird processors into things that were never rmeant to receive them.
 
-In addition, fix breakage in 3.5 that adjusted versatile's interrupts to
-match the spec instead of matching what qemu supports. (It only _ever_ ran
-under qemu, nobody seems to have classic versatile hardware anymore, so...)
-
 diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
 index c1f38f6..fe5738c 100644
 --- a/arch/arm/mach-versatile/Kconfig
@@ -90,22 +86,3 @@
  config ARCH_VERSATILE_PB
  	bool "Support Versatile Platform Baseboard for ARM926EJ-S"
  	default y
-diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
-index e92e5e0..807a5ad 100644
---- a/arch/arm/mach-versatile/pci.c
-+++ b/arch/arm/mach-versatile/pci.c
-@@ -333,7 +333,13 @@ static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
- 	 *  26     1     IRQ_SIC_PCI2
- 	 *  27     1     IRQ_SIC_PCI3
- 	 */
--	irq = IRQ_SIC_PCI0 + ((slot - 24 + pin - 1) & 3);
-+	// Hit QEMU 1.5.0 and later with a brick so it uses the IRQ we say.
-+	dev->bus->ops->write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, 27);
-+
-+	// The kernel has no clue where IRQs are, and its current assignments
-+	// match neither the hardware nor historic QEMU. Use historic QEMU
-+	// for compatability with old versions.
-+	irq = 59; //IRQ_SIC_PCI0 + ((slot - 24 + pin - 1) & 3);
- 
- 	return irq;
- }