Merge git://git.denx.de/u-boot-fdt
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index b6aae37..02c4cd3 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -22,6 +22,8 @@
 
 void reset_cpu(ulong ignored)
 {
+	/* Do this here while it still has an effect */
+	os_fd_restore();
 	if (state_uninit())
 		os_exit(2);
 
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index e6dd17e..8a4d719 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -107,10 +107,12 @@
 static struct termios orig_term;
 static bool term_setup;
 
-static void os_fd_restore(void)
+void os_fd_restore(void)
 {
-	if (term_setup)
+	if (term_setup) {
 		tcsetattr(0, TCSANOW, &orig_term);
+		term_setup = false;
+	}
 }
 
 /* Put tty into raw mode so <tab> and <ctrl+c> work */
@@ -120,7 +122,6 @@
 
 	if (term_setup)
 		return;
-	term_setup = true;
 
 	/* If not a tty, don't complain */
 	if (tcgetattr(fd, &orig_term))
@@ -134,6 +135,7 @@
 	if (tcsetattr(fd, TCSANOW, &term))
 		return;
 
+	term_setup = true;
 	atexit(os_fd_restore);
 }
 
diff --git a/arch/sandbox/dts/Makefile b/arch/sandbox/dts/Makefile
index 562a078..517b555 100644
--- a/arch/sandbox/dts/Makefile
+++ b/arch/sandbox/dts/Makefile
@@ -1,5 +1,5 @@
 dtb-$(CONFIG_SANDBOX) += sandbox.dtb
-dtb-$(CONFIG_DM_TEST) += test.dtb
+dtb-$(CONFIG_UT_DM) += test.dtb
 
 targets += $(dtb-y)
 
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index a3ebd80..8927527 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -17,30 +17,6 @@
 		stdout-path = "/serial";
 	};
 
-	/* Needs to be available prior to relocation */
-	uart0: serial {
-		compatible = "sandbox,serial";
-		sandbox,text-colour = "cyan";
-	};
-
-	triangle {
-		compatible = "demo-shape";
-		colour = "cyan";
-		sides = <3>;
-		character = <83>;
-		light-gpios = <&gpio_a 2>, <&gpio_b 6 0>;
-	};
-	square {
-		compatible = "demo-shape";
-		colour = "blue";
-		sides = <4>;
-	};
-	hexagon {
-		compatible = "demo-simple";
-		colour = "white";
-		sides = <6>;
-	};
-
 	cros_ec: cros-ec@0 {
 		reg = <0 0>;
 		compatible = "google,cros-ec-sandbox";
@@ -70,10 +46,22 @@
 		};
 	};
 
-	lcd {
-		compatible = "sandbox,lcd-sdl";
-		xres = <1366>;
-		yres = <768>;
+	eth@10002000 {
+		compatible = "sandbox,eth";
+		reg = <0x10002000 0x1000>;
+		fake-host-hwaddr = [00 00 66 44 22 00];
+	};
+
+	eth@80000000 {
+		compatible = "sandbox,eth-raw";
+		reg = <0x80000000 0x1000>;
+		host-raw-interface = "eth0";
+	};
+
+	eth@90000000 {
+		compatible = "sandbox,eth-raw";
+		reg = <0x90000000 0x1000>;
+		host-raw-interface = "lo";
 	};
 
 	gpio_a: gpios@0 {
@@ -92,6 +80,12 @@
 		num-gpios = <10>;
 	};
 
+	hexagon {
+		compatible = "demo-simple";
+		colour = "white";
+		sides = <6>;
+	};
+
 	i2c_0: i2c@0 {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -120,18 +114,10 @@
 		};
 	};
 
-	spi@0 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0 0>;
-		compatible = "sandbox,spi";
-		cs-gpios = <0>, <&gpio_a 0>;
-		firmware_storage_spi: flash@0 {
-			reg = <0>;
-			compatible = "spansion,m25p16", "sandbox,spi-flash";
-			spi-max-frequency = <40000000>;
-			sandbox,filename = "spi.bin";
-		};
+	lcd {
+		compatible = "sandbox,lcd-sdl";
+		xres = <1366>;
+		yres = <768>;
 	};
 
 	pci: pci-controller {
@@ -150,22 +136,38 @@
 		};
 	};
 
-	eth@10002000 {
-		compatible = "sandbox,eth";
-		reg = <0x10002000 0x1000>;
-		fake-host-hwaddr = [00 00 66 44 22 00];
+	spi@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0 0>;
+		compatible = "sandbox,spi";
+		cs-gpios = <0>, <&gpio_a 0>;
+		firmware_storage_spi: flash@0 {
+			reg = <0>;
+			compatible = "spansion,m25p16", "sandbox,spi-flash";
+			spi-max-frequency = <40000000>;
+			sandbox,filename = "spi.bin";
+		};
 	};
 
-	eth@80000000 {
-		compatible = "sandbox,eth-raw";
-		reg = <0x80000000 0x1000>;
-		host-raw-interface = "eth0";
+	square {
+		compatible = "demo-shape";
+		colour = "blue";
+		sides = <4>;
 	};
 
-	eth@90000000 {
-		compatible = "sandbox,eth-raw";
-		reg = <0x90000000 0x1000>;
-		host-raw-interface = "lo";
+	triangle {
+		compatible = "demo-shape";
+		colour = "cyan";
+		sides = <3>;
+		character = <83>;
+		light-gpios = <&gpio_a 2>, <&gpio_b 6 0>;
+	};
+
+	/* Needs to be available prior to relocation */
+	uart0: serial {
+		compatible = "sandbox,serial";
+		sandbox,text-colour = "cyan";
 	};
 
 	usb@0 {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 1bc3ca0..c25614a 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -8,9 +8,13 @@
 
 	aliases {
 		console = &uart0;
+		eth0 = "/eth@10002000";
+		eth5 = &eth_5;
 		i2c0 = "/i2c@0";
-		spi0 = "/spi@0";
 		pci0 = &pci;
+		rtc0 = &rtc_0;
+		rtc1 = &rtc_1;
+		spi0 = "/spi@0";
 		testfdt6 = "/e-test";
 		testbus3 = "/some-bus";
 		testfdt0 = "/some-bus/c-test@0";
@@ -18,18 +22,11 @@
 		testfdt3 = "/b-test";
 		testfdt5 = "/some-bus/c-test@5";
 		testfdt8 = "/a-test";
-		eth0 = "/eth@10002000";
-		eth5 = &eth_5;
 		usb0 = &usb_0;
 		usb1 = &usb_1;
 		usb2 = &usb_2;
 	};
 
-	uart0: serial {
-		compatible = "sandbox,serial";
-		u-boot,dm-pre-reloc;
-	};
-
 	a-test {
 		reg = <0>;
 		compatible = "denx,u-boot-fdt-test";
@@ -108,6 +105,24 @@
 		compatible = "denx,u-boot-fdt-test";
 	};
 
+	eth@10002000 {
+		compatible = "sandbox,eth";
+		reg = <0x10002000 0x1000>;
+		fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>;
+	};
+
+	eth_5: eth@10003000 {
+		compatible = "sandbox,eth";
+		reg = <0x10003000 0x1000>;
+		fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>;
+	};
+
+	eth@10004000 {
+		compatible = "sandbox,eth";
+		reg = <0x10004000 0x1000>;
+		fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x22>;
+	};
+
 	gpio_a: base-gpios {
 		compatible = "sandbox,gpio";
 		gpio-controller;
@@ -140,6 +155,22 @@
 			};
 		};
 
+		rtc_0: rtc@43 {
+			reg = <0x43>;
+			compatible = "sandbox-rtc";
+			emul {
+				compatible = "sandbox,i2c-rtc";
+			};
+		};
+
+		rtc_1: rtc@61 {
+			reg = <0x61>;
+			compatible = "sandbox-rtc";
+			emul {
+				compatible = "sandbox,i2c-rtc";
+			};
+		};
+
 		sandbox_pmic: sandbox_pmic {
 			reg = <0x40>;
 		};
@@ -175,22 +206,9 @@
 		};
 	};
 
