Baseline retrofit of older pcie and gem5-specific support

Signed-off-by: Christopher Daniel Emmons <chris.emmons@arm.com>
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index f9a5ca2..502d438 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -244,8 +244,10 @@
 MACHINE  :=
 endif
 ifeq ($(CONFIG_ARCH_MULTIPLATFORM),y)
+ifneq ($(CONFIG_ARCH_VEXPRESS_GEM5),y)
 MACHINE  :=
 endif
+endif
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y))
@@ -258,6 +260,15 @@
 endif
 endif
 
+ifeq ($(CONFIG_ARCH_VEXPRESS_GEM5),y)
+ifeq ($(KBUILD_SRC),)
+KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs))
+else
+KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs))
+endif
+endif
+
+
 export	TEXT_OFFSET GZFLAGS MMUEXT
 
 # Do we have FASTFPE?
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index d09b00a..e29f75d 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -12,8 +12,10 @@
 #
 
 ifneq ($(MACHINE),)
+ifneq ($(CONFIG_ARCH_VEXPRESS_GEM5),y)
 include $(srctree)/$(MACHINE)/Makefile.boot
 endif
+endif
 include $(srctree)/arch/arm/boot/dts/Makefile
 
 # Note: the following conditions must always be true:
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 563dab9..41009a6 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -315,6 +315,7 @@
 dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
 	vexpress-v2p-ca9.dtb \
 	vexpress-v2p-ca15-tc1.dtb \
