summaryrefslogtreecommitdiff
path: root/cpu/ppc4xx/440spe_pcie.c
diff options
context:
space:
mode:
authorGrzegorz Bernacki <gjb@semihalf.com>2007-07-31 18:51:48 +0200
committerStefan Roese <sr@denx.de>2007-08-02 08:25:27 +0200
commitc92409812206ac67a7fa7aae298539a9c3804a46 (patch)
tree5bd063206855c92bade65703c2848e2ccb33633e /cpu/ppc4xx/440spe_pcie.c
parentdec99558b9ea75a37940d07f41a3565a50b54ad1 (diff)
downloadu-boot-imx-c92409812206ac67a7fa7aae298539a9c3804a46.zip
u-boot-imx-c92409812206ac67a7fa7aae298539a9c3804a46.tar.gz
u-boot-imx-c92409812206ac67a7fa7aae298539a9c3804a46.tar.bz2
[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>
Diffstat (limited to 'cpu/ppc4xx/440spe_pcie.c')
-rw-r--r--cpu/ppc4xx/440spe_pcie.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/cpu/ppc4xx/440spe_pcie.c b/cpu/ppc4xx/440spe_pcie.c
index 7b27e87..bf68cc1 100644
--- a/cpu/ppc4xx/440spe_pcie.c
+++ b/cpu/ppc4xx/440spe_pcie.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2006
+ * (C) Copyright 2006 - 2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Copyright (c) 2005 Cisco Systems. All rights reserved.
@@ -40,6 +40,34 @@ enum {
LNKW_X8 = 0x8
};
+static inline int pcie_in_8(const volatile unsigned char __iomem *addr)
+{
+ int ret;
+
+ PCIE_IN(lbzx, ret, addr);
+
+ return ret;
+}
+
+static inline int pcie_in_le16(const volatile unsigned short __iomem *addr)
+{
+ int ret;
+
+ PCIE_IN(lhbrx, ret, addr)
+
+ return ret;
+}
+
+static inline unsigned pcie_in_le32(const volatile unsigned __iomem *addr)
+{
+ unsigned ret;
+
+ PCIE_IN(lwbrx, ret, addr);
+
+ return ret;
+}
+
+
static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
int offset, int len, u32 *val) {
@@ -55,13 +83,13 @@ static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
switch (len) {
case 1:
- *val = in_8(hose->cfg_data + offset);
+ *val = pcie_in_8(hose->cfg_data + offset);
break;
case 2:
- *val = in_le16((u16 *)(hose->cfg_data + offset));
+ *val = pcie_in_le16((u16 *)(hose->cfg_data + offset));
break;
default:
- *val = in_le32((u32 *)(hose->cfg_data + offset));
+ *val = pcie_in_le32((u32*)(hose->cfg_data + offset));
break;
}
return 0;