-	eth@10002000 {
-		compatible = "sandbox,eth";
-		reg = <0x10002000 0x1000>;
-		fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>;
-	};
-
-	eth_5: eth@10003000 {
-		compatible = "sandbox,eth";
-		reg = <0x10003000 0x1000>;
-		fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>;
-	};
-
-	eth@10004000 {
-		compatible = "sandbox,eth";
-		reg = <0x10004000 0x1000>;
-		fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x22>;
+	uart0: serial {
+		compatible = "sandbox,serial";
+		u-boot,dm-pre-reloc;
 	};
 
 	usb_0: usb@0 {
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 8e734fd..3506ba2 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -12,11 +12,14 @@
 
 choice
 	prompt "Mainboard vendor"
-	default VENDOR_COREBOOT
+	default VENDOR_EMULATION
 
 config VENDOR_COREBOOT
 	bool "coreboot"
 
+config VENDOR_EMULATION
+	bool "emulation"
+
 config VENDOR_GOOGLE
 	bool "Google"
 
@@ -27,6 +30,7 @@
 
 # board-specific options below
 source "board/coreboot/Kconfig"
+source "board/emulation/Kconfig"
 source "board/google/Kconfig"
 source "board/intel/Kconfig"
 
@@ -34,6 +38,7 @@
 source "arch/x86/cpu/baytrail/Kconfig"
 source "arch/x86/cpu/coreboot/Kconfig"
 source "arch/x86/cpu/ivybridge/Kconfig"
+source "arch/x86/cpu/qemu/Kconfig"
 source "arch/x86/cpu/quark/Kconfig"
 source "arch/x86/cpu/queensbay/Kconfig"
 
@@ -182,147 +187,6 @@
 	  memory is set as write-combining cache type. This option
 	  enables marking the graphics memory as write-combining.
 
-menu "Display"
-
-config FRAMEBUFFER_SET_VESA_MODE
-	prompt "Set framebuffer graphics resolution"
-	bool
-	help
-	  Set VESA/native framebuffer mode (needed for bootsplash and graphical framebuffer console)
-
-choice
-	prompt "framebuffer graphics resolution"
-	default FRAMEBUFFER_VESA_MODE_117
-	depends on FRAMEBUFFER_SET_VESA_MODE
-	help
-	  This option sets the resolution used for the coreboot framebuffer (and
-	  bootsplash screen).
-
-config FRAMEBUFFER_VESA_MODE_100
-	bool "640x400 256-color"
-
-config FRAMEBUFFER_VESA_MODE_101
-	bool "640x480 256-color"
-
-config FRAMEBUFFER_VESA_MODE_102
-	bool "800x600 16-color"
-
-config FRAMEBUFFER_VESA_MODE_103
-	bool "800x600 256-color"
-
-config FRAMEBUFFER_VESA_MODE_104
-	bool "1024x768 16-color"
-
-config FRAMEBUFFER_VESA_MODE_105
-	bool "1024x7686 256-color"
-
-config FRAMEBUFFER_VESA_MODE_106
-	bool "1280x1024 16-color"
-
-config FRAMEBUFFER_VESA_MODE_107
-	bool "1280x1024 256-color"
-
-config FRAMEBUFFER_VESA_MODE_108
-	bool "80x60 text"
-
-config FRAMEBUFFER_VESA_MODE_109
-	bool "132x25 text"
-
-config FRAMEBUFFER_VESA_MODE_10A
-	bool "132x43 text"
-
-config FRAMEBUFFER_VESA_MODE_10B
-	bool "132x50 text"
-
-config FRAMEBUFFER_VESA_MODE_10C
-	bool "132x60 text"
-
-config FRAMEBUFFER_VESA_MODE_10D
-	bool "320x200 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_10E
-	bool "320x200 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_10F
-	bool "320x200 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_110
-	bool "640x480 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_111
-	bool "640x480 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_112
-	bool "640x480 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_113
-	bool "800x600 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_114
-	bool "800x600 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_115
-	bool "800x600 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_116
-	bool "1024x768 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_117
-	bool "1024x768 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_118
-	bool "1024x768 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_119
-	bool "1280x1024 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_11A
-	bool "1280x1024 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_11B
-	bool "1280x1024 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_USER
-	bool "Manually select VESA mode"
-
-endchoice
-
-# Map the config names to an integer (KB).
-config FRAMEBUFFER_VESA_MODE
-	prompt "VESA mode" if FRAMEBUFFER_VESA_MODE_USER
-	hex
-	default 0x100 if FRAMEBUFFER_VESA_MODE_100
-	default 0x101 if FRAMEBUFFER_VESA_MODE_101
-	default 0x102 if FRAMEBUFFER_VESA_MODE_102
-	default 0x103 if FRAMEBUFFER_VESA_MODE_103
-	default 0x104 if FRAMEBUFFER_VESA_MODE_104
-	default 0x105 if FRAMEBUFFER_VESA_MODE_105
-	default 0x106 if FRAMEBUFFER_VESA_MODE_106
-	default 0x107 if FRAMEBUFFER_VESA_MODE_107
-	default 0x108 if FRAMEBUFFER_VESA_MODE_108
-	default 0x109 if FRAMEBUFFER_VESA_MODE_109
-	default 0x10A if FRAMEBUFFER_VESA_MODE_10A
-	default 0x10B if FRAMEBUFFER_VESA_MODE_10B
-	default 0x10C if FRAMEBUFFER_VESA_MODE_10C
-	default 0x10D if FRAMEBUFFER_VESA_MODE_10D
-	default 0x10E if FRAMEBUFFER_VESA_MODE_10E
-	default 0x10F if FRAMEBUFFER_VESA_MODE_10F
-	default 0x110 if FRAMEBUFFER_VESA_MODE_110
-	default 0x111 if FRAMEBUFFER_VESA_MODE_111
-	default 0x112 if FRAMEBUFFER_VESA_MODE_112
-	default 0x113 if FRAMEBUFFER_VESA_MODE_113
-	default 0x114 if FRAMEBUFFER_VESA_MODE_114
-	default 0x115 if FRAMEBUFFER_VESA_MODE_115
-	default 0x116 if FRAMEBUFFER_VESA_MODE_116
-	default 0x117 if FRAMEBUFFER_VESA_MODE_117
-	default 0x118 if FRAMEBUFFER_VESA_MODE_118
-	default 0x119 if FRAMEBUFFER_VESA_MODE_119
-	default 0x11A if FRAMEBUFFER_VESA_MODE_11A
-	default 0x11B if FRAMEBUFFER_VESA_MODE_11B
-	default 0x117 if FRAMEBUFFER_VESA_MODE_USER
-
-endmenu
-
 config HAVE_FSP
 	bool "Add an Firmware Support Package binary"
 	help
@@ -356,6 +220,7 @@
 
 config FSP_TEMP_RAM_ADDR
 	hex
+	depends on HAVE_FSP
 	default 0x2000000
 	help
 	  Stack top address which is used in FspInit after DRAM is ready and
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 043bea2..7ff05e6 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -14,11 +14,12 @@
 
 obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
 obj-$(CONFIG_SYS_COREBOOT) += coreboot/
+obj-$(CONFIG_QEMU) += qemu/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
 obj-$(CONFIG_INTEL_QUARK) += quark/
 obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/
-obj-y += lapic.o
+obj-y += irq.o lapic.o
 obj-$(CONFIG_SMP) += mp_init.o
 obj-y += mtrr.o
 obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/cpu/baytrail/pci.c b/arch/x86/cpu/baytrail/pci.c
index 6c291f9..48409de 100644
--- a/arch/x86/cpu/baytrail/pci.c
+++ b/arch/x86/cpu/baytrail/pci.c
@@ -39,7 +39,7 @@
 	pci_set_region(hose->regions + 3,
 		       0,
 		       0,
-		       gd->ram_size,
+		       gd->ram_size < 0x80000000 ? gd->ram_size : 0x80000000,
 		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
 
 	hose->region_count = 4;
diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
index 4cdd0d4..0e9f15f 100644
--- a/arch/x86/cpu/coreboot/coreboot.c
+++ b/arch/x86/cpu/coreboot/coreboot.c
@@ -7,16 +7,11 @@
  */
 
 #include <common.h>
-#include <asm/u-boot-x86.h>
-#include <flash.h>
+#include <fdtdec.h>
 #include <netdev.h>
-#include <ns16550.h>
-#include <asm/msr.h>
-#include <asm/cache.h>
-#include <asm/cpu.h>
 #include <asm/io.h>
+#include <asm/msr.h>
 #include <asm/mtrr.h>
-#include <asm/arch/tables.h>
 #include <asm/arch/sysinfo.h>
 #include <asm/arch/timestamp.h>
 
@@ -53,13 +48,6 @@
 	return 0;
 }
 
-#ifndef CONFIG_SYS_NO_FLASH
-ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
-{
-	return 0;
-}
-#endif
-
 int board_eth_init(bd_t *bis)
 {
 	return pci_eth_init(bis);
@@ -67,7 +55,8 @@
 
 void board_final_cleanup(void)
 {
-	/* Un-cache the ROM so the kernel has one
+	/*
+	 * Un-cache the ROM so the kernel has one
 	 * more MTRR available.
 	 *
 	 * Coreboot should have assigned this to the
@@ -86,21 +75,22 @@
 		mtrr_close(&state);
 	}
 
-	/* Issue SMI to Coreboot to lock down ME and registers */
-	printf("Finalizing Coreboot\n");
-	outb(0xcb, 0xb2);
-}
-
-void panic_puts(const char *str)
-{
-	NS16550_t port = (NS16550_t)0x3f8;
-
-	NS16550_init(port, 1);
-	while (*str)
-		NS16550_putc(port, *str++);
+	if (!fdtdec_get_config_bool(gd->fdt_blob, "u-boot,no-apm-finalize")) {
+		/*
+		 * Issue SMI to coreboot to lock down ME and registers
+		 * when allowed via device tree
+		 */
+		printf("Finalizing coreboot\n");
+		outb(0xcb, 0xb2);
+	}
 }
 
 int misc_init_r(void)
 {
 	return 0;
 }
+
+int arch_misc_init(void)
+{
+	return 0;
+}
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c
new file mode 100644
index 0000000..74b89ad
--- /dev/null
+++ b/arch/x86/cpu/irq.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/pirq_routing.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct irq_router irq_router;
+static struct irq_routing_table *pirq_routing_table;
+
+bool pirq_check_irq_routed(int link, u8 irq)
+{
+	u8 pirq;
+	int base = irq_router.link_base;
+
+	if (irq_router.config == PIRQ_VIA_PCI)
+		pirq = x86_pci_read_config8(irq_router.bdf,
+					    LINK_N2V(link, base));
+	else
+		pirq = readb(irq_router.ibase + LINK_N2V(link, base));
+
+	pirq &= 0xf;
+
+	/* IRQ# 0/1/2/8/13 are reserved */
+	if (pirq < 3 || pirq == 8 || pirq == 13)
+		return false;
+
+	return pirq == irq ? true : false;
+}
+
+int pirq_translate_link(int link)
+{
+	return LINK_V2N(link, irq_router.link_base);
+}
+
+void pirq_assign_irq(int link, u8 irq)
+{
+	int base = irq_router.link_base;
+
+	/* IRQ# 0/1/2/8/13 are reserved */
+	if (irq < 3 || irq == 8 || irq == 13)
+		return;
+
+	if (irq_router.config == PIRQ_VIA_PCI)
+		x86_pci_write_config8(irq_router.bdf,
+				      LINK_N2V(link, base), irq);
+	else
+		writeb(irq, irq_router.ibase + LINK_N2V(link, base));
+}
+
+static inline void fill_irq_info(struct irq_info **slotp, int *entries, u8 bus,
+				 u8 device, u8 func, u8 pin, u8 pirq)
+{
+	struct irq_info *slot = *slotp;
+
+	slot->bus = bus;
+	slot->devfn = (device << 3) | func;
+	slot->irq[pin - 1].link = LINK_N2V(pirq, irq_router.link_base);
+	slot->irq[pin - 1].bitmap = irq_router.irq_mask;
+	(*entries)++;
+	(*slotp)++;
+}
+
+__weak void cpu_irq_init(void)
+{
+	return;
+}
+
+static int create_pirq_routing_table(void)
+{
+	const void *blob = gd->fdt_blob;
+	struct fdt_pci_addr addr;
+	int node;
+	int len, count;
+	const u32 *cell;
+	struct irq_routing_table *rt;
+	struct irq_info *slot;
+	int irq_entries = 0;
+	int i;
+	int ret;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_IRQ_ROUTER);
+	if (node < 0) {
+		debug("%s: Cannot find irq router node\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = fdtdec_get_pci_addr(blob, node, FDT_PCI_SPACE_CONFIG,
+				  "reg", &addr);
+	if (ret)
+		return ret;
+
+	/* extract the bdf from fdt_pci_addr */
+	irq_router.bdf = addr.phys_hi & 0xffff00;
+
+	ret = fdt_find_string(blob, node, "intel,pirq-config", "pci");
+	if (!ret) {
+		irq_router.config = PIRQ_VIA_PCI;
+	} else {
+		ret = fdt_find_string(blob, node, "intel,pirq-config", "ibase");
+		if (!ret)
+			irq_router.config = PIRQ_VIA_IBASE;
+		else
+			return -EINVAL;
+	}
+
+	ret = fdtdec_get_int_array(blob, node, "intel,pirq-link",
+				   &irq_router.link_base, 1);
+	if (ret)
+		return ret;
+
+	irq_router.irq_mask = fdtdec_get_int(blob, node,
+					     "intel,pirq-mask", PIRQ_BITMAP);
+
+	if (irq_router.config == PIRQ_VIA_IBASE) {
+		int ibase_off;
+
+		ibase_off = fdtdec_get_int(blob, node, "intel,ibase-offset", 0);
+		if (!ibase_off)
+			return -EINVAL;
+
+		/*
+		 * Here we assume that the IBASE register has already been
+		 * properly configured by U-Boot before.
+		 *
+		 * By 'valid' we mean:
+		 *   1) a valid memory space carved within system memory space
+		 *      assigned to IBASE register block.
+		 *   2) memory range decoding is enabled.
+		 * Hence we don't do any santify test here.
+		 */
+		irq_router.ibase = x86_pci_read_config32(irq_router.bdf,
+							 ibase_off);
+		irq_router.ibase &= ~0xf;
+	}
+
+	cell = fdt_getprop(blob, node, "intel,pirq-routing", &len);
+	if (!cell)
+		return -EINVAL;
+
+	if ((len % sizeof(struct pirq_routing)) == 0)
+		count = len / sizeof(struct pirq_routing);
+	else
+		return -EINVAL;
+
+	rt = malloc(sizeof(struct irq_routing_table));
+	if (!rt)
+		return -ENOMEM;
+	memset((char *)rt, 0, sizeof(struct irq_routing_table));
+
+	/* Populate the PIRQ table fields */
+	rt->signature = PIRQ_SIGNATURE;
+	rt->version = PIRQ_VERSION;
+	rt->rtr_bus = 0;
+	rt->rtr_devfn = (PCI_DEV(irq_router.bdf) << 3) |
+			PCI_FUNC(irq_router.bdf);
+	rt->rtr_vendor = PCI_VENDOR_ID_INTEL;
+	rt->rtr_device = PCI_DEVICE_ID_INTEL_ICH7_31;
+
+	slot = rt->slots;
+
+	/* Now fill in the irq_info entries in the PIRQ table */
+	for (i = 0; i < count; i++) {
+		struct pirq_routing pr;
+
+		pr.bdf = fdt_addr_to_cpu(cell[0]);
+		pr.pin = fdt_addr_to_cpu(cell[1]);
+		pr.pirq = fdt_addr_to_cpu(cell[2]);
+
+		debug("irq_info %d: b.d.f %x.%x.%x INT%c PIRQ%c\n",
+		      i, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf),
+		      PCI_FUNC(pr.bdf), 'A' + pr.pin - 1,
+		      'A' + pr.pirq);
+		fill_irq_info(&slot, &irq_entries, PCI_BUS(pr.bdf),
+			      PCI_DEV(pr.bdf), PCI_FUNC(pr.bdf),
+			      pr.pin, pr.pirq);
+		cell += sizeof(struct pirq_routing) / sizeof(u32);
+	}
+
+	rt->size = irq_entries * sizeof(struct irq_info) + 32;
+
+	pirq_routing_table = rt;
+
+	return 0;
+}
+
+void pirq_init(void)
+{
+	cpu_irq_init();
+
+	if (create_pirq_routing_table()) {
+		debug("Failed to create pirq routing table\n");
+	} else {
+		/* Route PIRQ */
+		pirq_route_irqs(pirq_routing_table->slots,
+				get_irq_slot_count(pirq_routing_table));
+	}
+}
+
+u32 write_pirq_routing_table(u32 addr)
+{
+	if (!pirq_routing_table)
+		return addr;
+
+	return copy_pirq_routing_table(addr, pirq_routing_table);
+}
diff --git a/arch/x86/cpu/qemu/Kconfig b/arch/x86/cpu/qemu/Kconfig
new file mode 100644
index 0000000..fb775d7
--- /dev/null
+++ b/arch/x86/cpu/qemu/Kconfig
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+config QEMU
+	bool
+	select TSC_CALIBRATION_BYPASS
+
+if QEMU
+
+config SYS_CAR_ADDR
+	hex
+	default 0xd0000
+
+config SYS_CAR_SIZE
+	hex
+	default 0x10000
+
+endif
diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile
new file mode 100644
index 0000000..be79723
--- /dev/null
+++ b/arch/x86/cpu/qemu/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += car.o dram.o qemu.o
+obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/cpu/qemu/car.S b/arch/x86/cpu/qemu/car.S
new file mode 100644
index 0000000..13b3aea
--- /dev/null
+++ b/arch/x86/cpu/qemu/car.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm/post.h>
+
+.globl car_init
+car_init:
+	/* Save the BIST result */
+	movl	%eax, %ebp
+
+	post_code(POST_CAR_START)
+
+	/*
+	 * Since we know we are running inside emulator,
+	 * we can do nothing here for CAR initialization.
+	 */
+
+	/* Restore the BIST result */
+	movl	%ebp, %eax
+
+	post_code(POST_CAR_CPU_CACHE)
+	jmp	car_init_ret
diff --git a/arch/x86/cpu/qemu/dram.c b/arch/x86/cpu/qemu/dram.c
new file mode 100644
index 0000000..a88d0d2
--- /dev/null
+++ b/arch/x86/cpu/qemu/dram.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/post.h>
+#include <asm/arch/qemu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	u32 ram;
+
+	outb(HIGH_RAM_ADDR, CMOS_ADDR_PORT);
+	ram = ((u32)inb(CMOS_DATA_PORT)) << 14;
+	outb(LOW_RAM_ADDR, CMOS_ADDR_PORT);
+	ram |= ((u32)inb(CMOS_DATA_PORT)) << 6;
+	ram += 16 * 1024;
+
+	gd->ram_size = ram * 1024;
+	post_code(POST_DRAM);
+
+	return 0;
+}
+
+void dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = 0;
+	gd->bd->bi_dram[0].size = gd->ram_size;
+}
+
+/*
+ * This function looks for the highest region of memory lower than 4GB which
+ * has enough space for U-Boot where U-Boot is aligned on a page boundary.
+ * It overrides the default implementation found elsewhere which simply
+ * picks the end of ram, wherever that may be. The location of the stack,
+ * the relocation address, and how far U-Boot is moved by relocation are
+ * set in the global data structure.
+ */
+ulong board_get_usable_ram_top(ulong total_size)
+{
+	return gd->ram_size;
+}
diff --git a/arch/x86/cpu/qemu/pci.c b/arch/x86/cpu/qemu/pci.c
new file mode 100644
index 0000000..1a9140b
--- /dev/null
+++ b/arch/x86/cpu/qemu/pci.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <pci_rom.h>
+#include <asm/pci.h>
+#include <asm/arch/device.h>
+#include <asm/arch/qemu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_pci_setup_hose(struct pci_controller *hose)
+{
+	hose->first_busno = 0;
+	hose->last_busno = 0;
+
+	/* PCI memory space */
+	pci_set_region(hose->regions + 0,
+		       CONFIG_PCI_MEM_BUS,
+		       CONFIG_PCI_MEM_PHYS,
+		       CONFIG_PCI_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	/* PCI IO space */
+	pci_set_region(hose->regions + 1,
+		       CONFIG_PCI_IO_BUS,
+		       CONFIG_PCI_IO_PHYS,
+		       CONFIG_PCI_IO_SIZE,
+		       PCI_REGION_IO);
+
+	pci_set_region(hose->regions + 2,
+		       CONFIG_PCI_PREF_BUS,
+		       CONFIG_PCI_PREF_PHYS,
+		       CONFIG_PCI_PREF_SIZE,
+		       PCI_REGION_PREFETCH);
+
+	pci_set_region(hose->regions + 3,
+		       0,
+		       0,
+		       gd->ram_size,
+		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+	hose->region_count = 4;
+}
+
+int board_pci_post_scan(struct pci_controller *hose)
+{
+	int ret = 0;
+	u16 device;
+	int pam, i;
+	pci_dev_t vga;
+	ulong start;
+
+	/*
+	 * i440FX and Q35 chipset have different PAM register offset, but with
+	 * the same bitfield layout. Here we determine the offset based on its
+	 * PCI device ID.
+	 */
+	device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID);
+	pam = (device == PCI_DEVICE_ID_INTEL_82441) ? I440FX_PAM : Q35_PAM;
+
+	/*
+	 * Initialize Programmable Attribute Map (PAM) Registers
+	 *
+	 * Configure legacy segments C/D/E/F to system RAM
+	 */
+	for (i = 0; i < PAM_NUM; i++)
+		x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW);
+
+	if (device == PCI_DEVICE_ID_INTEL_82441) {
+		/*
+		 * Enable legacy IDE I/O ports decode
+		 *
+		 * Note: QEMU always decode legacy IDE I/O port on PIIX chipset.
+		 * However Linux ata_piix driver does sanity check on these two
+		 * registers to see whether legacy ports decode is turned on.
+		 * This is to make Linux ata_piix driver happy.
+		 */
+		x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN);
+		x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN);
+	}
+
+	/*
+	 * QEMU emulated graphic card shows in the PCI configuration space with
+	 * PCI vendor id and device id as an artificial pair 0x1234:0x1111.
+	 * It is on PCI bus 0, function 0, but device number is not consistent
+	 * for the two x86 targets it supports. For i440FX and PIIX chipset
+	 * board, it shows as device 2, while for Q35 and ICH9 chipset board,
+	 * it shows as device 1.
+	 */
+	vga = (device == PCI_DEVICE_ID_INTEL_82441) ? I440FX_VGA : Q35_VGA;
+	start = get_timer(0);
+	ret = pci_run_vga_bios(vga, NULL, PCI_ROM_USE_NATIVE);
+	debug("BIOS ran in %lums\n", get_timer(start));
+
+	return ret;
+}
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
new file mode 100644
index 0000000..930d2b6
--- /dev/null
+++ b/arch/x86/cpu/qemu/qemu.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/irq.h>
+#include <asm/post.h>
+#include <asm/processor.h>
+
+int arch_cpu_init(void)
+{
+	int ret;
+
+	post_code(POST_CPU_INIT);
+#ifdef CONFIG_SYS_X86_TSC_TIMER
+	timer_set_base(rdtsc());
+#endif
+
+	ret = x86_cpu_init_f();
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int print_cpuinfo(void)
+{
+	post_code(POST_CPU_INFO);
+	return default_print_cpuinfo();
+}
+
+void reset_cpu(ulong addr)
+{
+	/* cold reset */
+	x86_full_reset();
+}
+
+int arch_misc_init(void)
+{
+	pirq_init();
+
+	return 0;
+}
diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index e78a271..20cc09e 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -9,6 +9,7 @@
 #include <netdev.h>
 #include <phy.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/pci.h>
 #include <asm/post.h>
 #include <asm/processor.h>
@@ -147,3 +148,33 @@
 	else
 		return 0;
 }