+        vexpress-v2p-ca15-tc1-gem5.dtb \
 	vexpress-v2p-ca15_a7.dtb \
 	rtsm_ve-cortex_a9x2.dtb \
 	rtsm_ve-cortex_a9x4.dtb \
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1-gem5.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1-gem5.dtsi
new file mode 100644
index 0000000..b3c5abe
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1-gem5.dtsi
@@ -0,0 +1,373 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * Motherboard Express uATX
+ * V2M-P1
+ *
+ * HBI-0190D
+ *
+ * RS1 memory map ("ARM Cortex-A Series memory map" in the board's
+ * Technical Reference Manual)
+ *
+ * WARNING! The hardware described in this file is independent from the
+ * original variant (vexpress-v2m.dtsi), but there is a strong
+ * correspondence between the two configurations.
+ *
+ * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT
+ * CHANGES TO vexpress-v2m.dtsi!
+ */
+
+	motherboard {
+		model = "V2M-P1";
+		arm,hbi = <0x190>;
+		arm,vexpress,site = <0>;
+		arm,v2m-memory-map = "rs1";
+		compatible = "arm,vexpress,v2m-p1", "simple-bus";
+		#address-cells = <2>; /* SMB chipselect number and offset */
+		#size-cells = <1>;
+		#interrupt-cells = <1>;
+		ranges;
+
+		/*
+		 * Note: The pcie is probably not perfect.
+		 * It was created to support IDE for gem5.
+		 */
+		pci: gem5_pcie@0x30000000 {
+		compatible = "arm,gem5_pcie","pci";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0x30000000 0x1000000>; /* Configuration Space */
+		virtual-reg = <0xf0000000>; /* Virtual address - cfg space*/
+		bus-range = <0 0>;
+		/* currently only 3 ranges accepted: MEM, MEMP & IO */
+		ranges = <0x42000000 0 0x41000000 0 0x41000000  0 0x01000000
+			/* ^- Prefetchable-Memory Space */
+			0x02000000 0 0x40000000 0 0x40000000  0 0x01000000
+			/* ^-Non-Prefetchable Mem Space */
+			0x01000000 0 0x2f000000 0 0x2f000000 0 0x00010000>;
+			/* ^-IO Space */
+		interrupt-parent = <&gic>;
+		interrupts = <17>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &gic 0 49 4
+			0000 0 0 2 &gic 0 50 4
+			0000 0 0 3 &gic 0 51 4
+			0000 0 0 4 &gic 0 52 4
+			>;
+		};
+
+		flash@0,00000000 {
+			compatible = "arm,vexpress-flash", "cfi-flash";
+			reg = <0 0x00000000 0x04000000>,
+			      <4 0x00000000 0x04000000>;
+			bank-width = <4>;
+		};
+
+		psram@1,00000000 {
+			compatible = "arm,vexpress-psram", "mtd-ram";
+			reg = <1 0x00000000 0x02000000>;
+			bank-width = <4>;
+		};
+
+		vram@2,00000000 {
+			compatible = "arm,vexpress-vram";
+			reg = <2 0x00000000 0x00800000>;
+		};
+
+		ethernet@2,02000000 {
+			compatible = "smsc,lan9118", "smsc,lan9115";
+			reg = <2 0x02000000 0x10000>;
+			interrupts = <15>;
+			phy-mode = "mii";
+			reg-io-width = <4>;
+			smsc,irq-active-high;
+			smsc,irq-push-pull;
+			vdd33a-supply = <&v2m_fixed_3v3>;
+			vddvario-supply = <&v2m_fixed_3v3>;
+		};
+
+		usb@2,03000000 {
+			compatible = "nxp,usb-isp1761";
+			reg = <2 0x03000000 0x20000>;
+			interrupts = <16>;
+			port1-otg;
+		};
+
+		iofpga@3,00000000 {
+			compatible = "arm,amba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 3 0 0x200000>;
+
+			v2m_sysreg: sysreg@010000 {
+				compatible = "arm,vexpress-sysreg";
+				reg = <0x010000 0x1000>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+
+			v2m_sysctl: sysctl@020000 {
+				compatible = "arm,sp810", "arm,primecell";
+				reg = <0x020000 0x1000>;
+				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
+				clock-names = "refclk", "timclk", "apb_pclk";
+				#clock-cells = <1>;
+				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+			};
+
+			/* PCI-E I2C bus */
+			v2m_i2c_pcie: i2c@030000 {
+				compatible = "arm,versatile-i2c";
+				reg = <0x030000 0x1000>;
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				pcie-switch@60 {
+					compatible = "idt,89hpes32h8";
+					reg = <0x60>;
+				};
+			};
+
+			aaci@040000 {
+				compatible = "arm,pl041", "arm,primecell";
+				reg = <0x040000 0x1000>;
+				interrupts = <11>;
+				clocks = <&smbclk>;
+				clock-names = "apb_pclk";
+			};
+
+			mmci@050000 {
+				compatible = "arm,pl180", "arm,primecell";
+				reg = <0x050000 0x1000>;
+				interrupts = <9 10>;
+				cd-gpios = <&v2m_sysreg 0 0>;
+				wp-gpios = <&v2m_sysreg 1 0>;
+				max-frequency = <12000000>;
+				vmmc-supply = <&v2m_fixed_3v3>;
+				clocks = <&v2m_clk24mhz>, <&smbclk>;
+				clock-names = "mclk", "apb_pclk";
+			};
+
+			kmi@060000 {
+				compatible = "arm,pl050", "arm,primecell";
+				reg = <0x060000 0x1000>;
+				interrupts = <12>;
+				clocks = <&v2m_clk24mhz>, <&smbclk>;
+				clock-names = "KMIREFCLK", "apb_pclk";
+			};
+
+			kmi@070000 {
+				compatible = "arm,pl050", "arm,primecell";
+				reg = <0x070000 0x1000>;
+				interrupts = <13>;
+				clocks = <&v2m_clk24mhz>, <&smbclk>;
+				clock-names = "KMIREFCLK", "apb_pclk";
+			};
+
+			v2m_serial0: uart@090000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x090000 0x1000>;
+				interrupts = <5>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial1: uart@0a0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0a0000 0x1000>;
+				interrupts = <6>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial2: uart@0b0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0b0000 0x1000>;
+				interrupts = <7>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial3: uart@0c0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0c0000 0x1000>;
+				interrupts = <8>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			wdt@0f0000 {
+				compatible = "arm,sp805", "arm,primecell";
+				reg = <0x0f0000 0x1000>;
+				interrupts = <0>;
+				clocks = <&v2m_refclk32khz>, <&smbclk>;
+				clock-names = "wdogclk", "apb_pclk";
+			};
+
+			v2m_timer01: timer@110000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x110000 0x1000>;
+				interrupts = <2>;
+				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			v2m_timer23: timer@120000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x120000 0x1000>;
+				interrupts = <3>;
+				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			/* DVI I2C bus */
+			v2m_i2c_dvi: i2c@160000 {
+				compatible = "arm,versatile-i2c";
+				reg = <0x160000 0x1000>;
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				dvi-transmitter@39 {
+					compatible = "sil,sii9022-tpi", "sil,sii9022";
+					reg = <0x39>;
+				};
+
+				dvi-transmitter@60 {
+					compatible = "sil,sii9022-cpi", "sil,sii9022";
+					reg = <0x60>;
+				};
+			};
+
+			rtc@170000 {
+				compatible = "arm,pl031", "arm,primecell";
+				reg = <0x170000 0x1000>;
+				interrupts = <4>;
+				clocks = <&smbclk>;
+				clock-names = "apb_pclk";
+			};
+
+			compact-flash@1a0000 {
+				compatible = "arm,vexpress-cf", "ata-generic";
+				reg = <0x1a0000 0x100
+				       0x1a0100 0xf00>;
+				reg-shift = <2>;
+			};
+
+			clcd@1f0000 {
+				status = "disabled";
+				compatible = "arm,pl111", "arm,primecell";
+				reg = <0x1f0000 0x1000>;
+				interrupts = <14>;
+				clocks = <&v2m_oscclk1>, <&smbclk>;
+				clock-names = "clcdclk", "apb_pclk";
+			};
+		};
+
+		v2m_fixed_3v3: fixedregulator@0 {
+			compatible = "regulator-fixed";
+			regulator-name = "3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		v2m_clk24mhz: clk24mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-output-names = "v2m:clk24mhz";
+		};
+
+		v2m_refclk1mhz: refclk1mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1000000>;
+			clock-output-names = "v2m:refclk1mhz";
+		};
+
+		v2m_refclk32khz: refclk32khz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "v2m:refclk32khz";
+		};
+
+		mcc {
+			compatible = "arm,vexpress,config-bus";
+			arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+			osc@0 {
+				/* MCC static memory clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 0>;
+				freq-range = <25000000 60000000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk0";
+			};
+
+			v2m_oscclk1: osc@1 {
+				/* CLCD clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 1>;
+				freq-range = <23750000 63500000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk1";
+			};
+
+			v2m_oscclk2: osc@2 {
+				/* IO FPGA peripheral clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 2>;
+				freq-range = <24000000 24000000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk2";
+			};
+
+			volt@0 {
+				/* Logic level voltage */
+				compatible = "arm,vexpress-volt";
+				arm,vexpress-sysreg,func = <2 0>;
+				regulator-name = "VIO";
+				regulator-always-on;
+				label = "VIO";
+			};
+
+			temp@0 {
+				/* MCC internal operating temperature */
+				compatible = "arm,vexpress-temp";
+				arm,vexpress-sysreg,func = <4 0>;
+				label = "MCC";
+			};
+
+			reset@0 {
+				compatible = "arm,vexpress-reset";
+				arm,vexpress-sysreg,func = <5 0>;
+			};
+
+			muxfpga@0 {
+				compatible = "arm,vexpress-muxfpga";
+				arm,vexpress-sysreg,func = <7 0>;
+			};
+
+			shutdown@0 {
+				compatible = "arm,vexpress-shutdown";
+				arm,vexpress-sysreg,func = <8 0>;
+			};
+
+			reboot@0 {
+				compatible = "arm,vexpress-reboot";
+				arm,vexpress-sysreg,func = <9 0>;
+			};
+
+			dvimode@0 {
+				compatible = "arm,vexpress-dvimode";
+				arm,vexpress-sysreg,func = <11 0>;
+			};
+		};
+	};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1-gem5.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1-gem5.dts
new file mode 100644
index 0000000..0ac3e65
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1-gem5.dts
@@ -0,0 +1,302 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A15x2 (version with Test Chip 1)
+ * Cortex-A15 MPCore (V2P-CA15)
+ *
+ * HBI-0237A
+ */
+
+/dts-v1/;
+
+/memreserve/ 0xbf000000 0x01000000;
+
+/ {
+	model = "V2P-CA15";
+	arm,hbi = <0x0>;
+	arm,vexpress,site = <0xf>;
+	compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+		i2c0 = &v2m_i2c_dvi;
+		i2c1 = &v2m_i2c_pcie;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0>;
+			clock-frequency = <1000000000>;
+		};
+
+/*		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <1>;
+		};
+*/
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0 0x80000000 0 0x40000000>;
+	};
+
+	hdlcd@2b000000 {
+		compatible = "arm,hdlcd";
+		reg = <0 0x2b000000 0 0x1000>;
+		interrupts = <0 85 4>;
+		clocks = <&oscclk5>;
+		clock-names = "pxlclk";
+		mode = "1024x768-16@60";
+		framebuffer = <0 0xbf000000 0 0x01000000>;
+	};
+/*
+	memory-controller@2b0a0000 {
+		compatible = "arm,pl341", "arm,primecell";
+		reg = <0 0x2b0a0000 0 0x1000>;
+		clocks = <&oscclk7>;
+		clock-names = "apb_pclk";
+	};
+*/
+/*
+	wdt@2b060000 {
+		compatible = "arm,sp805", "arm,primecell";
+		status = "disabled";
+		reg = <0 0x2b060000 0 0x1000>;
+		interrupts = <0 98 4>;
+		clocks = <&oscclk7>;
+		clock-names = "apb_pclk";
+	};
+*/
+	gic: interrupt-controller@2c001000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0 0x2c001000 0 0x1000>,
+		      <0 0x2c002000 0 0x1000>,
+		      <0 0x2c004000 0 0x2000>,
+		      <0 0x2c006000 0 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+/*
+	memory-controller@7ffd0000 {
+		compatible = "arm,pl354", "arm,primecell";
+		reg = <0 0x7ffd0000 0 0x1000>;
+		interrupts = <0 86 4>,
+			     <0 87 4>;
+		clocks = <&oscclk7>;
+		clock-names = "apb_pclk";
+	};
+*/
+/*
+	dma@7ffb0000 {
+		compatible = "arm,pl330", "arm,primecell";
+		reg = <0 0x7ffb0000 0 0x1000>;
+		interrupts = <0 92 4>,
+			     <0 88 4>,
+			     <0 89 4>,
+			     <0 90 4>,
+			     <0 91 4>;
+		clocks = <&oscclk7>;
+		clock-names = "apb_pclk";
+	};
+*/
+/*
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <1 13 0xf08>,
+			     <1 14 0xf08>,
+			     <1 11 0xf08>,
+			     <1 10 0xf08>;
+	};
+*/
+
+	/** HACK : cortex-a9-twd-timer hack -- temporary fix */
+	timer@2c080000 {
+		compatible = "arm,cortex-a9-twd-timer";
+		reg = <0 0x2c080000 0 0x20>;
+		interrupts = <1 13 0xf04>;
+		clocks = <&oscclk7>;
+		clock-names = "apb_pclk";
+	};
+
+	pmu {
+		compatible = "arm,cortex-a15-pmu";
+		interrupts = <0 68 4>,
+			     <0 69 4>;
+	};
+
+	dcc {
+		compatible = "arm,vexpress,config-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		osc@0 {
+			/* CPU PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 0>;
+			freq-range = <50000000 60000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk0";
+		};
+
+		osc@4 {
+			/* Multiplexed AXI master clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 4>;
+			freq-range = <20000000 40000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk4";
+		};
+
+		oscclk5: osc@5 {
+			/* HDLCD PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 5>;
+			freq-range = <23750000 165000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk5";
+		};
+
+		smbclk: osc@6 {
+			/* SMB clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 6>;
+			freq-range = <20000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk6";
+		};
+
+		oscclk7: osc@7 {
+			/* SYS PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 7>;
+			freq-range = <20000000 60000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk7";
+		};
+
+		osc@8 {
+			/* DDR2 PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 8>;
+			freq-range = <40000000 40000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk8";
+		};
+
+		volt@0 {
+			/* CPU core voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 0>;
+			regulator-name = "Cores";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-always-on;
+			label = "Cores";
+		};
+
+		amp@0 {
+			/* Total current for the two cores */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 0>;
+			label = "Cores";
+		};
+
+		temp@0 {
+			/* DCC internal temperature */
+			compatible = "arm,vexpress-temp";
+			arm,vexpress-sysreg,func = <4 0>;
+			label = "DCC";
+		};
+
+		power@0 {
+			/* Total power */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 0>;
+			label = "Cores";
+		};
+
+		energy@0 {
+			/* Total energy */
+			compatible = "arm,vexpress-energy";
+			arm,vexpress-sysreg,func = <13 0>;
+			label = "Cores";
+		};
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+
+		/include/ "vexpress-v2m-rs1-gem5.dtsi"
+	};
+};
diff --git a/arch/arm/configs/vexpress_gem5_defconfig b/arch/arm/configs/vexpress_gem5_defconfig
new file mode 100644
index 0000000..f992256c
--- /dev/null
+++ b/arch/arm/configs/vexpress_gem5_defconfig
@@ -0,0 +1,192 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+CONFIG_CPUSETS=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_ARCH_VEXPRESS_GEM5=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+CONFIG_MCPM=y
+CONFIG_BIG_LITTLE=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_SCHED_HRTICK=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_ARM_CPU_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+# CONFIG_ANDROID_PARANOID_NETWORK is not set
+# CONFIG_NET_ACTIVITY_STATS is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MISC_DEVICES=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_HAVE_PATA_PLATFORM=y
+CONFIG_ATA=y
+CONFIG_SATA_PMP=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_SATA_SFF=y
+CONFIG_ATA_BMDMA=y
+CONFIG_ATA_PIIX=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_MOUSE_PS2_TOUCHKIT=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+# CONFIG_VT_CONSOLE_SLEEP is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_HWMON is not set
+CONFIG_DISPLAY_TIMING=y
+CONFIG_VIDEOMODE=y
+CONFIG_OF_DISPLAY_TIMING=y
+CONFIG_OF_VIDEOMODE=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FB_ARMHDLCD=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_ARMAACI=y
+# CONFIG_SND_USB is not set
+CONFIG_HID_DRAGONRISE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_ISP1760_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_TIMED_OUTPUT=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
+CONFIG_ANDROID_INTF_ALARM_DEV=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_GATOR=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_NOP_TRACER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
+CONFIG_FTRACE=y
+CONFIG_DEBUG_USER=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_BINARY_PRINTF=y
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 556b01d..466497d 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -15,7 +15,6 @@
 	select HAVE_SMP
 	select ICST
 	select MIGHT_HAVE_CACHE_L2X0
