[ppc440SPe] Graceful recovery from machine check during PCIe configuration

During config transactions on the PCIe bus an attempt to scan for a
non-existent device can lead to a machine check exception with certain
peripheral devices. In order to avoid crashing in such scenarios the
instrumented versions of the config cycle read routines are introduced, so
the exceptions fixups framework can gracefully recover.

Signed-off-by: Grzegorz Bernacki <gjb@semihalf.com>
Acked-by: Rafal Jaworowski <raj@semihalf.com>
diff --git a/cpu/ppc4xx/440spe_pcie.h b/cpu/ppc4xx/440spe_pcie.h
index 2becc77..eb7cecf 100644
--- a/cpu/ppc4xx/440spe_pcie.h
+++ b/cpu/ppc4xx/440spe_pcie.h
@@ -145,8 +145,8 @@
 #define PECFG_PIMEN		0x33c
 #define PECFG_PIM0LAL		0x340
 #define PECFG_PIM0LAH		0x344
-#define PECFG_PIM1LAL     	0x348
-#define PECFG_PIM1LAH     	0x34c
+#define PECFG_PIM1LAL		0x348
+#define PECFG_PIM1LAH		0x34c
 #define PECFG_PIM01SAL		0x350
 #define PECFG_PIM01SAH		0x354
 
@@ -161,6 +161,21 @@
 	mtdcr(DCRN_SDR0_CFGADDR, offset); \
 	mtdcr(DCRN_SDR0_CFGDATA,data);})
 
+#define PCIE_IN(opcode, ret, addr) \
+	__asm__ __volatile__(			\
+		"sync\n"			\
+		#opcode " %0,0,%1\n"		\
+		"1: twi 0,%0,0\n"		\
+		"isync\n"			\
+		"b 3f\n"			\
+		"2: li %0,-1\n"			\
+		"3:\n"				\
+		".section __ex_table,\"a\"\n"	\
+		".balign 4\n"			\
+		".long 1b,2b\n"			\
+		".previous\n"			\
+		: "=r" (ret) : "r" (addr), "m" (*addr));
+
 int ppc440spe_init_pcie(void);
 int ppc440spe_init_pcie_rootport(int port);
 void yucca_setup_pcie_fpga_rootpoint(int port);