+
+void cpu_irq_init(void)
+{
+	struct quark_rcba *rcba;
+	u32 base;
+
+	base = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, LB_RCBA);
+	base &= ~MEM_BAR_EN;
+	rcba = (struct quark_rcba *)base;
+
+	/*
+	 * Route Quark PCI device interrupt pin to PIRQ
+	 *
+	 * Route device#23's INTA/B/C/D to PIRQA/B/C/D
+	 * Route device#20,21's INTA/B/C/D to PIRQE/F/G/H
+	 */
+	writew(PIRQC, &rcba->rmu_ir);
+	writew(PIRQA | (PIRQB << 4) | (PIRQC << 8) | (PIRQD << 12),
+	       &rcba->d23_ir);
+	writew(PIRQD, &rcba->core_ir);
+	writew(PIRQE | (PIRQF << 4) | (PIRQG << 8) | (PIRQH << 12),
+	       &rcba->d20d21_ir);
+}
+
+int arch_misc_init(void)
+{
+	pirq_init();
+
+	return 0;
+}
diff --git a/arch/x86/cpu/queensbay/Makefile b/arch/x86/cpu/queensbay/Makefile
index 4599a48..d8761fd 100644
--- a/arch/x86/cpu/queensbay/Makefile
+++ b/arch/x86/cpu/queensbay/Makefile
@@ -5,5 +5,5 @@
 #
 
 obj-y += fsp_configs.o
-obj-y += irq.o tnc.o topcliff.o
+obj-y += tnc.o topcliff.o
 obj-$(CONFIG_PCI) += tnc_pci.o