-	select NO_IOPORT
 	select PLAT_VERSATILE
 	select PLAT_VERSATILE_CLCD
 	select POWER_RESET
@@ -34,6 +33,7 @@
 	  - LogicTile Express 13MG (V2F-2XV6) with A5, A7, A9 or A15 SMMs
 	    (Soft Macrocell Models)
 	  - Versatile Express RTSMs (Models)
+	  - Versatile Express gem5 (Model)
 
 	  You must boot using a Flattened Device Tree in order to use these
 	  platforms. The traditional (ATAGs) boot method is not usable on
@@ -42,6 +42,24 @@
 menu "Versatile Express platform type"
 	depends on ARCH_VEXPRESS
 
+choice
+        prompt "Platform variant"
+        default ARCH_VEXPRESS_CA9x4
+        config ARCH_VEXPRESS_CA9X4
+                bool "Versatile Express Cortex-A9x4 tile"
+                select NO_IOPORT
+
+        config ARCH_VEXPRESS_GEM5
+                bool "Versatile Express gem5 model"
+                select MIGHT_HAVE_PCI
+                select PCI
+                select NEED_MACH_IO_H
+                select NEED_MACH_MEMORY_H
+                help
+                  Enables gem5-specific workarounds / enhancements to the base
+                  Versatile Express platform.
+endchoice
+
 config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
 	bool "Enable A5 and A9 only errata work-arounds"
 	default y
