x86: qemu: Implement PIRQ routing

Support QEMU PIRQ routing via device tree on both i440fx and q35
platforms. With this commit, Linux booting on QEMU from U-Boot
has working ATA/SATA, USB and ethernet.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
index c4cac04..0e9f15f 100644
--- a/arch/x86/cpu/coreboot/coreboot.c
+++ b/arch/x86/cpu/coreboot/coreboot.c
@@ -89,3 +89,8 @@
 {
 	return 0;
 }
+
+int arch_misc_init(void)
+{
+	return 0;
+}
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
index 0f98476..930d2b6 100644
--- a/arch/x86/cpu/qemu/qemu.c
+++ b/arch/x86/cpu/qemu/qemu.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <asm/irq.h>
 #include <asm/post.h>
 #include <asm/processor.h>
 
@@ -35,3 +36,10 @@
 	/* cold reset */
 	x86_full_reset();
 }
+
+int arch_misc_init(void)
+{
+	pirq_init();
+
+	return 0;
+}
diff --git a/arch/x86/dts/qemu-x86_i440fx.dts b/arch/x86/dts/qemu-x86_i440fx.dts
index 4cf843b..557428a 100644
--- a/arch/x86/dts/qemu-x86_i440fx.dts
+++ b/arch/x86/dts/qemu-x86_i440fx.dts
@@ -6,6 +6,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
 /include/ "skeleton.dtsi"
 /include/ "serial.dtsi"
 
@@ -29,6 +31,20 @@
 		ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0 0x10000000
 			0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000
 			0x01000000 0x0 0x2000 0x2000 0 0xe000>;
+
+		irq-router@1,0 {
+			reg = <0x00000800 0 0 0 0>;
+			compatible = "intel,irq-router";
+			intel,pirq-config = "pci";
+			intel,pirq-link = <0x60 4>;
+			intel,pirq-mask = <0x0e40>;
+			intel,pirq-routing = <
+				/* PIIX UHCI */
+				PCI_BDF(0, 1, 2) INTD PIRQD
+				/* e1000 NIC */
+				PCI_BDF(0, 3, 0) INTA PIRQC
+			>;
+		};
 	};
 
 };
diff --git a/arch/x86/dts/qemu-x86_q35.dts b/arch/x86/dts/qemu-x86_q35.dts
index 02a483c..c259f2a 100644
--- a/arch/x86/dts/qemu-x86_q35.dts
+++ b/arch/x86/dts/qemu-x86_q35.dts
@@ -6,6 +6,18 @@
 
 /dts-v1/;
 
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+/* ICH9 IRQ router has discrete PIRQ control registers */
+#undef PIRQE
+#undef PIRQF
+#undef PIRQG
+#undef PIRQH
+#define PIRQE	8
+#define PIRQF	9
+#define PIRQG	10
+#define PIRQH	11
+
 /include/ "skeleton.dtsi"
 /include/ "serial.dtsi"
 
@@ -30,6 +42,26 @@
 		ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0 0x10000000
 			0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000
 			0x01000000 0x0 0x2000 0x2000 0 0xe000>;
+
+		irq-router@1f,0 {
+			reg = <0x0000f800 0 0 0 0>;
+			compatible = "intel,irq-router";
+			intel,pirq-config = "pci";
+			intel,pirq-link = <0x60 8>;
+			intel,pirq-mask = <0x0e40>;
+			intel,pirq-routing = <
+				/* e1000 NIC */
+				PCI_BDF(0, 2, 0) INTA PIRQG
+				/* ICH9 UHCI */
+				PCI_BDF(0, 29, 0) INTA PIRQA
+				PCI_BDF(0, 29, 1) INTB PIRQB
+				PCI_BDF(0, 29, 2) INTC PIRQC
+				/* ICH9 EHCI */
+				PCI_BDF(0, 29, 7) INTD PIRQD
+				/* ICH9 SATA */
+				PCI_BDF(0, 31, 2) INTA PIRQA
+			>;
+		};
 	};
 
 };