diff --git a/arch/x86/cpu/queensbay/irq.c b/arch/x86/cpu/queensbay/irq.c
deleted file mode 100644
index faf9515..0000000
--- a/arch/x86/cpu/queensbay/irq.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <errno.h>
-#include <malloc.h>
-#include <asm/io.h>
-#include <asm/pci.h>
-#include <asm/post.h>
-#include <asm/processor.h>
-#include <asm/pirq_routing.h>
-#include <asm/arch/device.h>
-#include <asm/arch/tnc.h>
-#include <asm/arch/irq.h>
-
-static struct irq_routing_table *pirq_routing_table;
-
-bool pirq_check_irq_routed(int link, u8 irq)
-{
-	u8 pirq;
-
-	pirq = x86_pci_read_config8(TNC_LPC, LINK_N2V(link));
-	pirq &= 0xf;
-
-	/* IRQ# 0/1/2/8/13 are reserved */
-	if (pirq < 3 || pirq == 8 || pirq == 13)
-		return false;
-
-	return pirq == irq ? true : false;
-}
-
-int pirq_translate_link(int link)
-{
-	return LINK_V2N(link);
-}
-
-void pirq_assign_irq(int link, u8 irq)
-{
-	/* IRQ# 0/1/2/8/13 are reserved */
-	if (irq < 3 || irq == 8 || irq == 13)
-		return;
-
-	x86_pci_write_config8(TNC_LPC, LINK_N2V(link), irq);
-}
-
-static inline void fill_irq_info(struct irq_info **slotp, int *entries, u8 bus,
-				 u8 device, u8 func, u8 pin, u8 pirq)
-{
-	struct irq_info *slot = *slotp;
-
-	slot->bus = bus;
-	slot->devfn = (device << 3) | func;
-	slot->irq[pin - 1].link = LINK_N2V(pirq);
-	slot->irq[pin - 1].bitmap = PIRQ_BITMAP;
-	(*entries)++;
-	(*slotp)++;
-}
-
-/* PCIe port downstream INTx swizzle */
-static inline u8 pin_swizzle(u8 pin, int port)
-{
-	return (pin + port) % 4;
-}
-
-__weak int board_fill_irq_info(struct irq_info *slot)
-{
-	return 0;
-}
-
-static int create_pirq_routing_table(void)
-{
-	struct irq_routing_table *rt;
-	struct irq_info *slot;
-	int irq_entries = 0;
-	pci_dev_t tcf_bdf;
-	u8 tcf_bus, bus;
-	int i;
-
-	rt = malloc(sizeof(struct irq_routing_table));
-	if (!rt)
-		return -ENOMEM;
-	memset((char *)rt, 0, sizeof(struct irq_routing_table));
-
-	/* Populate the PIRQ table fields */
-	rt->signature = PIRQ_SIGNATURE;
-	rt->version = PIRQ_VERSION;
-	rt->rtr_bus = 0;
-	rt->rtr_devfn = (TNC_LPC_DEV << 3) | TNC_LPC_FUNC;
-	rt->rtr_vendor = PCI_VENDOR_ID_INTEL;
-	rt->rtr_device = PCI_DEVICE_ID_INTEL_ICH7_31;
-
-	slot = rt->slots;
-
-	/*
-	 * Now fill in the irq_info entries in the PIRQ table
-	 *
-	 * We start from internal TunnelCreek PCI devices first, then
-	 * followed by all the 4 PCIe ports downstream devices, including
-	 * the Queensbay platform Topcliff chipset devices.
-	 */
-	fill_irq_info(&slot, &irq_entries, 0, TNC_IGD_DEV,
-		      TNC_IGD_FUNC, INTA, PIRQE);
-	fill_irq_info(&slot, &irq_entries, 0, TNC_SDVO_DEV,
-		      TNC_SDVO_FUNC, INTA, PIRQF);
-	fill_irq_info(&slot, &irq_entries, 0, TNC_HDA_DEV,
-		      TNC_HDA_FUNC, INTA, PIRQG);
-	fill_irq_info(&slot, &irq_entries, 0, TNC_PCIE0_DEV,
-		      TNC_PCIE0_FUNC, INTA, PIRQE);
-	fill_irq_info(&slot, &irq_entries, 0, TNC_PCIE1_DEV,
-		      TNC_PCIE1_FUNC, INTA, PIRQF);
-	fill_irq_info(&slot, &irq_entries, 0, TNC_PCIE2_DEV,
-		      TNC_PCIE2_FUNC, INTA, PIRQG);
-	fill_irq_info(&slot, &irq_entries, 0, TNC_PCIE3_DEV,
-		      TNC_PCIE3_FUNC, INTA, PIRQH);
-
-	/* Check which PCIe port the Topcliff chipset is connected to */
-	tcf_bdf = pci_find_device(PCI_VENDOR_ID_INTEL, 0x8800, 0);
-	tcf_bus = PCI_BUS(tcf_bdf);
-	for (i = 0; i < 4; i++) {
-		bus = x86_pci_read_config8(PCI_BDF(0, TNC_PCIE0_DEV + i, 0),
-					   PCI_SECONDARY_BUS);
-		if (bus == tcf_bus)
-			break;
-	}
-
-	/* Fill in the Topcliff chipset devices' irq info */
-	if (i < 4) {
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_PCIE_PORT_DEV,
-			      TCF_PCIE_PORT_FUNC, INTA, pin_swizzle(PIRQA, i));
-
-		tcf_bus++;
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_0,
-			      TCF_GBE_FUNC, INTA, pin_swizzle(PIRQA, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_0,
-			      TCF_GPIO_FUNC, INTA, pin_swizzle(PIRQA, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
-			      TCF_USB1_OHCI0_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
-			      TCF_USB1_OHCI1_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
-			      TCF_USB1_OHCI2_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
-			      TCF_USB1_EHCI_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
-			      TCF_USB_DEVICE_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_4,
-			      TCF_SDIO0_FUNC, INTC, pin_swizzle(PIRQC, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_4,
-			      TCF_SDIO1_FUNC, INTC, pin_swizzle(PIRQC, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_6,
-			      TCF_SATA_FUNC, INTD, pin_swizzle(PIRQD, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_8,
-			      TCF_USB2_OHCI0_FUNC, INTA, pin_swizzle(PIRQA, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_8,
-			      TCF_USB2_OHCI1_FUNC, INTA, pin_swizzle(PIRQA, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_8,
-			      TCF_USB2_OHCI2_FUNC, INTA, pin_swizzle(PIRQA, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_8,
-			      TCF_USB2_EHCI_FUNC, INTA, pin_swizzle(PIRQA, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
-			      TCF_DMA1_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
-			      TCF_UART0_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
-			      TCF_UART1_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
-			      TCF_UART2_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
-			      TCF_UART3_FUNC, INTB, pin_swizzle(PIRQB, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
-			      TCF_DMA2_FUNC, INTC, pin_swizzle(PIRQC, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
-			      TCF_SPI_FUNC, INTC, pin_swizzle(PIRQC, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
-			      TCF_I2C_FUNC, INTC, pin_swizzle(PIRQC, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
-			      TCF_CAN_FUNC, INTC, pin_swizzle(PIRQC, i));
-		fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
-			      TCF_1588_FUNC, INTC, pin_swizzle(PIRQC, i));
-	}
-
-	/* Call board-specific routine to fill in add-in card's irq info */
-	irq_entries += board_fill_irq_info(slot);
-
-	rt->size = irq_entries * sizeof(struct irq_info) + 32;
-
-	pirq_routing_table = rt;
-
-	return 0;
-}
-
-void pirq_init(void)
-{
-	struct tnc_rcba *rcba;
-	u32 base;
-
-	base = x86_pci_read_config32(TNC_LPC, LPC_RCBA);
-	base &= ~MEM_BAR_EN;
-	rcba = (struct tnc_rcba *)base;
-
-	/* Make sure all internal PCI devices are using INTA */
-	writel(INTA, &rcba->d02ip);
-	writel(INTA, &rcba->d03ip);
-	writel(INTA, &rcba->d27ip);
-	writel(INTA, &rcba->d31ip);
-	writel(INTA, &rcba->d23ip);
-	writel(INTA, &rcba->d24ip);
-	writel(INTA, &rcba->d25ip);
-	writel(INTA, &rcba->d26ip);
-
-	/*
-	 * Route TunnelCreek PCI device interrupt pin to PIRQ
-	 *
-	 * Since PCIe downstream ports received INTx are routed to PIRQ
-	 * A/B/C/D directly and not configurable, we route internal PCI
-	 * device's INTx to PIRQ E/F/G/H.
-	 */
-	writew(PIRQE, &rcba->d02ir);
-	writew(PIRQF, &rcba->d03ir);
-	writew(PIRQG, &rcba->d27ir);
-	writew(PIRQH, &rcba->d31ir);
-	writew(PIRQE, &rcba->d23ir);
-	writew(PIRQF, &rcba->d24ir);
-	writew(PIRQG, &rcba->d25ir);
-	writew(PIRQH, &rcba->d26ir);
-
-	if (create_pirq_routing_table()) {
-		debug("Failed to create pirq routing table\n");
-	} else {
-		/* Route PIRQ */
-		pirq_route_irqs(pirq_routing_table->slots,
-				get_irq_slot_count(pirq_routing_table));
-	}
-}
-
-u32 write_pirq_routing_table(u32 addr)
-{
-	return copy_pirq_routing_table(addr, pirq_routing_table);
-}
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c
index b46a7e9..873de7b 100644
--- a/arch/x86/cpu/queensbay/tnc.c
+++ b/arch/x86/cpu/queensbay/tnc.c
@@ -6,10 +6,11 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/pci.h>
 #include <asm/post.h>
 #include <asm/arch/device.h>
-#include <asm/arch/irq.h>
+#include <asm/arch/tnc.h>
 #include <asm/fsp/fsp_support.h>
 #include <asm/processor.h>
 
@@ -45,6 +46,42 @@
 	return 0;
 }
 
+void cpu_irq_init(void)
+{
+	struct tnc_rcba *rcba;
+	u32 base;
+
+	base = x86_pci_read_config32(TNC_LPC, LPC_RCBA);
+	base &= ~MEM_BAR_EN;
+	rcba = (struct tnc_rcba *)base;
+
+	/* Make sure all internal PCI devices are using INTA */
+	writel(INTA, &rcba->d02ip);
+	writel(INTA, &rcba->d03ip);
+	writel(INTA, &rcba->d27ip);
+	writel(INTA, &rcba->d31ip);
+	writel(INTA, &rcba->d23ip);
+	writel(INTA, &rcba->d24ip);
+	writel(INTA, &rcba->d25ip);
+	writel(INTA, &rcba->d26ip);
+
+	/*
+	 * Route TunnelCreek PCI device interrupt pin to PIRQ
+	 *
+	 * Since PCIe downstream ports received INTx are routed to PIRQ
+	 * A/B/C/D directly and not configurable, we route internal PCI
+	 * device's INTx to PIRQ E/F/G/H.
+	 */
+	writew(PIRQE, &rcba->d02ir);
+	writew(PIRQF, &rcba->d03ir);
+	writew(PIRQG, &rcba->d27ir);
+	writew(PIRQH, &rcba->d31ir);
+	writew(PIRQE, &rcba->d23ir);
+	writew(PIRQF, &rcba->d24ir);
+	writew(PIRQG, &rcba->d25ir);
+	writew(PIRQH, &rcba->d26ir);
+}
+
 int arch_misc_init(void)
 {
 	pirq_init();
diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile
index 431bbd8..f86514c 100644
--- a/arch/x86/dts/Makefile
+++ b/arch/x86/dts/Makefile
@@ -2,7 +2,9 @@
 	chromebox_panther.dtb \
 	crownbay.dtb \
 	galileo.dtb \
-	minnowmax.dtb
+	minnowmax.dtb \
+	qemu-x86_i440fx.dtb \
+	qemu-x86_q35.dtb
 
 targets += $(dtb-y)
 
diff --git a/arch/x86/dts/crownbay.dts b/arch/x86/dts/crownbay.dts
index fbdeade..d68efda 100644
--- a/arch/x86/dts/crownbay.dts
+++ b/arch/x86/dts/crownbay.dts
@@ -6,6 +6,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
 /include/ "skeleton.dtsi"
 /include/ "serial.dtsi"
 
@@ -135,6 +137,58 @@
 				};
 			};
 		};
+
+		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 = <0xdee0>;
+			intel,pirq-routing = <
+				/* TunnelCreek PCI devices */
+				PCI_BDF(0, 2, 0) INTA PIRQE
+				PCI_BDF(0, 3, 0) INTA PIRQF
+				PCI_BDF(0, 23, 0) INTA PIRQE
+				PCI_BDF(0, 24, 0) INTA PIRQF
+				PCI_BDF(0, 25, 0) INTA PIRQG
+				PCI_BDF(0, 26, 0) INTA PIRQH
+				PCI_BDF(0, 27, 0) INTA PIRQG
+				/*
+				 * Topcliff PCI devices
+				 *
+				 * Note on the Crown Bay board, Topcliff chipset
+				 * is connected to TunnelCreek PCIe port 0, so
+				 * its bus number is 1 for its PCIe port and 2
+				 * for its PCI devices per U-Boot currnet PCI
+				 * bus enumeration algorithm.
+				 */
+				PCI_BDF(1, 0, 0) INTA PIRQA
+				PCI_BDF(2, 0, 1) INTA PIRQA
+				PCI_BDF(2, 0, 2) INTA PIRQA
+				PCI_BDF(2, 2, 0) INTB PIRQB
+				PCI_BDF(2, 2, 1) INTB PIRQB
+				PCI_BDF(2, 2, 2) INTB PIRQB
+				PCI_BDF(2, 2, 3) INTB PIRQB
+				PCI_BDF(2, 2, 4) INTB PIRQB
+				PCI_BDF(2, 4, 0) INTC PIRQC
+				PCI_BDF(2, 4, 1) INTC PIRQC
+				PCI_BDF(2, 6, 0) INTD PIRQD
+				PCI_BDF(2, 8, 0) INTA PIRQA
+				PCI_BDF(2, 8, 1) INTA PIRQA
+				PCI_BDF(2, 8, 2) INTA PIRQA
+				PCI_BDF(2, 8, 3) INTA PIRQA
+				PCI_BDF(2, 10, 0) INTB PIRQB
+				PCI_BDF(2, 10, 1) INTB PIRQB
+				PCI_BDF(2, 10, 2) INTB PIRQB
+				PCI_BDF(2, 10, 3) INTB PIRQB
+				PCI_BDF(2, 10, 4) INTB PIRQB
+				PCI_BDF(2, 12, 0) INTC PIRQC
+				PCI_BDF(2, 12, 1) INTC PIRQC
+				PCI_BDF(2, 12, 2) INTC PIRQC
+				PCI_BDF(2, 12, 3) INTC PIRQC
+				PCI_BDF(2, 12, 4) INTC PIRQC
+			>;
+		};
 	};
 
 };
diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts
index 60dbc5f..2ba081e 100644
--- a/arch/x86/dts/galileo.dts
+++ b/arch/x86/dts/galileo.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include <dt-bindings/mrc/quark.h>
+#include <dt-bindings/interrupt-router/intel-irq.h>
 
 /include/ "skeleton.dtsi"
 
@@ -67,6 +68,27 @@
 			clock-frequency = <44236800>;
 			current-speed = <115200>;
 		};
+
+		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 = <0xdef8>;
+			intel,pirq-routing = <
+				PCI_BDF(0, 20, 0) INTA PIRQE
+				PCI_BDF(0, 20, 1) INTB PIRQF
+				PCI_BDF(0, 20, 2) INTC PIRQG
+				PCI_BDF(0, 20, 3) INTD PIRQH
+				PCI_BDF(0, 20, 4) INTA PIRQE
+				PCI_BDF(0, 20, 5) INTB PIRQF
+				PCI_BDF(0, 20, 6) INTC PIRQG
+				PCI_BDF(0, 20, 7) INTD PIRQH
+				PCI_BDF(0, 21, 0) INTA PIRQE
+				PCI_BDF(0, 21, 1) INTB PIRQF
+				PCI_BDF(0, 21, 2) INTC PIRQG
+			>;
+		};
 	};
 
 	gpioa {
diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
index 7103bc5..bd21bfb 100644
--- a/arch/x86/dts/minnowmax.dts
+++ b/arch/x86/dts/minnowmax.dts
@@ -6,6 +6,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/gpio/x86-gpio.h>
+
 /include/ "skeleton.dtsi"
 /include/ "serial.dtsi"
 
@@ -22,6 +24,27 @@
 		silent_console = <0>;
 	};
 
+	pch_pinctrl {
+		compatible = "intel,x86-pinctrl";
+		io-base = <0x4c>;
+
+		pin_usb_host_en0@0 {
+			gpio-offset = <0x80 8>;
+			pad-offset = <0x260>;
+			mode-gpio;
+			output-value = <1>;
+			direction = <PIN_OUTPUT>;
+		};
+
+		pin_usb_host_en1@0 {
+			gpio-offset = <0x80 9>;
+			pad-offset = <0x258>;
+			mode-gpio;
+			output-value = <1>;
+			direction = <PIN_OUTPUT>;
+		};
+	};
+
 	gpioa {
 		compatible = "intel,ich6-gpio";
 		u-boot,dm-pre-reloc;
diff --git a/arch/x86/dts/qemu-x86_i440fx.dts b/arch/x86/dts/qemu-x86_i440fx.dts
new file mode 100644
index 0000000..557428a
--- /dev/null
+++ b/arch/x86/dts/qemu-x86_i440fx.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+/include/ "skeleton.dtsi"
+/include/ "serial.dtsi"
+
+/ {
+	model = "QEMU x86 (I440FX)";
+	compatible = "qemu,x86";
+
+	config {
+		silent_console = <0>;
+	};
+
+	chosen {
+		stdout-path = "/serial";
+	};
+
+	pci {
+		compatible = "pci-x86";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		u-boot,dm-pre-reloc;
+		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
new file mode 100644
index 0000000..c259f2a
--- /dev/null
+++ b/arch/x86/dts/qemu-x86_q35.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/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"
+
+/ {
+	model = "QEMU x86 (Q35)";
+	compatible = "qemu,x86";
+
+	config {
+		silent_console = <0>;
+		u-boot,no-apm-finalize;
+	};
+
+	chosen {
+		stdout-path = "/serial";
+	};
+
+	pci {
+		compatible = "pci-x86";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		u-boot,dm-pre-reloc;
+		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
+			>;
+		};
+	};
+
+};
diff --git a/arch/x86/include/asm/arch-qemu/device.h b/arch/x86/include/asm/arch-qemu/device.h
new file mode 100644
index 0000000..75a435e
--- /dev/null
+++ b/arch/x86/include/asm/arch-qemu/device.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _QEMU_DEVICE_H_
+#define _QEMU_DEVICE_H_
+
+#include <pci.h>
+
+#define QEMU_I440FX	PCI_BDF(0, 0, 0)
+#define PIIX_ISA	PCI_BDF(0, 1, 0)
+#define PIIX_IDE	PCI_BDF(0, 1, 1)
+#define PIIX_USB	PCI_BDF(0, 1, 2)
+#define I440FX_VGA	PCI_BDF(0, 2, 0)
+
+#define QEMU_Q35	PCI_BDF(0, 0, 0)
+#define Q35_VGA		PCI_BDF(0, 1, 0)
+
+#endif /* _QEMU_DEVICE_H_ */
diff --git a/arch/x86/include/asm/arch-qemu/gpio.h b/arch/x86/include/asm/arch-qemu/gpio.h
new file mode 100644
index 0000000..ca8cba4
--- /dev/null
+++ b/arch/x86/include/asm/arch-qemu/gpio.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _X86_ARCH_GPIO_H_
+#define _X86_ARCH_GPIO_H_
+
+/* Where in config space is the register that points to the GPIO registers? */
+#define PCI_CFG_GPIOBASE 0x44
+
+#endif /* _X86_ARCH_GPIO_H_ */
diff --git a/arch/x86/include/asm/arch-qemu/qemu.h b/arch/x86/include/asm/arch-qemu/qemu.h
new file mode 100644
index 0000000..5cbffff
--- /dev/null
+++ b/arch/x86/include/asm/arch-qemu/qemu.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ARCH_QEMU_H_
+#define _ARCH_QEMU_H_
+
+/* Programmable Attribute Map (PAM) Registers */
+#define I440FX_PAM		0x59
+#define Q35_PAM			0x90
+#define PAM_NUM			7
+#define PAM_RW			0x33
+
+/* IDE Timing Register */
+#define IDE0_TIM		0x40
+#define IDE1_TIM		0x42
+#define IDE_DECODE_EN		0x8000
+
+/* I/O Ports */
+#define CMOS_ADDR_PORT		0x70
+#define CMOS_DATA_PORT		0x71
+
+#define LOW_RAM_ADDR		0x34
+#define HIGH_RAM_ADDR		0x35
+
+#endif /* _ARCH_QEMU_H_ */
diff --git a/arch/x86/include/asm/arch-quark/device.h b/arch/x86/include/asm/arch-quark/device.h
index 4af3ded..7882f33 100644
--- a/arch/x86/include/asm/arch-quark/device.h
+++ b/arch/x86/include/asm/arch-quark/device.h
@@ -9,20 +9,60 @@
 
 #include <pci.h>
 
-#define QUARK_HOST_BRIDGE	PCI_BDF(0, 0, 0)
-#define QUARK_MMC_SDIO		PCI_BDF(0, 20, 0)
-#define QUARK_UART0		PCI_BDF(0, 20, 1)
-#define QUARK_USB_DEVICE	PCI_BDF(0, 20, 2)
-#define QUARK_USB_EHCI		PCI_BDF(0, 20, 3)
-#define QUARK_USB_OHCI		PCI_BDF(0, 20, 4)
-#define QUARK_UART1		PCI_BDF(0, 20, 5)
-#define QUARK_EMAC0		PCI_BDF(0, 20, 6)
-#define QUARK_EMAC1		PCI_BDF(0, 20, 7)
-#define QUARK_SPI0		PCI_BDF(0, 21, 0)
-#define QUARK_SPI1		PCI_BDF(0, 21, 1)
-#define QUARK_I2C_GPIO		PCI_BDF(0, 21, 2)
-#define QUARK_PCIE0		PCI_BDF(0, 23, 0)
-#define QUARK_PCIE1		PCI_BDF(0, 23, 1)
-#define QUARK_LEGACY_BRIDGE	PCI_BDF(0, 31, 0)
+#define QUARK_HOST_BRIDGE_DEV	0
+#define QUARK_HOST_BRIDGE_FUNC	0
+
+#define QUARK_DEV_20		20
+#define QUARK_MMC_SDIO_FUNC	0
+#define QUARK_UART0_FUNC	1
+#define QUARK_USB_DEVICE_FUNC	2
+#define QUARK_USB_EHCI_FUNC	3
+#define QUARK_USB_OHCI_FUNC	4
+#define QUARK_UART1_FUNC	5
+#define QUARK_EMAC0_FUNC	6
+#define QUARK_EMAC1_FUNC	7
+
+#define QUARK_DEV_21		21
+#define QUARK_SPI0_FUNC		0
+#define QUARK_SPI1_FUNC		1
+#define QUARK_I2C_GPIO_FUNC	2
+
+#define QUARK_DEV_23		23
+#define QUARK_PCIE0_FUNC	0
+#define QUARK_PCIE1_FUNC	1
+
+#define QUARK_LGC_BRIDGE_DEV	31
+#define QUARK_LGC_BRIDGE_FUNC	0
+
+#define QUARK_HOST_BRIDGE	\
+	PCI_BDF(0, QUARK_HOST_BRIDGE_DEV, QUARK_HOST_BRIDGE_FUNC)
+#define QUARK_MMC_SDIO		\
+	PCI_BDF(0, QUARK_DEV_20, QUARK_MMC_SDIO_FUNC)
+#define QUARK_UART0		\
+	PCI_BDF(0, QUARK_DEV_20, QUARK_UART0_FUNC)
+#define QUARK_USB_DEVICE	\
+	PCI_BDF(0, QUARK_DEV_20, QUARK_USB_DEVICE_FUNC)
+#define QUARK_USB_EHCI		\
+	PCI_BDF(0, QUARK_DEV_20, QUARK_USB_EHCI_FUNC)
+#define QUARK_USB_OHCI		\
+	PCI_BDF(0, QUARK_DEV_20, QUARK_USB_OHCI_FUNC)
+#define QUARK_UART1		\
+	PCI_BDF(0, QUARK_DEV_20, QUARK_UART1_FUNC)
+#define QUARK_EMAC0		\
+	PCI_BDF(0, QUARK_DEV_20, QUARK_EMAC0_FUNC)
+#define QUARK_EMAC1		\
+	PCI_BDF(0, QUARK_DEV_20, QUARK_EMAC1_FUNC)
+#define QUARK_SPI0		\
+	PCI_BDF(0, QUARK_DEV_21, QUARK_SPI0_FUNC)
+#define QUARK_SPI1		\
+	PCI_BDF(0, QUARK_DEV_21, QUARK_SPI1_FUNC)
+#define QUARK_I2C_GPIO		\
+	PCI_BDF(0, QUARK_DEV_21, QUARK_I2C_GPIO_FUNC)
+#define QUARK_PCIE0		\
+	PCI_BDF(0, QUARK_DEV_23, QUARK_PCIE0_FUNC)
+#define QUARK_PCIE1		\
+	PCI_BDF(0, QUARK_DEV_23, QUARK_PCIE1_FUNC)
+#define QUARK_LEGACY_BRIDGE	\
+	PCI_BDF(0, QUARK_LGC_BRIDGE_DEV, QUARK_LGC_BRIDGE_FUNC)
 
 #endif /* _QUARK_DEVICE_H_ */
diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h
index 6dd02fd..c997928 100644
--- a/arch/x86/include/asm/arch-quark/quark.h
+++ b/arch/x86/include/asm/arch-quark/quark.h
@@ -76,4 +76,19 @@
 #define LB_BC			0xd8
 #define LB_RCBA			0xf0
 
+#ifndef __ASSEMBLY__
+
+/* Root Complex Register Block */
+struct quark_rcba {
+	u32	rctl;
+	u32	esd;
+	u32	rsvd1[3150];
+	u16	rmu_ir;
+	u16	d23_ir;
+	u16	core_ir;
+	u16	d20d21_ir;
+};
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* _QUARK_H_ */
diff --git a/arch/x86/include/asm/arch-queensbay/irq.h b/arch/x86/include/asm/arch-queensbay/irq.h
deleted file mode 100644
index e7f8616..0000000
--- a/arch/x86/include/asm/arch-queensbay/irq.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#ifndef _ARCH_IRQ_H_
-#define _ARCH_IRQ_H_
-
-enum pci_int_pin {
-	INTX,
-	INTA,
-	INTB,
-	INTC,
-	INTD
-};
-
-enum pirq_pin {
-	PIRQA,
-	PIRQB,
-	PIRQC,
-	PIRQD,
-	PIRQE,
-	PIRQF,
-	PIRQG,
-	PIRQH
-};
-
-/* PIRQ link number and value conversion */
-#define LINK_V2N(link)	(link - 0x60)
-#define LINK_N2V(link)	(link + 0x60)
-
-#define PIRQ_BITMAP	0xdee0
-
-struct irq_info;
-
-/**
- * board_fill_irq_info() - Board-specific irq_info fill routine
- *
- * This fills the irq_info table for any board-specific add-in cards.
- *
- * @slot:	pointer to the struct irq_info that is to be filled in
- * @return:	number of entries were written to the struct irq_info
- */
-int board_fill_irq_info(struct irq_info *slot);
-
-/**
- * pirq_init() - Initialize platform PIRQ routing
- *
- * This initializes the PIRQ routing on the platform and configures all PCI
- * devices' interrupt line register to a working IRQ number on the 8259 PIC.
- */
-void pirq_init(void);
-
-#endif /* _ARCH_IRQ_H_ */
diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
index 1099427..ed85b08 100644
--- a/arch/x86/include/asm/gpio.h
+++ b/arch/x86/include/asm/gpio.h
@@ -147,6 +147,7 @@
 	} set3;
 };
 
+int gpio_ich6_pinctrl_init(void);
 void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio);
 void ich_gpio_set_gpio_map(const struct pch_gpio_map *map);
 
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
new file mode 100644
index 0000000..4de5512
--- /dev/null
+++ b/arch/x86/include/asm/irq.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ARCH_IRQ_H_
+#define _ARCH_IRQ_H_
+
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+/**
+ * Intel interrupt router configuration mechanism
+ *
+ * There are two known ways of Intel interrupt router configuration mechanism
+ * so far. On most cases, the IRQ routing configuraiton is controlled by PCI
+ * configuraiton registers on the legacy bridge, normally PCI BDF(0, 31, 0).
+ * On some newer platforms like BayTrail and Braswell, the IRQ routing is now
+ * in the IBASE register block where IBASE is memory-mapped.
+ */
+enum pirq_config {
+	PIRQ_VIA_PCI,
+	PIRQ_VIA_IBASE
+};
+
+/**
+ * Intel interrupt router control block
+ *
+ * Its members' value will be filled in based on device tree's input.
+ *
+ * @config:	PIRQ_VIA_PCI or PIRQ_VIA_IBASE
+ * @link_base:	link value base number
+ * @irq_mask:	IRQ mask reprenting the 16 IRQs in 8259, bit N is 1 means
+ *		IRQ N is available to be routed
+ * @lb_bdf:	irq router's PCI bus/device/function number encoding
+ * @ibase:	IBASE register block base address
+ */
+struct irq_router {
+	int config;
+	u32 link_base;
+	u16 irq_mask;
+	u32 bdf;
+	u32 ibase;
+};
+
+struct pirq_routing {
+	int bdf;
+	int pin;
+	int pirq;
+};
+
+/* PIRQ link number and value conversion */
+#define LINK_V2N(link, base)	(link - base)
+#define LINK_N2V(link, base)	(link + base)
+
+#define PIRQ_BITMAP		0xdef8
+
+/**
+ * cpu_irq_init() - Initialize CPU IRQ routing
+ *
+ * This initializes some platform-specific registers related to IRQ routing,
+ * like configuring internal PCI devices to use which PCI interrupt pin,
+ * and which PCI interrupt pin is mapped to which PIRQ line. Note on some
+ * platforms, such IRQ routing might be hard-coded thus cannot configure.
+ */
+void cpu_irq_init(void);
+
+/**
+ * pirq_init() - Initialize platform PIRQ routing
+ *
+ * This initializes the PIRQ routing on the platform and configures all PCI
+ * devices' interrupt line register to a working IRQ number on the 8259 PIC.
+ */
+void pirq_init(void);
+
+#endif /* _ARCH_IRQ_H_ */
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index be103c0..d1d21ed 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -16,7 +16,6 @@
 void setup_gdt(gd_t *id, u64 *gdt_addr);
 int init_cache(void);
 int cleanup_before_linux(void);