@@ -53,10 +71,6 @@
 	  build a working kernel, you must also enable relevant core
 	  tile support or Flattened Device Tree based support options.
 
-config ARCH_VEXPRESS_CA9X4
-	bool "Versatile Express Cortex-A9x4 tile"
-	select ARM_ERRATA_643719
-
 config ARCH_VEXPRESS_DCSCB
 	bool "Dual Cluster System Control Block (DCSCB) support"
 	depends on MCPM
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 191f2b5..282134a 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -1,11 +1,19 @@
 #
 # Makefile for the linux kernel.
 #
+
+ifeq ($(CONFIG_ARCH_VEXPRESS_GEM5),y)
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
+	-I$(srctree)/arch/arm/plat-versatile/include \
+	-I$(srctree)/arch/arm/mach-vexpress/include
+else
 ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
 	-I$(srctree)/arch/arm/plat-versatile/include
+endif
 
 obj-y					:= v2m.o
 obj-$(CONFIG_ARCH_VEXPRESS_CA9X4)	+= ct-ca9x4.o
+obj-$(CONFIG_ARCH_VEXPRESS_GEM5)	+= ct-ca9x4.o
 obj-$(CONFIG_ARCH_VEXPRESS_DCSCB)	+= dcscb.o	dcscb_setup.o
 CFLAGS_dcscb.o				+= -march=armv7-a
 CFLAGS_REMOVE_dcscb.o			= -pg
