PPC 85xx: Add qemu-ppce500 machine

For KVM we have a special PV machine type called "ppce500". This machine
is inspired by the MPC8544DS board, but implements a lot less features
than that one.

It also provides more PCI slots and is supposed to be enumerated by
device tree only.

This patch adds support for the generic ppce500 machine and tries to
rely solely on device tree for device enumeration.

Signed-off-by: Alexander Graf <agraf@suse.de>
Acked-by: Scott Wood <scottwood@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>
diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile
index ef7637a..4094785 100644
--- a/arch/powerpc/cpu/mpc85xx/Makefile
+++ b/arch/powerpc/cpu/mpc85xx/Makefile
@@ -102,7 +102,9 @@
 obj-y	+= cpu_init.o
 obj-y	+= cpu_init_early.o
 obj-y	+= interrupts.o
+ifneq ($(CONFIG_QEMU_E500),y)
 obj-y	+= speed.o
+endif
 obj-y	+= tlb.o
 obj-y	+= traps.o
 
diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c
index 3e99b07..2c8126c 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu.c
@@ -272,7 +272,7 @@
 #ifndef CONFIG_SYS_FSL_TBCLK_DIV
 #define CONFIG_SYS_FSL_TBCLK_DIV 8
 #endif
-unsigned long get_tbclk (void)
+__weak unsigned long get_tbclk (void)
 {
 	unsigned long tbclk_div = CONFIG_SYS_FSL_TBCLK_DIV;
 
@@ -338,7 +338,8 @@
 	!defined(CONFIG_SYS_INIT_L2_ADDR)
 phys_size_t initdram(int board_type)
 {
-#if defined(CONFIG_SPD_EEPROM) || defined(CONFIG_DDR_SPD)
+#if defined(CONFIG_SPD_EEPROM) || defined(CONFIG_DDR_SPD) || \
+	defined(CONFIG_QEMU_E500)
 	return fsl_ddr_sdram_size();
 #else
 	return (phys_size_t)CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c
index 993b8b8..998781b 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c
@@ -79,7 +79,7 @@
 #endif
 
 /* We run cpu_init_early_f in AS = 1 */
-void cpu_init_early_f(void)
+void cpu_init_early_f(void *fdt)
 {
 	u32 mas0, mas1, mas2, mas3, mas7;
 	int i;
@@ -102,6 +102,12 @@
 	for (i = 0; i < sizeof(gd_t); i++)
 		((char *)gd)[i] = 0;
 
+	/*
+	 * CONFIG_SYS_CCSRBAR_PHYS below may use gd->fdt_blob on ePAPR systems,
+	 * so we need to populate it before it accesses it.
+	 */
+	gd->fdt_blob = fdt;
+
 	mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(13);
 	mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_1M);
 	mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G);
diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S
index 691bd3a..6b0380f 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -78,6 +78,13 @@
 	li	r1,MSR_DE
 	mtmsr 	r1
 
+	/*
+	 * If we got an ePAPR device tree pointer passed in as r3, we need that
+	 * later in cpu_init_early_f(). Save it to a safe register before we
+	 * clobber it so that we can fetch it from there later.
+	 */
+	mr	r24, r3
+
 #ifdef CONFIG_SYS_FSL_ERRATUM_A004510
 	mfspr	r3,SPRN_SVR
 	rlwinm	r3,r3,0,0xff
@@ -1142,6 +1149,10 @@
 	mr	r1,r3		/* Transfer to SP(r1) */
 
 	GET_GOT
+
+	/* Pass our potential ePAPR device tree pointer to cpu_init_early_f */
+	mr	r3, r24
+
 	bl	cpu_init_early_f
 
 	/* switch back to AS = 0 */
diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c
index fed8df9..129ec66 100644
--- a/arch/powerpc/cpu/mpc85xx/tlb.c
+++ b/arch/powerpc/cpu/mpc85xx/tlb.c
@@ -24,7 +24,7 @@
 		mtspr(MMUCSR0, 0x2);
 }
 
-void init_tlbs(void)
+__weak void init_tlbs(void)
 {
 	int i;
 
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index df44451..e376783 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -797,6 +797,10 @@
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_A005125
 
+#elif defined(CONFIG_QEMU_E500)
+#define CONFIG_MAX_CPUS			1
+#define CONFIG_SYS_CCSRBAR_DEFAULT	0xe0000000
+
 #else
 #error Processor type not defined for this platform
 #endif