-void panic_puts(const char *str);
 
 /* cpu/.../timer.c */
 void timer_isr(void *);
diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c
index 5f96da1..5809235 100644
--- a/arch/x86/lib/fsp/fsp_support.c
+++ b/arch/x86/lib/fsp/fsp_support.c
@@ -279,7 +279,7 @@
 			res_desc = (struct hob_res_desc *)hdr;
 			if (res_desc->type == RES_SYS_MEM) {
 				phys_start = res_desc->phys_start;
-				/* Need memory above 1MB to be collected here */
+				/* Need memory above 4GB to be collected here */
 				if (phys_start >= (phys_addr_t)FSP_HIGHMEM_BASE)
 					top += (u32)(res_desc->len);
 			}
diff --git a/board/coreboot/coreboot/Kconfig b/board/coreboot/coreboot/Kconfig
index 6a04158..3ff64f4 100644
--- a/board/coreboot/coreboot/Kconfig
+++ b/board/coreboot/coreboot/Kconfig
@@ -16,21 +16,21 @@
 
 config SYS_CONFIG_NAME
 	string "Board configuration file"
-	default "chromebook_link"
+	default "qemu-x86"
 	help
 	  This option selects the board configuration file in include/configs/
 	  directory to be used to build U-Boot for coreboot.
 
 config DEFAULT_DEVICE_TREE
 	string "Board Device Tree Source (dts) file"
-	default "chromebook_link"
+	default "qemu-x86_i440fx"
 	help
 	  This option selects the board Device Tree Source (dts) file in
 	  arch/x86/dts/ directory to be used to build U-Boot for coreboot.
 
 config SYS_CAR_ADDR
 	hex "Board specific Cache-As-RAM (CAR) address"
-	default 0x19200000
+	default 0x01920000
 	help
 	  This option specifies the board specific Cache-As-RAM (CAR) address.
 
diff --git a/board/emulation/Kconfig b/board/emulation/Kconfig
new file mode 100644
index 0000000..36809fd
--- /dev/null
+++ b/board/emulation/Kconfig
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+if VENDOR_EMULATION
+
+choice
+	prompt "Mainboard model"
+
+config TARGET_QEMU_X86
+	bool "QEMU x86"
+	help
+	  This is the QEMU emulated x86 board. U-Boot supports running
+	  as a coreboot payload as well as bare boot without coreboot.
+	  There are two types of x86 boards supported by QEMU which are
+	  supported by U-Boot. They are via QEMU '-M pc', an i440FX/PIIX
+	  chipset platform and '-M q35', a Q35/ICH9 chipset platform.
+
+endchoice
+
+source "board/emulation/qemu-x86/Kconfig"
+
+endif
diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig
new file mode 100644
index 0000000..e777ef4
--- /dev/null
+++ b/board/emulation/qemu-x86/Kconfig
@@ -0,0 +1,24 @@
+if TARGET_QEMU_X86
+
+config SYS_BOARD
+	default "qemu-x86"
+
+config SYS_VENDOR
+	default "emulation"
+
+config SYS_SOC
+	default "qemu"
+
+config SYS_CONFIG_NAME
+	default "qemu-x86"
+
+config SYS_TEXT_BASE
+	default 0xfff00000
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+	select X86_RESET_VECTOR
+	select QEMU
+	select BOARD_ROMSIZE_KB_1024
+
+endif
diff --git a/board/emulation/qemu-x86/MAINTAINERS b/board/emulation/qemu-x86/MAINTAINERS
new file mode 100644
index 0000000..ea4dd19
--- /dev/null
+++ b/board/emulation/qemu-x86/MAINTAINERS
@@ -0,0 +1,6 @@
+QEMU X86 BOARD
+M:	Bin Meng <bmeng.cn@gmail.com>
+S:	Maintained
+F:	board/emulation/qemu-x86/
+F:	include/configs/qemu-x86.h
+F:	configs/qemu-x86_defconfig
diff --git a/board/emulation/qemu-x86/Makefile b/board/emulation/qemu-x86/Makefile
new file mode 100644
index 0000000..ad2bbb9
--- /dev/null
+++ b/board/emulation/qemu-x86/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	+= qemu-x86.o start.o
diff --git a/board/emulation/qemu-x86/qemu-x86.c b/board/emulation/qemu-x86/qemu-x86.c
new file mode 100644
index 0000000..fedea81
--- /dev/null
+++ b/board/emulation/qemu-x86/qemu-x86.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <netdev.h>
+
+int board_eth_init(bd_t *bis)
+{
+	return pci_eth_init(bis);
+}
diff --git a/board/emulation/qemu-x86/start.S b/board/emulation/qemu-x86/start.S
new file mode 100644
index 0000000..a71db69
--- /dev/null
+++ b/board/emulation/qemu-x86/start.S
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+.globl early_board_init
+early_board_init:
+	jmp	early_board_init_ret
diff --git a/board/intel/crownbay/crownbay.c b/board/intel/crownbay/crownbay.c
index 31bb320..ad2d5b6 100644
--- a/board/intel/crownbay/crownbay.c
+++ b/board/intel/crownbay/crownbay.c
@@ -12,8 +12,6 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, 4)
 