@@ -20,3 +28,4 @@
 endif
 obj-$(CONFIG_SMP)			+= platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
+obj-$(CONFIG_PCI)			+= pcie_gem5.o
diff --git a/arch/arm/mach-vexpress/include/mach/hardware.h b/arch/arm/mach-vexpress/include/mach/hardware.h
index 40a8c17..6cfc841 100644
--- a/arch/arm/mach-vexpress/include/mach/hardware.h
+++ b/arch/arm/mach-vexpress/include/mach/hardware.h
@@ -1 +1,27 @@
-/* empty */
+#ifndef __ASM_ARM_ARCH_HARDWARE_H
+#define __ASM_ARM_ARCH_HARDWARE_H
+
+#define IRQ_V2M_PCIE		(32 + 36)
+
+/* The __io macro calls this function. */
+u32 pci_convert_base_to_vbase(u32 a);
+
+/* #defines replaced with u32 */
+extern u32 dt_vexpress_pci_cfg_base;
+extern u32 dt_vexpress_pci_cfg_size;
+extern u32 dt_vexpress_pci_cfg_limit;
+extern u32 dt_vexpress_pci_cfg_vbase;
+extern u32 dt_vexpress_pci_mem_vbase;
+extern u32 dt_vexpress_pci_memp_vbase;
+extern u32 dt_vexpress_pci_io_vbase;
+extern u32 dt_vexpress_pci_mem_base;
+extern u32 dt_vexpress_pci_memp_base;
+extern u32 dt_vexpress_pci_io_base;
+extern u32 dt_vexpress_pci_mem_size;
+extern u32 dt_vexpress_pci_memp_size;
+extern u32 dt_vexpress_pci_io_size;
+extern u32 dt_vexpress_pci_mem_limit;
+extern u32 dt_vexpress_pci_memp_limit;
+extern u32 dt_vexpress_pci_io_limit;
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h
new file mode 100644
index 0000000..abebbf8
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/io.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include "hardware.h"
+#define IO_SPACE_LIMIT  0xffffffff
+#define __io(a) __typesafe_io(pci_convert_base_to_vbase(a))
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/memory.h b/arch/arm/mach-vexpress/include/mach/memory.h
new file mode 100644
index 0000000..12be6c5
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/memory.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_ARM_ARCH_MEMORY_H
+#define __ASM_ARM_ARCH_MEMORY_H
+
+#define CONSISTENT_DMA_SIZE    SZ_16M
+#define arch_is_coherent() 1
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index 68abc8b..11c2305 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -60,7 +60,6 @@
 #define IRQ_V2M_CLCD		{ (32 + 14) }
 #define IRQ_V2M_LAN9118		(32 + 15)
 #define IRQ_V2M_ISP1761		(32 + 16)
-#define IRQ_V2M_PCIE		(32 + 17)
 
 
 /*
diff --git a/arch/arm/mach-vexpress/pcie_gem5.c b/arch/arm/mach-vexpress/pcie_gem5.c
new file mode 100644
index 0000000..d2bc768
--- /dev/null
+++ b/arch/arm/mach-vexpress/pcie_gem5.c
@@ -0,0 +1,200 @@
+/*
+ *  linux/arch/arm/mach-versatile/pci.c
+ *
+ * (C) Copyright Koninklijke Philips Electronics NV 2004. All rights reserved.
+ * You can redistribute and/or modify this software under the terms of version 2
+ * of the GNU General Public License as published by the Free Software Foundation.
+ * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * Koninklijke Philips Electronics nor its subsidiaries is obligated to provide any support for this software.
+ *
+ * ARM Versatile PCI driver.
+ *
+ * 14/04/2005 Initial version, colin.king@philips.com
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include "include/mach/hardware.h"
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+
+static int versatile_read_config(struct pci_bus *pbus, unsigned int devfn, int where,
+				 int size, u32 *val)
+{
+    u32 addr, bus, slot, function;
+    bus = pbus->number;
+    slot = PCI_SLOT(devfn);
+    function = PCI_FUNC(devfn);
+
+    if (bus != 0) {
+        switch (size) {
+          case 1:
+            *val = 0xff;
+            break;
+          case 2:
+            *val = 0xffff;
+            break;
+          case 4:
+            *val = 0xffffffff;
+            break;
+        }
+        return PCIBIOS_DEVICE_NOT_FOUND;
+    }
+
+    addr = dt_vexpress_pci_cfg_vbase | (bus << 24) | ((slot & 0x1f) << 19) |
+        ((function & 7) << 16) | where;
+
+    switch (size) {
+      case 1:
+        *val = readb(addr);
+        break;
+      case 2:
+        *val = readw(addr);
+        break;
+      case 4:
+        *val = readl(addr);
+        break;
+    }
+    return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int versatile_write_config(struct pci_bus *pbus, unsigned int devfn, int where,
+				  int size, u32 val)
+{
+    u32 addr, bus, slot, function;
+    bus = pbus->number;
+    slot = PCI_SLOT(devfn);
+    function = PCI_FUNC(devfn);
+
+    if (bus != 0) {
+        return PCIBIOS_DEVICE_NOT_FOUND;
+    }
+
+    addr = dt_vexpress_pci_cfg_vbase | (bus << 24) | ((slot & 0x1f) << 19) |
+        ((function & 7) << 16) | where;
+
+    switch (size) {
+      case 1:
+        writeb(val, addr);
+        break;
+      case 2:
+        writew(val, addr);
+        break;
+      case 4:
+        writel(val, addr);
+        break;
+    }
+    return PCIBIOS_SUCCESSFUL;
+}
+
+
+
+static struct pci_ops pci_versatile_ops = {
+	.read	= versatile_read_config,
+	.write	= versatile_write_config,
+};
+
+static struct resource vexpress_io_res = {
+	.name	= "PCI I/O space",
+	.start	= 0xDEADBEEF,
+	.end	= 0xDEADBEEF,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource vexpress_mem_res = {
+	.name	= "PCI non-prefetchable",
+	.start	= 0xDEADBEEF,
+	.end	= 0xDEADBEEF,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource vexpress_memp_res = {
+	.name	= "PCI prefetchable",
+	.start	= 0xDEADBEEF,
+	.end	= 0xDEADBEEF,
+	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+
+int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
+{
+    sys->busnr = 0;
+    sys->mem_offset = 0;
+    sys->io_offset = 0;
+
+    pci_add_resource(&sys->resources, &vexpress_io_res);
+    pci_add_resource(&sys->resources, &vexpress_mem_res);
+    pci_add_resource(&sys->resources, &vexpress_memp_res);
+
+    return 1;
+}
+
+struct pci_bus * __init pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
+{
+    struct pci_bus *root_bus = NULL;
+
+    root_bus = pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
+    pci_assign_unassigned_resources();
+
+    return root_bus;
+}
+
+void __init pci_versatile_preinit(void)
+{
+        vexpress_io_res.start = dt_vexpress_pci_io_base;
+        vexpress_io_res.end = dt_vexpress_pci_io_limit;
+
+        vexpress_mem_res.start = dt_vexpress_pci_mem_base;
+        vexpress_mem_res.end = dt_vexpress_pci_mem_limit;
+
+        vexpress_memp_res.start = dt_vexpress_pci_memp_base;
+        vexpress_memp_res.end = dt_vexpress_pci_memp_limit;
+
+	pcibios_min_io = dt_vexpress_pci_io_base;
+	pcibios_min_mem = dt_vexpress_pci_mem_base;
+}
+
+/*
+ * map the specified device/slot/pin to an IRQ.   Different backplanes may need to modify this.
+ */
+static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq;
+	int devslot = PCI_SLOT(dev->devfn);
+
+	irq = IRQ_V2M_PCIE + pin - 1;
+
+	printk("PCI map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq);
+
+	return irq;
+}
+
+static struct hw_pci versatile_pci __initdata = {
+	.swizzle		= NULL,
+	.map_irq		= versatile_map_irq,
+	.nr_controllers		= 1,
+	.setup			= pci_versatile_setup,
+	.scan			= pci_versatile_scan_bus,
+	.preinit		= pci_versatile_preinit,
+};
+
+static int __init versatile_pci_init(void)
+{
+	if (dt_vexpress_pci_cfg_base == 0)
+		pr_info("Skipping PCI init\n");
+	else
+		pci_common_init(&versatile_pci);
+	return 0;
+}
+
+subsys_initcall(versatile_pci_init);
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index ffa9b73..b297430 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -46,6 +46,30 @@
 #define V2M_PA_CS3	0x4c000000
 #define V2M_PA_CS7	0x10000000
 
+#define SPACE_CODE_BIT_LOCN 24
+#define SPACE_CODE_WIDTH 0x3
+
+u32 dt_vexpress_pci_cfg_base = 0;
+u32 dt_vexpress_pci_cfg_size;
+u32 dt_vexpress_pci_cfg_limit;
+u32 dt_vexpress_pci_cfg_vbase;
+u32 dt_vexpress_pci_mem_vbase;
+u32 dt_vexpress_pci_memp_vbase;
+u32 dt_vexpress_pci_io_vbase;
+u32 dt_vexpress_pci_mem_base;
+u32 dt_vexpress_pci_memp_base;
+u32 dt_vexpress_pci_io_base;
+u32 dt_vexpress_pci_mem_size;
+u32 dt_vexpress_pci_memp_size;
+u32 dt_vexpress_pci_io_size;
+u32 dt_vexpress_pci_mem_limit;
+u32 dt_vexpress_pci_memp_limit;
+u32 dt_vexpress_pci_io_limit;
+
+u32 pci_convert_base_to_vbase(u32 a) {
+    return (a - dt_vexpress_pci_io_base + dt_vexpress_pci_io_vbase);
+}
+
 static struct map_desc v2m_io_desc[] __initdata = {
 	{
 		.virtual	= V2M_PERIPH,
@@ -281,6 +305,33 @@
 	&rtc_device,
 };
 
+static struct map_desc v2m_rs1_io_desc_pci[] __initdata = {
+	{
+	    .virtual    = 0xDEADBEEF,
+	    .pfn        = 0xDEADBEEF,
+	    .length     = 0xDEADBEEF,
+	    .type       = MT_DEVICE
+	},
+	{
+	    .virtual    = 0xDEADBEEF,
+	    .pfn        = 0xDEADBEEF,
+	    .length     = 0xDEADBEEF,
+	    .type       = MT_DEVICE
+	},
+	{
+	    .virtual    = 0xDEADBEEF,
+	    .pfn        = 0xDEADBEEF,
+	    .length     = 0xDEADBEEF,
+	    .type       = MT_DEVICE
+	},
+	{
+	    .virtual    = 0xDEADBEEF,
+	    .pfn        = 0xDEADBEEF,
+	    .length     = 0xDEADBEEF,
+	    .type       = MT_DEVICE
+	},
+};
+
 static void __init v2m_timer_init(void)
 {
 	vexpress_clk_init(ioremap(V2M_SYSCTL, SZ_4K));
@@ -297,7 +348,7 @@
 struct ct_desc *ct_desc;
 
 static struct ct_desc *ct_descs[] __initdata = {
-#ifdef CONFIG_ARCH_VEXPRESS_CA9X4
+#if defined(CONFIG_ARCH_VEXPRESS_CA9X4) || defined(CONFIG_ARCH_VEXPRESS_GEM5)
 	&ct_ca9x4_desc,
 #endif
 };
@@ -415,15 +466,207 @@
 	return 1;
 }
 
+static int __init v2m_dt_scan_pcie_gem5_ranges(unsigned long node, const char *uname,
+		int depth, void *data)
+{
+	const u32 **ranges = data;
+
+	if (strncmp(uname, "gem5_pcie@", 10) != 0)
+		return 0;
+
+	*ranges = of_get_flat_dt_prop(node, "ranges", NULL);
+	return 1;
+}
+
+static int __init v2m_dt_scan_pcie_gem5_reg(unsigned long node, const char *uname,
+		int depth, void *data)
+{
+	const u32 **reg = data;
+
+	if (strncmp(uname, "gem5_pcie@", 10) != 0)
+		return 0;
+
+	*reg = of_get_flat_dt_prop(node, "reg", NULL);
+	return 1;
+}
+
+static int __init v2m_dt_scan_pcie_gem5_virtual_reg(unsigned long node, const char *uname,
+		int depth, void *data)
+{
+	const u32 **reg = data;
+
+	if (strncmp(uname, "gem5_pcie@", 10) != 0)
+		return 0;
+
+	*reg = of_get_flat_dt_prop(node, "virtual-reg", NULL);
+	return 1;
+}
+
+static int __init v2m_dt_scan_pcie_gem5_addr_cells(unsigned long node, const char *uname,
+		int depth, void *data)
+{
+	const u32 **addr_cells = data;
+
+	if (strncmp(uname, "gem5_pcie@", 10) != 0)
+		return 0;
+
+	*addr_cells = of_get_flat_dt_prop(node, "#address-cells", NULL);
+	return 1;
+}
+
+static int __init v2m_dt_scan_pcie_gem5_size_cells(unsigned long node, const char *uname,
+		int depth, void *data)
+{
+	const u32 **size_cells = data;
+
+	if (strncmp(uname, "gem5_pcie@", 10) != 0)
+		return 0;
+
+	*size_cells = of_get_flat_dt_prop(node, "#size-cells", NULL);
+	return 1;
+}
+
+static int __init v2m_dt_scan_motherboard_addr_cells(unsigned long node, const char *uname,
+		int depth, void *data)
+{
+	const u32 **addr_cells = data;
+
+	if (strcmp(uname, "motherboard") != 0)
+		return 0;
+
+	*addr_cells = of_get_flat_dt_prop(node, "#address-cells", NULL);
+	return 1;
+}
+
+static void __init v2m_dt_pci_init(void)
+{
+	const __be32 *ranges = NULL;
+	const __be32 *reg = NULL;
+	const __be32 *virtual_reg = NULL;
+	const __be32 *addr_cells  = NULL;
+	const __be32 *size_cells  = NULL;
+	const __be32 *m_addr_cells  = NULL;
+
+	/* variables to identify io and mem spaces */
+	int i;
+	int n_addr_cells, n_size_cells, m_n_addr_cells, range_set_w;
+	u32 phys_hi, phys_addr, addr_space_size;
+
+	/* Scan Flat device tree for pcie node and extract the necessary parameters */
+	printk("kdebugv2m: Following are test values to confirm proper working\n");
+	of_scan_flat_dt(v2m_dt_scan_pcie_gem5_ranges, &ranges);
+
+	if (ranges == NULL) {
+		pr_info("No gem5 PCI found in DT.\n");
+		return;
+	}
+
+	printk("kdebugv2m: Ranges %x %x \n",
+		be32_to_cpup(&ranges[0]), be32_to_cpup(&ranges[1]) );
+
+	of_scan_flat_dt(v2m_dt_scan_pcie_gem5_reg, &reg);
+	printk("kdebugv2m: Regs %x %x \n", be32_to_cpup(&reg[1]),
+		be32_to_cpup(&reg[2]) );
+
+	of_scan_flat_dt(v2m_dt_scan_pcie_gem5_virtual_reg, &virtual_reg);
+	printk("kdebugv2m: Virtual-Reg %x \n", be32_to_cpup(&virtual_reg[0]));
+
+	of_scan_flat_dt(v2m_dt_scan_pcie_gem5_addr_cells, &addr_cells);
+	printk("kdebugv2m: pci node addr_cells %x \n",
+		be32_to_cpup(&addr_cells[0]));
+
+	of_scan_flat_dt(v2m_dt_scan_pcie_gem5_size_cells, &size_cells);
+	printk("kdebugv2m: pci node size_cells %x \n",
+		be32_to_cpup(&size_cells[0]));
+
+	of_scan_flat_dt(v2m_dt_scan_motherboard_addr_cells, &m_addr_cells);
+	printk("kdebugv2m: motherboard addr_cells %x \n",
+		be32_to_cpup(&m_addr_cells[0]));
+
+	n_addr_cells = be32_to_cpup(addr_cells);
+	n_size_cells = be32_to_cpup(size_cells);
+	m_n_addr_cells = be32_to_cpup(m_addr_cells);
+	range_set_w = n_addr_cells + m_n_addr_cells + n_size_cells;
+
+	/* Assign values to the extern variables */
+	dt_vexpress_pci_cfg_base  = be32_to_cpup(&reg[1]);
+	dt_vexpress_pci_cfg_size  = be32_to_cpup(&reg[2]);
+	dt_vexpress_pci_cfg_vbase = be32_to_cpup(&virtual_reg[0]);
+
+	/* interating to get range parameters from Flat DTB */
+	for(i=0; i<3; i++) {
+		phys_hi = be32_to_cpup(&ranges[i*range_set_w]);
+		phys_addr = be32_to_cpup(&ranges[i*range_set_w + n_addr_cells - 1]);
+		addr_space_size = be32_to_cpup(&ranges[i*range_set_w + range_set_w - 1]);
+		switch( (phys_hi >> SPACE_CODE_BIT_LOCN) & SPACE_CODE_WIDTH) {
+		case 1: /* IO Space */
+			dt_vexpress_pci_io_base = phys_addr;
+			dt_vexpress_pci_io_size = addr_space_size;
+			break;
+		case 2: /* Mem Space */
+                	if( (phys_hi >> 30) & 0x1) { /* Prefetchable mem */
+				dt_vexpress_pci_memp_base = phys_addr;
+				dt_vexpress_pci_memp_size = addr_space_size;
+			} else { /* non-prefetchable mem */
+				dt_vexpress_pci_mem_base = phys_addr;
+				dt_vexpress_pci_mem_size = addr_space_size;
+			}
+			break;
+		}
+	}
+
+	dt_vexpress_pci_mem_vbase = dt_vexpress_pci_cfg_vbase +
+		dt_vexpress_pci_cfg_size;
+	dt_vexpress_pci_memp_vbase = dt_vexpress_pci_mem_vbase +
+		dt_vexpress_pci_mem_size;
+	dt_vexpress_pci_io_vbase = dt_vexpress_pci_memp_vbase +
+		dt_vexpress_pci_memp_size;
+	dt_vexpress_pci_cfg_limit  = (dt_vexpress_pci_cfg_size +
+		dt_vexpress_pci_cfg_base -1);
+	dt_vexpress_pci_mem_limit  = (dt_vexpress_pci_mem_base +
+		dt_vexpress_pci_mem_size - 1);
+	dt_vexpress_pci_memp_limit = (dt_vexpress_pci_memp_base +
+		dt_vexpress_pci_memp_size - 1);
+	dt_vexpress_pci_io_limit   = (dt_vexpress_pci_io_base +
+		dt_vexpress_pci_io_size - 1);
+
+	/* Update the map_desc structure */
+	// CFG
+	v2m_rs1_io_desc_pci[0].virtual    = dt_vexpress_pci_cfg_vbase;
+	v2m_rs1_io_desc_pci[0].pfn        = __phys_to_pfn(dt_vexpress_pci_cfg_base);
+	v2m_rs1_io_desc_pci[0].length     = dt_vexpress_pci_cfg_size;
+
+	// MEMP
+	v2m_rs1_io_desc_pci[1].virtual    = dt_vexpress_pci_memp_vbase;
+	v2m_rs1_io_desc_pci[1].pfn        = __phys_to_pfn(dt_vexpress_pci_memp_base);
+	v2m_rs1_io_desc_pci[1].length     = dt_vexpress_pci_memp_size;
+
+	// MEM
+	v2m_rs1_io_desc_pci[2].virtual    = dt_vexpress_pci_mem_vbase;
+	v2m_rs1_io_desc_pci[2].pfn        = __phys_to_pfn(dt_vexpress_pci_mem_base);
+	v2m_rs1_io_desc_pci[2].length     = dt_vexpress_pci_mem_size;
+
+	// IO
+	v2m_rs1_io_desc_pci[3].virtual    = dt_vexpress_pci_io_vbase;
+	v2m_rs1_io_desc_pci[3].pfn        = __phys_to_pfn(dt_vexpress_pci_io_base);
+	v2m_rs1_io_desc_pci[3].length     = dt_vexpress_pci_io_size;
+
+	/* Initialize the updated mapping */
+	iotable_init(v2m_rs1_io_desc_pci, ARRAY_SIZE(v2m_rs1_io_desc_pci));
+}
+
 void __init v2m_dt_map_io(void)
 {
 	const char *map = NULL;
 
 	of_scan_flat_dt(v2m_dt_scan_memory_map, &map);
 
-	if (map && strcmp(map, "rs1") == 0)
+	if (map && strcmp(map, "rs1") == 0) {
 		iotable_init(&v2m_rs1_io_desc, 1);
-	else
+#ifdef CONFIG_PCI
+		v2m_dt_pci_init();
+#endif
+	} else
 		iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
 
 #if defined(CONFIG_SMP)