-DECLARE_GLOBAL_DATA_PTR;
-
 int board_early_init_f(void)
 {
 	lpc47m_enable_serial(SERIAL_DEV, UART0_BASE, UART0_IRQ);
diff --git a/board/intel/galileo/galileo.c b/board/intel/galileo/galileo.c
index f2e7468..746ab27 100644
--- a/board/intel/galileo/galileo.c
+++ b/board/intel/galileo/galileo.c
@@ -6,8 +6,6 @@
 
 #include <common.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 int board_early_init_f(void)
 {
 	return 0;
diff --git a/board/intel/minnowmax/minnowmax.c b/board/intel/minnowmax/minnowmax.c
index fd2070a..383cae0 100644
--- a/board/intel/minnowmax/minnowmax.c
+++ b/board/intel/minnowmax/minnowmax.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <asm/gpio.h>
 #include <asm/ibmpc.h>
 #include <asm/pnp_def.h>
 #include <netdev.h>
@@ -12,7 +13,13 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, 4)
 
-DECLARE_GLOBAL_DATA_PTR;
+int arch_early_init_r(void)
+{
+	/* do the pin-muxing */
+	gpio_ich6_pinctrl_init();
+
+	return 0;
+}
 
 int board_early_init_f(void)
 {
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index 04a6d9b..ecd3e9d 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -79,7 +79,7 @@
 
 #ifdef CONFIG_ATAPI
 static void	atapi_inquiry(block_dev_desc_t *dev_desc);
-static ulong atapi_read(int device, ulong blknr, lbaint_t blkcnt,
+static ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt,
 			void *buffer);
 #endif
 
@@ -1388,13 +1388,13 @@
 #define ATAPI_READ_BLOCK_SIZE	2048	/* assuming CD part */
 #define ATAPI_READ_MAX_BLOCK	(ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)
 
-ulong atapi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
+ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer)
 {
 	ulong n = 0;
 	unsigned char ccb[12];	/* Command descriptor block */
 	ulong cnt;
 
-	debug("atapi_read dev %d start %lX, blocks " LBAF " buffer at %lX\n",
+	debug("atapi_read dev %d start " LBAF " blocks " LBAF " buffer at %lX\n",
 	      device, blknr, blkcnt, (ulong) buffer);
 
 	do {
diff --git a/configs/coreboot-x86_defconfig b/configs/coreboot-x86_defconfig
index 9bed74c..97ac1fa 100644
--- a/configs/coreboot-x86_defconfig
+++ b/configs/coreboot-x86_defconfig
@@ -1,5 +1,7 @@
 CONFIG_X86=y
+CONFIG_VENDOR_COREBOOT=y
 CONFIG_TARGET_COREBOOT=y
 CONFIG_CMD_NET=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM_PCI=y
+CONFIG_TSC_CALIBRATION_BYPASS=y
diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig
index c0a937f..a3b564e 100644
--- a/configs/galileo_defconfig
+++ b/configs/galileo_defconfig
@@ -6,3 +6,4 @@
 CONFIG_CMD_NET=y
 CONFIG_OF_CONTROL=y
 CONFIG_ETH_DESIGNWARE=y
+CONFIG_GENERATE_PIRQ_TABLE=y
diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig
index 87c99a8..744aca3 100644
--- a/configs/minnowmax_defconfig
+++ b/configs/minnowmax_defconfig
@@ -3,6 +3,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="minnowmax"
 CONFIG_TARGET_MINNOWMAX=y
 CONFIG_HAVE_INTEL_ME=y
+CONFIG_VIDEO_VESA=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
 CONFIG_SMP=y
diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig
new file mode 100644
index 0000000..901cbd7
--- /dev/null
+++ b/configs/qemu-x86_defconfig
@@ -0,0 +1,10 @@
+CONFIG_X86=y
+CONFIG_VENDOR_EMULATION=y
+CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx"
+CONFIG_TARGET_QEMU_X86=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_CMD_NET=y
+CONFIG_OF_CONTROL=y
+CONFIG_VIDEO_VESA=y
+CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
+CONFIG_FRAMEBUFFER_VESA_MODE_111=y
diff --git a/doc/README.x86 b/doc/README.x86
index ef13fb4..c19f4a0 100644
--- a/doc/README.x86
+++ b/doc/README.x86
@@ -14,12 +14,13 @@
 Status
 ------
 U-Boot supports running as a coreboot [1] payload on x86. So far only Link
-(Chromebook Pixel) has been tested, but it should work with minimal adjustments
-on other x86 boards since coreboot deals with most of the low-level details.
+(Chromebook Pixel) and QEMU [2] x86 targets have been tested, but it should
+work with minimal adjustments on other x86 boards since coreboot deals with
+most of the low-level details.
 
 U-Boot also supports booting directly from x86 reset vector without coreboot,
-aka raw support or bare support. Currently Link, Intel Crown Bay, Intel
-Minnowboard Max and Intel Galileo support running U-Boot 'bare metal'.
+aka raw support or bare support. Currently Link, QEMU x86 targets and all
+Intel boards support running U-Boot 'bare metal'.
 
 As for loading an OS, U-Boot supports directly booting a 32-bit or 64-bit
 Linux kernel as part of a FIT image. It also supports a compressed zImage.
@@ -32,15 +33,15 @@
 $ make coreboot-x86_defconfig
 $ make all
 
-Note this default configuration will build a U-Boot payload for the Link board.
+Note this default configuration will build a U-Boot payload for the QEMU board.
 To build a coreboot payload against another board, you can change the build
 configuration during the 'make menuconfig' process.
 
 x86 architecture  --->
 	...
-	(chromebook_link) Board configuration file
-	(chromebook_link) Board Device Tree Source (dts) file
-	(0x19200000) Board specific Cache-As-RAM (CAR) address
+	(qemu-x86) Board configuration file
+	(qemu-x86_i440fx) Board Device Tree Source (dts) file
+	(0x01920000) Board specific Cache-As-RAM (CAR) address
 	(0x4000) Board specific Cache-As-RAM (CAR) size
 
 Change the 'Board configuration file' and 'Board Device Tree Source (dts) file'
@@ -78,7 +79,7 @@
 * ./northbridge/intel/sandybridge/systemagent-r6.bin
 
 The 3rd one should be renamed to mrc.bin.
-As for the video ROM, you can get it here [2].
+As for the video ROM, you can get it here [3].
 Make sure all these binary blobs are put in the board directory.
 
 Now you can build U-Boot and obtain u-boot.rom:
@@ -88,8 +89,8 @@
 
 Intel Crown Bay specific instructions:
 
-U-Boot support of Intel Crown Bay board [3] relies on a binary blob called
-Firmware Support Package [4] to perform all the necessary initialization steps
+U-Boot support of Intel Crown Bay board [4] relies on a binary blob called
+Firmware Support Package [5] to perform all the necessary initialization steps
 as documented in the BIOS Writer Guide, including initialization of the CPU,
 memory controller, chipset and certain bus interfaces.
 
@@ -178,6 +179,21 @@
 $ make galileo_defconfig
 $ make all
 
+QEMU x86 target instructions:
+
+To build u-boot.rom for QEMU x86 targets, just simply run
+
+$ make qemu-x86_defconfig
+$ make all
+
+Note this default configuration will build a U-Boot for the QEMU x86 i440FX
+board. To build a U-Boot against QEMU x86 Q35 board, you can change the build
+configuration during the 'make menuconfig' process like below:
+
+Device Tree Control  --->
+	...
+	(qemu-x86_q35) Default Device Tree for DT control
+
 Test with coreboot
 ------------------
 For testing U-Boot as the coreboot payload, there are things that need be paid
@@ -207,10 +223,38 @@
 the video information correctly (it always says the resolution is 0x0). This
 works correctly for link though.
 
+Test with QEMU
+--------------
+QEMU is a fancy emulator that can enable us to test U-Boot without access to
+a real x86 board. Please make sure your QEMU version is 2.3.0 or above test
+U-Boot. To launch QEMU with u-boot.rom, call QEMU as follows:
+
+$ qemu-system-i386 -nographic -bios path/to/u-boot.rom
+
+This will instantiate an emulated x86 board with i440FX and PIIX chipset. QEMU
+also supports emulating an x86 board with Q35 and ICH9 based chipset, which is
+also supported by U-Boot. To instantiate such a machine, call QEMU with:
+
+$ qemu-system-i386 -nographic -bios path/to/u-boot.rom -M q35
+
+Note by default QEMU instantiated boards only have 128 MiB system memory. But
+it is enough to have U-Boot boot and function correctly. You can increase the
+system memory by pass '-m' parameter to QEMU if you want more memory:
+
+$ qemu-system-i386 -nographic -bios path/to/u-boot.rom -m 1024
+
+This creates a board with 1 GiB system memory. Currently U-Boot for QEMU only
+supports 3 GiB maximum system memory and reserves the last 1 GiB address space
+for PCI device memory-mapped I/O and other stuff, so the maximum value of '-m'
+would be 3072.
+
+QEMU emulates a graphic card which U-Boot supports. Removing '-nographic' will
+show QEMU's VGA console window. Note this will disable QEMU's serial output.
+If you want to check both consoles, use '-serial stdio'.
 
 CPU Microcode
 -------------
-Modern CPUs usually require a special bit stream called microcode [5] to be
+Modern CPUs usually require a special bit stream called microcode [6] to be
 loaded on the processor after power up in order to function properly. U-Boot
 has already integrated these as hex dumps in the source tree.
 
@@ -227,7 +271,6 @@
 
 Useful Commands
 ---------------
-
 In keeping with the U-Boot philosophy of providing functions to check and
 adjust internal settings, there are several x86-specific commands that may be
 useful:
@@ -314,7 +357,8 @@
 References
 ----------
 [1] http://www.coreboot.org
-[2] http://www.coreboot.org/~stepan/pci8086,0166.rom
-[3] http://www.intel.com/content/www/us/en/embedded/design-tools/evaluation-platforms/atom-e660-eg20t-development-kit.html
-[4] http://www.intel.com/fsp
-[5] http://en.wikipedia.org/wiki/Microcode
+[2] http://www.qemu.org
+[3] http://www.coreboot.org/~stepan/pci8086,0166.rom
+[4] http://www.intel.com/content/www/us/en/embedded/design-tools/evaluation-platforms/atom-e660-eg20t-development-kit.html
+[5] http://www.intel.com/fsp
+[6] http://en.wikipedia.org/wiki/Microcode
diff --git a/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt b/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt
new file mode 100644
index 0000000..45ab1af
--- /dev/null
+++ b/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt
@@ -0,0 +1,31 @@
+Intel x86 PINCTRL/GPIO controller
+
+Pin-muxing on x86 can be described with a node for the PINCTRL master
+node and a set of child nodes for each pin on the SoC.
+
+The PINCTRL master node requires the following properties:
+- compatible : "intel,x86-pinctrl"
+
+Pin nodes must be children of the pinctrl master node and can
+contain the following properties:
+- pad-offset        - (required) offset in the IOBASE for the pin to configured.
+- gpio-offset       - (required) offset in the GPIOBASE for the pin to configured and
+					also the bit shift in this register.
+- mode-gpio			- (optional) standalone property to force the pin into GPIO mode.
+- mode-func			- (optional) function number to assign to the pin. if 'mode-gpio'
+					is set, this property will be ignored.
+in case of 'mode-gpio' property set:
+- output-value		- (optional) this set the default output value of the GPIO.
+- direction         - (optional) this set the direction of the gpio.
+- pull-str          - (optional) this set the pull strength of the pin.
+- pull-assign       - (optional) this set the pull assignement (up/down) of the pin.
+
+Example:
+
+pin_usb_host_en0@0 {
+    gpio-offset = <0x80 8>;
+    pad-offset = <0x260>;
+    mode-gpio;
+    output-value = <1>;
+    direction = <PIN_OUTPUT>;
+};
diff --git a/doc/device-tree-bindings/misc/intel,irq-router.txt b/doc/device-tree-bindings/misc/intel,irq-router.txt
new file mode 100644
index 0000000..598b4b1
--- /dev/null
+++ b/doc/device-tree-bindings/misc/intel,irq-router.txt
@@ -0,0 +1,50 @@
+Intel Interrupt Router Device Binding
+=====================================
+
+The device tree node which describes the operation of the Intel Interrupt Router
+device is as follows:
+
+Required properties :
+- reg : Specifies the interrupt router's PCI configuration space address as
+    defined by the Open Firmware spec.
+- compatible = "intel,irq-router"
+- intel,pirq-config : Specifies the IRQ routing register programming mechanism.
+    Valid values are:
+      "pci": IRQ routing is controlled by PCI configuration registers
+      "ibase": IRQ routing is in the memory-mapped IBASE register block
+- intel,ibase-offset : IBASE register offset in the interrupt router's PCI
+    configuration space, required only if intel,pirq-config = "ibase".
+- intel,pirq-link : Specifies the PIRQ link information with two cells. The
+    first cell is the register offset that controls the first PIRQ link routing.
+    The second cell is the total number of PIRQ links the router supports.
+- intel,pirq-mask : Specifies the IRQ mask reprenting the 16 IRQs in 8259 PIC.
+    Bit N is 1 means IRQ N is available to be routed.
+- intel,pirq-routing : Specifies all PCI devices' IRQ routing information,
+   encoded as 3 cells a group for a device. The first cell is the device's PCI
+   bus number, device number and function number encoding with PCI_BDF() macro.
+   The second cell is the PCI interrupt pin used by this device. The last cell
+   is which PIRQ line the PCI interrupt pin is routed to.
+
+
+Example
+-------
+
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+	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 = <0xdef8>;
+		intel,pirq-routing = <
+			PCI_BDF(0, 2, 0) INTA PIRQA
+			PCI_BDF(0, 3, 0) INTA PIRQB
+			PCI_BDF(0, 8, 0) INTA PIRQC
+			PCI_BDF(0, 8, 1) INTB PIRQD
+			PCI_BDF(1, 6, 0) INTA PIRQE
+			PCI_BDF(1, 6, 1) INTB PIRQF
+			PCI_BDF(1, 6, 2) INTC PIRQG
+			PCI_BDF(1, 6, 3) INTD PIRQH
+		>;
+	};
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 7e679a0..8a108f3 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -44,21 +44,28 @@
 	uint16_t lvl;
 };
 
+#define GPIO_USESEL_OFFSET(x)	(x)
+#define GPIO_IOSEL_OFFSET(x)	(x + 4)
+#define GPIO_LVL_OFFSET(x)	(x + 8)
+
+#define IOPAD_MODE_MASK				0x7
+#define IOPAD_PULL_ASSIGN_SHIFT		7
+#define IOPAD_PULL_ASSIGN_MASK		(0x3 << IOPAD_PULL_ASSIGN_SHIFT)
+#define IOPAD_PULL_STRENGTH_SHIFT	9
+#define IOPAD_PULL_STRENGTH_MASK	(0x3 << IOPAD_PULL_STRENGTH_SHIFT)
+
 /* TODO: Move this to device tree, or platform data */
 void ich_gpio_set_gpio_map(const struct pch_gpio_map *map)
 {
 	gd->arch.gpio_map = map;
 }
 
-static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
+static int gpio_ich6_get_base(unsigned long base)
 {
-	struct ich6_bank_platdata *plat = dev_get_platdata(dev);
 	pci_dev_t pci_dev;			/* handle for 0:1f:0 */
 	u8 tmpbyte;
 	u16 tmpword;
 	u32 tmplong;
-	u16 gpiobase;
-	int offset;
 
 	/* Where should it be? */
 	pci_dev = PCI_BDF(0, 0x1f, 0);
@@ -123,9 +130,9 @@
 	 * while on the Ivybridge the bit0 is used to indicate it is an
 	 * I/O space.
 	 */
-	tmplong = x86_pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);
+	tmplong = x86_pci_read_config32(pci_dev, base);
 	if (tmplong == 0x00000000 || tmplong == 0xffffffff) {
-		debug("%s: unexpected GPIOBASE value\n", __func__);
+		debug("%s: unexpected BASE value\n", __func__);
 		return -ENODEV;
 	}
 
@@ -135,7 +142,215 @@
 	 * at the offset that we just read. Bit 0 indicates that it's
 	 * an I/O address, not a memory address, so mask that off.
 	 */
-	gpiobase = tmplong & 0xfffe;
+	return tmplong & 0xfffc;
+}
+
+static int _ich6_gpio_set_value(uint16_t base, unsigned offset, int value)
+{
+	u32 val;
+
+	val = inl(base);
+	if (value)
+		val |= (1UL << offset);
+	else
+		val &= ~(1UL << offset);
+	outl(val, base);
+
+	return 0;
+}
+
+static int _ich6_gpio_set_function(uint16_t base, unsigned offset, int func)
+{
+	u32 val;
+
+	if (func) {
+		val = inl(base);
+		val |= (1UL << offset);
+		outl(val, base);
+	} else {
+		val = inl(base);
+		val &= ~(1UL << offset);
+		outl(val, base);
+	}
+
+	return 0;
+}
+
+static int _ich6_gpio_set_direction(uint16_t base, unsigned offset, int dir)
+{
+	u32 val;
+
+	if (!dir) {
+		val = inl(base);
+		val |= (1UL << offset);
+		outl(val, base);
+	} else {
+		val = inl(base);
+		val &= ~(1UL << offset);
+		outl(val, base);
+	}
+
+	return 0;
+}
+
+static int _gpio_ich6_pinctrl_cfg_pin(s32 gpiobase, s32 iobase, int pin_node)
+{
+	u32 gpio_offset[2];
+	int pad_offset;
+	int val;
+	int ret;
+	const void *prop;
+
+	/*
+	 * GPIO node is not mandatory, so we only do the
+	 * pinmuxing if the node exist.
+	 */
+	ret = fdtdec_get_int_array(gd->fdt_blob, pin_node, "gpio-offset",
+			     gpio_offset, 2);
+	if (!ret) {
+		/* Do we want to force the GPIO mode? */
+		prop = fdt_getprop(gd->fdt_blob, pin_node, "mode-gpio",
+				      NULL);
+		if (prop)
+			_ich6_gpio_set_function(GPIO_USESEL_OFFSET
+						(gpiobase) +
+						gpio_offset[0],
+						gpio_offset[1], 1);
+
+		val =
+		    fdtdec_get_int(gd->fdt_blob, pin_node, "direction", -1);
+		if (val != -1)
+			_ich6_gpio_set_direction(GPIO_IOSEL_OFFSET
+						 (gpiobase) +
+						 gpio_offset[0],
+						 gpio_offset[1], val);
+
+		val =
+		    fdtdec_get_int(gd->fdt_blob, pin_node, "output-value", -1);
+		if (val != -1)
+			_ich6_gpio_set_value(GPIO_LVL_OFFSET(gpiobase)
+					     + gpio_offset[0],
+					     gpio_offset[1], val);
+	}
+
+	/* if iobase is present, let's configure the pad */
+	if (iobase != -1) {
+		int iobase_addr;
+
+		/*
+		 * The offset for the same pin for the IOBASE and GPIOBASE are
+		 * different, so instead of maintaining a lookup table,
+		 * the device tree should provide directly the correct
+		 * value for both mapping.
+		 */
+		pad_offset =
+		    fdtdec_get_int(gd->fdt_blob, pin_node, "pad-offset", -1);
+		if (pad_offset == -1) {
+			debug("%s: Invalid register io offset %d\n",
+			      __func__, pad_offset);
+			return -EINVAL;
+		}
+
+		/* compute the absolute pad address */
+		iobase_addr = iobase + pad_offset;
+
+		/*
+		 * Do we need to set a specific function mode?
+		 * If someone put also 'mode-gpio', this option will
+		 * be just ignored by the controller
+		 */
+		val = fdtdec_get_int(gd->fdt_blob, pin_node, "mode-func", -1);
+		if (val != -1)
+			clrsetbits_le32(iobase_addr, IOPAD_MODE_MASK, val);
+
+		/* Configure the pull-up/down if needed */
+		val = fdtdec_get_int(gd->fdt_blob, pin_node, "pull-assign", -1);
+		if (val != -1)
+			clrsetbits_le32(iobase_addr,
+					IOPAD_PULL_ASSIGN_MASK,
+					val << IOPAD_PULL_ASSIGN_SHIFT);
+
+		val =
+		    fdtdec_get_int(gd->fdt_blob, pin_node, "pull-strength", -1);
+		if (val != -1)
+			clrsetbits_le32(iobase_addr,
+					IOPAD_PULL_STRENGTH_MASK,
+					val << IOPAD_PULL_STRENGTH_SHIFT);
+
+		debug("%s: pad cfg [0x%x]: %08x\n", __func__, pad_offset,
+		      readl(iobase_addr));
+	}
+
+	return 0;
+}
+
+int gpio_ich6_pinctrl_init(void)
+{
+	int pin_node;
+	int node;
+	int ret;
+	int gpiobase;
+	int iobase_offset;
+	int iobase = -1;
+
+	/*
+	 * Get the memory/io base address to configure every pins.
+	 * IOBASE is used to configure the mode/pads
+	 * GPIOBASE is used to configure the direction and default value
+	 */
+	gpiobase = gpio_ich6_get_base(PCI_CFG_GPIOBASE);
+	if (gpiobase < 0) {
+		debug("%s: invalid GPIOBASE address (%08x)\n", __func__,
+		      gpiobase);
+		return -EINVAL;
+	}
+
+	/* This is not an error to not have a pinctrl node */
+	node =
+	    fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_INTEL_X86_PINCTRL);
+	if (node <= 0) {
+		debug("%s: no pinctrl node\n", __func__);
+		return 0;
+	}
+
+	/*
+	 * Get the IOBASE, this is not mandatory as this is not
+	 * supported by all the CPU
+	 */
+	iobase_offset = fdtdec_get_int(gd->fdt_blob, node, "io-base", -1);
+	if (iobase_offset == -1) {
+		debug("%s: io-base offset not present\n", __func__);
+	} else {
+		iobase = gpio_ich6_get_base(iobase_offset);
+		if (iobase < 0) {
+			debug("%s: invalid IOBASE address (%08x)\n", __func__,
+			      iobase);
+			return -EINVAL;
+		}
+	}
+
+	for (pin_node = fdt_first_subnode(gd->fdt_blob, node);
+	     pin_node > 0;
+	     pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) {
+		/* Configure the pin */
+		ret = _gpio_ich6_pinctrl_cfg_pin(gpiobase, iobase, pin_node);
+		if (ret != 0) {
+			debug("%s: invalid configuration for the pin %d\n",
+			      __func__, pin_node);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ich6_bank_platdata *plat = dev_get_platdata(dev);
+	u16 gpiobase;
+	int offset;
+
+	gpiobase = gpio_ich6_get_base(PCI_CFG_GPIOBASE);
 	offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
 	if (offset == -1) {
 		debug("%s: Invalid register offset %d\n", __func__, offset);
@@ -192,30 +407,24 @@
 static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
 	struct ich6_bank_priv *bank = dev_get_priv(dev);
-	u32 tmplong;
 
-	tmplong = inl(bank->io_sel);
-	tmplong |= (1UL << offset);
-	outl(bank->io_sel, tmplong);
-	return 0;
+	return _ich6_gpio_set_direction(inl(bank->io_sel), offset, 0);
 }
 
 static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
 				       int value)
 {
+	int ret;
 	struct ich6_bank_priv *bank = dev_get_priv(dev);
-	u32 tmplong;
 
-	gpio_set_value(offset, value);
+	ret = _ich6_gpio_set_direction(inl(bank->io_sel), offset, 1);
+	if (ret)
+		return ret;
 
-	tmplong = inl(bank->io_sel);
-	tmplong &= ~(1UL << offset);
-	outl(bank->io_sel, tmplong);
-	return 0;
+	return _ich6_gpio_set_value(bank->lvl, offset, value);
 }
 
 static int ich6_gpio_get_value(struct udevice *dev, unsigned offset)
-
 {
 	struct ich6_bank_priv *bank = dev_get_priv(dev);
 	u32 tmplong;
@@ -230,15 +439,7 @@
 			       int value)
 {
 	struct ich6_bank_priv *bank = dev_get_priv(dev);
-	u32 tmplong;
-
-	tmplong = inl(bank->lvl);
-	if (value)
-		tmplong |= (1UL << offset);
-	else
-		tmplong &= ~(1UL << offset);
-	outl(bank->lvl, tmplong);
-	return 0;
+	return _ich6_gpio_set_value(bank->lvl, offset, value);
 }
 
 static int ich6_gpio_get_function(struct udevice *dev, unsigned offset)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index d48d865..de87505 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -596,6 +596,7 @@
 UCLASS_DRIVER(pci) = {
 	.id		= UCLASS_PCI,
 	.name		= "pci",
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
 	.post_bind	= pci_uclass_post_bind,
 	.pre_probe	= pci_uclass_pre_probe,
 	.post_probe	= pci_uclass_post_probe,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5b6c6bc..157491c 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -186,72 +186,6 @@
 	return -1;
 }
 
-/*
- *
- */
-
-int __pci_hose_phys_to_bus(struct pci_controller *hose,
-				phys_addr_t phys_addr,
-				unsigned long flags,
-				unsigned long skip_mask,
-				pci_addr_t *ba)
-{
-	struct pci_region *res;
-	pci_addr_t bus_addr;
-	int i;
-
-	for (i = 0; i < hose->region_count; i++) {
-		res = &hose->regions[i];
-
-		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
-			continue;
-
-		if (res->flags & skip_mask)
-			continue;
-
-		bus_addr = phys_addr - res->phys_start + res->bus_start;
-
-		if (bus_addr >= res->bus_start &&
-			bus_addr < res->bus_start + res->size) {
-			*ba = bus_addr;
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
-				    phys_addr_t phys_addr,
-				    unsigned long flags)
-{
-	pci_addr_t bus_addr = 0;
-	int ret;
-
-	if (!hose) {
-		puts("pci_hose_phys_to_bus: invalid hose\n");
-		return bus_addr;
-	}
-
-	/*
-	 * if PCI_REGION_MEM is set we do a two pass search with preference
-	 * on matches that don't have PCI_REGION_SYS_MEMORY set
-	 */
-	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
-		ret = __pci_hose_phys_to_bus(hose, phys_addr,
-				flags, PCI_REGION_SYS_MEMORY, &bus_addr);
-		if (!ret)
-			return bus_addr;
-	}
-
-	ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
-
-	if (ret)
-		puts("pci_hose_phys_to_bus: invalid physical address\n");
-
-	return bus_addr;
-}
-
 int pci_hose_config_device(struct pci_controller *hose,
 			   pci_dev_t dev,
 			   unsigned long io,
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index e8da977..7c10983 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -14,15 +14,12 @@
 #include <errno.h>
 #include <pci.h>
 
-#undef DEBUG
 #ifdef DEBUG
 #define DEBUGF(x...) printf(x)
 #else
 #define DEBUGF(x...)
 #endif /* DEBUG */
 
-#define	PCIAUTO_IDE_MODE_MASK		0x05
-
 /* the user can define CONFIG_SYS_PCI_CACHE_LINE_SIZE to avoid problems */
 #ifndef CONFIG_SYS_PCI_CACHE_LINE_SIZE
 #define CONFIG_SYS_PCI_CACHE_LINE_SIZE	8
@@ -425,7 +422,6 @@
 {
 	unsigned int sub_bus = PCI_BUS(dev);
 	unsigned short class;
-	unsigned char prg_iface;
 	int n;
 
 	pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
@@ -461,17 +457,6 @@
 #endif
 		break;
 
-	case PCI_CLASS_STORAGE_IDE:
-		pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prg_iface);
-		if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
-			DEBUGF("PCI Autoconfig: Skipping legacy mode IDE controller\n");
-			return sub_bus;
-		}
-
-		pciauto_setup_device(hose, dev, 6, hose->pci_mem,
-			hose->pci_prefetch, hose->pci_io);
-		break;
-
 	case PCI_CLASS_BRIDGE_CARDBUS:
 		/*
 		 * just do a minimal setup of the bridge,
diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c
index 24c66bb..b9ff23f 100644
--- a/drivers/pci/pci_common.c
+++ b/drivers/pci/pci_common.c
@@ -182,10 +182,10 @@
 }
 
 int __pci_hose_bus_to_phys(struct pci_controller *hose,
-				pci_addr_t bus_addr,
-				unsigned long flags,
-				unsigned long skip_mask,
-				phys_addr_t *pa)
+			   pci_addr_t bus_addr,
+			   unsigned long flags,
+			   unsigned long skip_mask,
+			   phys_addr_t *pa)
 {
 	struct pci_region *res;
 	int i;
@@ -240,6 +240,68 @@
 	return phys_addr;
 }
 
+int __pci_hose_phys_to_bus(struct pci_controller *hose,
+			   phys_addr_t phys_addr,
+			   unsigned long flags,
+			   unsigned long skip_mask,
+			   pci_addr_t *ba)
+{
+	struct pci_region *res;
+	pci_addr_t bus_addr;
+	int i;
+
+	for (i = 0; i < hose->region_count; i++) {
+		res = &hose->regions[i];
+
+		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+			continue;
+
+		if (res->flags & skip_mask)
+			continue;
+
+		bus_addr = phys_addr - res->phys_start + res->bus_start;
+
+		if (bus_addr >= res->bus_start &&
+		    bus_addr < res->bus_start + res->size) {
+			*ba = bus_addr;
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+pci_addr_t pci_hose_phys_to_bus(struct pci_controller *hose,
+				phys_addr_t phys_addr,
+				unsigned long flags)
+{
+	pci_addr_t bus_addr = 0;
+	int ret;
+
+	if (!hose) {
+		puts("pci_hose_phys_to_bus: invalid hose\n");
+		return bus_addr;
+	}
+
+	/*
+	 * if PCI_REGION_MEM is set we do a two pass search with preference
+	 * on matches that don't have PCI_REGION_SYS_MEMORY set
+	 */
+	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+		ret = __pci_hose_phys_to_bus(hose, phys_addr,
+				flags, PCI_REGION_SYS_MEMORY, &bus_addr);
+		if (!ret)
+			return bus_addr;
+	}
+
+	ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
+
+	if (ret)
+		puts("pci_hose_phys_to_bus: invalid physical address\n");
+
+	return bus_addr;
+}
+
 pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
 {
 	struct pci_device_id ids[2] = { {}, {0, 0} };
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2544301..9ae23e8 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1,6 +1,5 @@
 config VIDEO_VESA
 	bool "Enable VESA video driver support"
-	depends on X86
 	default n
 	help
 	  Turn on this option to enable a very simple driver which uses vesa
@@ -8,6 +7,144 @@
 	  by U-Boot. This can in principle be used with any platform that
 	  supports PCI and video cards that support VESA BIOS Extension (VBE).
 
+config FRAMEBUFFER_SET_VESA_MODE
+	bool "Set framebuffer graphics resolution"
+	depends on VIDEO_VESA
+	help
+	  Set VESA/native framebuffer mode (needed for bootsplash and graphical
+	  framebuffer console)
+
+choice
+	prompt "framebuffer graphics resolution"
+	default FRAMEBUFFER_VESA_MODE_117
+	depends on FRAMEBUFFER_SET_VESA_MODE
+	help
+	  This option sets the resolution used for the U-Boot framebuffer (and
+	  bootsplash screen).
+
+config FRAMEBUFFER_VESA_MODE_100
+	bool "640x400 256-color"
+
+config FRAMEBUFFER_VESA_MODE_101
+	bool "640x480 256-color"
+
+config FRAMEBUFFER_VESA_MODE_102
+	bool "800x600 16-color"
+
+config FRAMEBUFFER_VESA_MODE_103
+	bool "800x600 256-color"
+
+config FRAMEBUFFER_VESA_MODE_104
+	bool "1024x768 16-color"
+
+config FRAMEBUFFER_VESA_MODE_105
+	bool "1024x7686 256-color"
+
+config FRAMEBUFFER_VESA_MODE_106
+	bool "1280x1024 16-color"
+
+config FRAMEBUFFER_VESA_MODE_107
+	bool "1280x1024 256-color"
+
+config FRAMEBUFFER_VESA_MODE_108
+	bool "80x60 text"
+
+config FRAMEBUFFER_VESA_MODE_109
+	bool "132x25 text"
+
+config FRAMEBUFFER_VESA_MODE_10A
+	bool "132x43 text"
+
+config FRAMEBUFFER_VESA_MODE_10B
+	bool "132x50 text"
+
+config FRAMEBUFFER_VESA_MODE_10C
+	bool "132x60 text"
+
+config FRAMEBUFFER_VESA_MODE_10D
+	bool "320x200 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_10E
+	bool "320x200 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_10F
+	bool "320x200 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_110
+	bool "640x480 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_111
+	bool "640x480 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_112
+	bool "640x480 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_113
+	bool "800x600 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_114
+	bool "800x600 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_115
+	bool "800x600 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_116
+	bool "1024x768 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_117
+	bool "1024x768 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_118
+	bool "1024x768 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_119
+	bool "1280x1024 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_11A
+	bool "1280x1024 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_11B
+	bool "1280x1024 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_USER
+	bool "Manually select VESA mode"
+
+endchoice
+
+# Map the config names to an integer (KB).
+config FRAMEBUFFER_VESA_MODE
+	prompt "VESA mode" if FRAMEBUFFER_VESA_MODE_USER
+	hex
+	default 0x100 if FRAMEBUFFER_VESA_MODE_100
+	default 0x101 if FRAMEBUFFER_VESA_MODE_101
+	default 0x102 if FRAMEBUFFER_VESA_MODE_102
+	default 0x103 if FRAMEBUFFER_VESA_MODE_103
+	default 0x104 if FRAMEBUFFER_VESA_MODE_104
+	default 0x105 if FRAMEBUFFER_VESA_MODE_105
+	default 0x106 if FRAMEBUFFER_VESA_MODE_106
+	default 0x107 if FRAMEBUFFER_VESA_MODE_107
+	default 0x108 if FRAMEBUFFER_VESA_MODE_108
+	default 0x109 if FRAMEBUFFER_VESA_MODE_109
+	default 0x10A if FRAMEBUFFER_VESA_MODE_10A
+	default 0x10B if FRAMEBUFFER_VESA_MODE_10B
+	default 0x10C if FRAMEBUFFER_VESA_MODE_10C
+	default 0x10D if FRAMEBUFFER_VESA_MODE_10D
+	default 0x10E if FRAMEBUFFER_VESA_MODE_10E
+	default 0x10F if FRAMEBUFFER_VESA_MODE_10F
+	default 0x110 if FRAMEBUFFER_VESA_MODE_110
+	default 0x111 if FRAMEBUFFER_VESA_MODE_111
+	default 0x112 if FRAMEBUFFER_VESA_MODE_112
+	default 0x113 if FRAMEBUFFER_VESA_MODE_113
+	default 0x114 if FRAMEBUFFER_VESA_MODE_114
+	default 0x115 if FRAMEBUFFER_VESA_MODE_115
+	default 0x116 if FRAMEBUFFER_VESA_MODE_116
+	default 0x117 if FRAMEBUFFER_VESA_MODE_117
+	default 0x118 if FRAMEBUFFER_VESA_MODE_118
+	default 0x119 if FRAMEBUFFER_VESA_MODE_119
+	default 0x11A if FRAMEBUFFER_VESA_MODE_11A
+	default 0x11B if FRAMEBUFFER_VESA_MODE_11B
+	default 0x117 if FRAMEBUFFER_VESA_MODE_USER
+
 config VIDEO_LCD_SSD2828
 	bool "SSD2828 bridge chip"
 	default n
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 519bb0b..de91e57 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -42,7 +42,7 @@
  * Note: With driver model, the label is allocated so there is no need for
  * the caller to preserve it.
  *
- * @param gp	GPIO number
+ * @param gpio	GPIO number
  * @param label	User label for this GPIO
  * @return 0 if ok, -1 on error
  */
@@ -127,7 +127,7 @@
 };
 
 /**
- * dm_gpio_is_valid() - Check if a GPIO is gpio_is_valie
+ * dm_gpio_is_valid() - Check if a GPIO is valid
  *
  * @desc:	GPIO description containing device, offset and flags,
  *		previously returned by gpio_request_by_name()
@@ -167,7 +167,7 @@
  *
  * @dev:	Device to check
  * @offset:	Offset of device GPIO to check
- * @namep:	If non-NULL, this is set to the nane given when the GPIO
+ * @namep:	If non-NULL, this is set to the name given when the GPIO
  *		was requested, or -1 if it has not been requested
  * @return  -ENODATA if the driver returned an unknown function,
  * -ENODEV if the device is not active, -EINVAL if the offset is invalid.
@@ -186,7 +186,7 @@
  *
  * @dev:	Device to check
  * @offset:	Offset of device GPIO to check
- * @namep:	If non-NULL, this is set to the nane given when the GPIO
+ * @namep:	If non-NULL, this is set to the name given when the GPIO
  *		was requested, or -1 if it has not been requested
  * @return  -ENODATA if the driver returned an unknown function,
  * -ENODEV if the device is not active, -EINVAL if the offset is invalid.
@@ -219,7 +219,7 @@
  * Also it would be useful to standardise additional functions like
  * pullup, slew rate and drive strength.
  *
- * gpio_request)( and gpio_free() are optional - if NULL then they will
+ * gpio_request() and gpio_free() are optional - if NULL then they will
  * not be called.
  *
  * Note that @offset is the offset from the base GPIO of the device. So
@@ -271,7 +271,7 @@
 	 *
 	 * @dev:	GPIO device
 	 * @desc:	Place to put GPIO description
-	 * @args:	Arguments provided in descripion
+	 * @args:	Arguments provided in description
 	 * @return 0 if OK, -ve on error
 	 */
 	int (*xlate)(struct udevice *dev, struct gpio_desc *desc,
@@ -398,7 +398,7 @@
 /**
  * gpio_request_list_by_name() - Request a list of GPIOs
  *
- * Reads all the GPIOs from a list and requetss them. See
+ * Reads all the GPIOs from a list and requests them. See
  * gpio_request_by_name() for additional details. Lists should not be
  * misused to hold unrelated or optional GPIOs. They should only be used
  * for things like parallel data lines. A zero phandle terminates the list
@@ -533,7 +533,7 @@
 /**
  * gpio_get_number() - Get the global GPIO number of a GPIO
  *
- * This should only be used for debugging or interest. It returns the nummber
+ * This should only be used for debugging or interest. It returns the number
  * that should be used for gpio_get_value() etc. to access this GPIO.
  *
  * @desc:	GPIO description containing device, offset and flags,
diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h
index 4fef433..0e1f046 100644
--- a/include/configs/crownbay.h
+++ b/include/configs/crownbay.h
@@ -17,8 +17,6 @@
 #define CONFIG_BOARD_EARLY_INIT_F
 #define CONFIG_ARCH_MISC_INIT
 
-#define CONFIG_NR_DRAM_BANKS		1
-
 #define CONFIG_X86_SERIAL
 #define CONFIG_SMSC_LPC47M
 
diff --git a/include/configs/galileo.h b/include/configs/galileo.h
index f780b8f..fd89bf3 100644
--- a/include/configs/galileo.h
+++ b/include/configs/galileo.h
@@ -15,8 +15,7 @@
 
 #define CONFIG_SYS_MONITOR_LEN		(1 << 20)
 #define CONFIG_BOARD_EARLY_INIT_F
-
-#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_ARCH_MISC_INIT
 
 #define CONFIG_X86_SERIAL
 
diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h
index 2a1915d..547765d 100644
--- a/include/configs/minnowmax.h
+++ b/include/configs/minnowmax.h
@@ -15,8 +15,7 @@
 
 #define CONFIG_SYS_MONITOR_LEN		(1 << 20)
 #define CONFIG_BOARD_EARLY_INIT_F
-
-#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_ARCH_EARLY_INIT_R
 
 #define CONFIG_X86_SERIAL
 #define CONFIG_SMSC_LPC47M
@@ -56,9 +55,6 @@
 #define CONFIG_X86_OPTION_ROM_FILE		vga.bin
 #define CONFIG_X86_OPTION_ROM_ADDR		0xfff90000
 
-#ifndef CONFIG_SYS_COREBOOT
-#define CONFIG_VIDEO_VESA
-#endif
 #define VIDEO_IO_OFFSET				0
 #define CONFIG_X86EMU_RAW_IO
 #define CONFIG_VGA_AS_SINGLE_DEVICE
diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h
new file mode 100644
index 0000000..78c296f
--- /dev/null
+++ b/include/configs/qemu-x86.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/x86-common.h>
+
+#define CONFIG_SYS_MONITOR_LEN		(1 << 20)
+#define CONFIG_ARCH_MISC_INIT
+
+#define CONFIG_X86_SERIAL
+
+#define CONFIG_PCI_MEM_BUS		0xc0000000
+#define CONFIG_PCI_MEM_PHYS		CONFIG_PCI_MEM_BUS
+#define CONFIG_PCI_MEM_SIZE		0x10000000
+
+#define CONFIG_PCI_PREF_BUS		0xd0000000
+#define CONFIG_PCI_PREF_PHYS		CONFIG_PCI_PREF_BUS
+#define CONFIG_PCI_PREF_SIZE		0x10000000
+
+#define CONFIG_PCI_IO_BUS		0x2000
+#define CONFIG_PCI_IO_PHYS		CONFIG_PCI_IO_BUS
+#define CONFIG_PCI_IO_SIZE		0xe000
+
+#define CONFIG_PCI_CONFIG_HOST_BRIDGE
+#define CONFIG_PCI_PNP
+#define CONFIG_E1000
+
+#define CONFIG_STD_DEVICES_SETTINGS	"stdin=serial,vga\0" \
+					"stdout=serial,vga\0" \
+					"stderr=serial,vga\0"
+
+/*
+ * ATA/SATA support for QEMU x86 targets
+ *   - Only legacy IDE controller is supported for QEMU '-M pc' target
+ *   - AHCI controller is supported for QEMU '-M q35' target
+ *
+ * Default configuraion is to support the QEMU default x86 target
+ * Undefine CONFIG_CMD_IDE to support q35 target
+ */
+#define CONFIG_CMD_IDE
+#ifdef CONFIG_CMD_IDE
+#define CONFIG_SYS_IDE_MAXBUS		2
+#define CONFIG_SYS_IDE_MAXDEVICE	4
+#define CONFIG_SYS_ATA_BASE_ADDR	0
+#define CONFIG_SYS_ATA_DATA_OFFSET	0
+#define CONFIG_SYS_ATA_REG_OFFSET	0
+#define CONFIG_SYS_ATA_ALT_OFFSET	0
+#define CONFIG_SYS_ATA_IDE0_OFFSET	0x1f0
+#define CONFIG_SYS_ATA_IDE1_OFFSET	0x170
+#define CONFIG_ATAPI
+
+#undef CONFIG_SCSI_AHCI
+#undef CONFIG_CMD_SCSI
+#else
+#define CONFIG_SCSI_DEV_LIST		\
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_AHCI}
+#endif
+
+/* GPIO is not supported */
+#undef CONFIG_INTEL_ICH6_GPIO
+#undef CONFIG_CMD_GPIO
+
+/* SPI is not supported */
+#undef CONFIG_ICH_SPI
+#undef CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_IS_NOWHERE
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h
index b6a76fe..e0e7fca 100644
--- a/include/configs/x86-chromebook.h
+++ b/include/configs/x86-chromebook.h
@@ -14,7 +14,6 @@
 #define CONFIG_BOARD_EARLY_INIT_F
 #define CONFIG_MISC_INIT_R
 
-#define CONFIG_NR_DRAM_BANKS			8
 #define CONFIG_X86_MRC_ADDR			0xfffa0000
 #define CONFIG_CACHE_MRC_SIZE_KB		512
 
diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h
index bf4758e..1917d87 100644
--- a/include/configs/x86-common.h
+++ b/include/configs/x86-common.h
@@ -21,6 +21,7 @@
 #define CONFIG_DISPLAY_BOARDINFO_LATE
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_LAST_STAGE_INIT
+#define CONFIG_NR_DRAM_BANKS		8
 
 #define CONFIG_LMB
 #define CONFIG_OF_LIBFDT
@@ -36,6 +37,7 @@
 #define CONFIG_SCSI_AHCI
 #ifdef CONFIG_SCSI_AHCI
 #define CONFIG_LIBATA
+#define CONFIG_LBA48
 #define CONFIG_SYS_64BIT_LBA
 
 #define CONFIG_SYS_SCSI_MAX_SCSI_ID	2
@@ -75,10 +77,6 @@
 #define CONFIG_SYS_HUSH_PARSER
 
 #define CONFIG_SUPPORT_VFAT
-/************************************************************
- * ATAPI support (experimental)
- ************************************************************/
-#define CONFIG_ATAPI
 
 /************************************************************
  * DISK Partition support
@@ -246,6 +244,7 @@
 
 #define CONFIG_EXTRA_ENV_SETTINGS			\
 	CONFIG_STD_DEVICES_SETTINGS			\
+	"pciconfighost=1\0"				\
 	"netdev=eth0\0"					\
 	"consoledev=ttyS0\0"				\
 	"othbootargs=acpi=off\0"			\
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 4d737f4..c7310d7 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -39,20 +39,18 @@
 	UCLASS_PCH,		/* x86 platform controller hub */
 	UCLASS_PCI,		/* PCI bus */
 	UCLASS_PCI_GENERIC,	/* Generic PCI bus device */
+	UCLASS_PMIC,		/* PMIC I/O device */
+	UCLASS_REGULATOR,	/* Regulator device */
 	UCLASS_RTC,		/* Real time clock device */
 	UCLASS_SERIAL,		/* Serial UART */
 	UCLASS_SPI,		/* SPI bus */
-	UCLASS_SPI_GENERIC,	/* Generic SPI flash target */
 	UCLASS_SPI_FLASH,	/* SPI flash */
+	UCLASS_SPI_GENERIC,	/* Generic SPI flash target */
 	UCLASS_THERMAL,		/* Thermal sensor */
 	UCLASS_USB,		/* USB bus */
 	UCLASS_USB_DEV_GENERIC,	/* USB generic device */
 	UCLASS_USB_HUB,		/* USB hub */
 
-	/* Power Management */
-	UCLASS_PMIC,		/* PMIC I/O device */
-	UCLASS_REGULATOR,	/* REGULATOR device */
-
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
 };
diff --git a/include/dt-bindings/gpio/x86-gpio.h b/include/dt-bindings/gpio/x86-gpio.h
new file mode 100644
index 0000000..7f1de30
--- /dev/null
+++ b/include/dt-bindings/gpio/x86-gpio.h
@@ -0,0 +1,31 @@
+/*
+ * This header provides constants for binding intel,x86-pinctrl.
+ */
+
+#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H
+#define _DT_BINDINGS_GPIO_X86_GPIO_H
+
+#include <dt-bindings/gpio/gpio.h>
+
+#define GPIO_MODE_NATIVE	0
+#define GPIO_MODE_GPIO		1
+
+#define GPIO_MODE_FUNC0	0
+#define GPIO_MODE_FUNC1	1
+#define GPIO_MODE_FUNC2	2
+#define GPIO_MODE_FUNC3	3
+#define GPIO_MODE_FUNC4	4
+#define GPIO_MODE_FUNC5	5
+#define GPIO_MODE_FUNC6	6
+
+#define PIN_INPUT	0
+#define PIN_OUTPUT	1
+
+#define PIN_INPUT_NOPULL	0
+#define PIN_INPUT_PULLUP	1
+#define PIN_INPUT_PULLDOWN	2
+
+#define PULL_STR_2K		0
+#define PULL_STR_20K	2
+
+#endif
diff --git a/include/dt-bindings/interrupt-router/intel-irq.h b/include/dt-bindings/interrupt-router/intel-irq.h
new file mode 100644
index 0000000..5092f33
--- /dev/null
+++ b/include/dt-bindings/interrupt-router/intel-irq.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_INTEL_IRQ_H_
+#define _DT_BINDINGS_INTEL_IRQ_H_
+
+/* PCI interrupt pin */
+#define INTA			1
+#define INTB			2
+#define INTC			3
+#define INTD			4
+
+/* PIRQs */
+#define PIRQA			0
+#define PIRQB			1
+#define PIRQC			2
+#define PIRQD			3
+#define PIRQE			4
+#define PIRQF			5
+#define PIRQG			6
+#define PIRQH			7
+
+/* PCI bdf encoding */
+#ifndef PCI_BDF
+#define PCI_BDF(b, d, f)	((b) << 16 | (d) << 11 | (f) << 8)
+#endif
+
+#endif /* _DT_BINDINGS_INTEL_IRQ_H_ */
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 6bf5f61..4fb8a2a 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -176,8 +176,10 @@
 	COMPAT_AMS_AS3722,		/* AMS AS3722 PMIC */
 	COMPAT_INTEL_ICH_SPI,		/* Intel ICH7/9 SPI controller */
 	COMPAT_INTEL_QRK_MRC,		/* Intel Quark MRC */
+	COMPAT_INTEL_X86_PINCTRL,	/* Intel ICH7/9 pin control */
 	COMPAT_SOCIONEXT_XHCI,		/* Socionext UniPhier xHCI */
 	COMPAT_INTEL_PCH,		/* Intel PCH */
+	COMPAT_INTEL_IRQ_ROUTER,	/* Intel Interrupt Router */
 
 	COMPAT_COUNT,
 };
diff --git a/include/os.h b/include/os.h
index ffbdce8..954a48c 100644
--- a/include/os.h
+++ b/include/os.h
@@ -112,6 +112,14 @@
 void os_tty_raw(int fd, bool allow_sigs);
 
 /**
+ * Restore the tty to its original mode
+ *
+ * Call this to restore the original terminal mode, after it has been changed
+ * by os_tty_raw(). This is an internal function.
+ */
+void os_fd_restore(void);
+
+/**
  * Acquires some memory from the underlying os.
  *
  * \param length	Number of bytes to be allocated
diff --git a/include/pci_ids.h b/include/pci_ids.h
index 2e66851..5771e12 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -2838,6 +2838,7 @@
 #define PCI_DEVICE_ID_INTEL_ICH9_6	0x2930
 #define PCI_DEVICE_ID_INTEL_ICH9_7	0x2916
 #define PCI_DEVICE_ID_INTEL_ICH9_8	0x2918
+#define PCI_DEVICE_ID_INTEL_ICH9_AHCI	0x2922
 #define PCI_DEVICE_ID_INTEL_I7_MCR	0x2c18
 #define PCI_DEVICE_ID_INTEL_I7_MC_TAD	0x2c19
 #define PCI_DEVICE_ID_INTEL_I7_MC_RAS	0x2c1a
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index b586da2..46dfcb6 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -75,8 +75,10 @@
 	COMPAT(AMS_AS3722, "ams,as3722"),
 	COMPAT(INTEL_ICH_SPI, "intel,ich-spi"),
 	COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
+	COMPAT(INTEL_X86_PINCTRL, "intel,x86-pinctrl"),
 	COMPAT(SOCIONEXT_XHCI, "socionext,uniphier-xhci"),
 	COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"),
+	COMPAT(COMPAT_INTEL_IRQ_ROUTER, "intel,irq-router"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
diff --git a/test/dm/pci.c b/test/dm/pci.c
index 2f3ae79..3ab4ba8 100644
--- a/test/dm/pci.c
+++ b/test/dm/pci.c
@@ -21,6 +21,17 @@
 }
 DM_TEST(dm_test_pci_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
+/* Test that sandbox PCI bus numbering works correctly */
+static int dm_test_pci_busnum(struct unit_test_state *uts)
+{
+	struct udevice *bus;
+
+	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus));
+
+	return 0;
+}
+DM_TEST(dm_test_pci_busnum, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
 /* Test that we can use the swapcase device correctly */
 static int dm_test_pci_swapcase(struct unit_test_state *uts)
 {
diff --git a/tools/ifdtool.c b/tools/ifdtool.c
index 590ccc9..1d61df1 100644
--- a/tools/ifdtool.c
+++ b/tools/ifdtool.c
@@ -462,7 +462,7 @@
 		if (ret)
 			return ret;
 		dump_region(i, frba);
-		if (region.size == 0)
+		if (region.size <= 0)
 			continue;
 		region_fd = open(region_filename(i),
 				 O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR |