diff options
Diffstat (limited to 'arch/mips/sgi-ip27/ip27-berr.c')
-rw-r--r-- | arch/mips/sgi-ip27/ip27-berr.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c new file mode 100644 index 000000000000..e1829a5d3b19 --- /dev/null +++ b/arch/mips/sgi-ip27/ip27-berr.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle | ||
7 | * Copyright (C) 1999, 2000 by Silicon Graphics | ||
8 | * Copyright (C) 2002 Maciej W. Rozycki | ||
9 | */ | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | |||
14 | #include <asm/module.h> | ||
15 | #include <asm/sn/addrs.h> | ||
16 | #include <asm/sn/arch.h> | ||
17 | #include <asm/sn/sn0/hub.h> | ||
18 | #include <asm/tlbdebug.h> | ||
19 | #include <asm/traps.h> | ||
20 | #include <asm/uaccess.h> | ||
21 | |||
22 | extern void dump_tlb_addr(unsigned long addr); | ||
23 | extern void dump_tlb_all(void); | ||
24 | |||
25 | static void dump_hub_information(unsigned long errst0, unsigned long errst1) | ||
26 | { | ||
27 | static char *err_type[2][8] = { | ||
28 | { NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout", | ||
29 | NULL, NULL, NULL, NULL }, | ||
30 | { "WERR", "Uncached Partial Write", "PWERR", "Write Timeout", | ||
31 | NULL, NULL, NULL, NULL } | ||
32 | }; | ||
33 | int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK; | ||
34 | |||
35 | if (!(errst0 & PI_ERR_ST0_VALID_MASK)) { | ||
36 | printk("Hub does not contain valid error information\n"); | ||
37 | return; | ||
38 | } | ||
39 | |||
40 | |||
41 | printk("Hub has valid error information:\n"); | ||
42 | if (errst0 & PI_ERR_ST0_OVERRUN_MASK) | ||
43 | printk("Overrun is set. Error stack may contain additional " | ||
44 | "information.\n"); | ||
45 | printk("Hub error address is %08lx\n", | ||
46 | (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3)); | ||
47 | printk("Incoming message command 0x%lx\n", | ||
48 | (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT); | ||
49 | printk("Supplemental field of incoming message is 0x%lx\n", | ||
50 | (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT); | ||
51 | printk("T5 Rn (for RRB only) is 0x%lx\n", | ||
52 | (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT); | ||
53 | printk("Error type is %s\n", err_type[wrb] | ||
54 | [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT] | ||
55 | ? : "invalid"); | ||
56 | } | ||
57 | |||
58 | int ip27_be_handler(struct pt_regs *regs, int is_fixup) | ||
59 | { | ||
60 | unsigned long errst0, errst1; | ||
61 | int data = regs->cp0_cause & 4; | ||
62 | int cpu = LOCAL_HUB_L(PI_CPU_NUM); | ||
63 | |||
64 | if (is_fixup) | ||
65 | return MIPS_BE_FIXUP; | ||
66 | |||
67 | printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i', | ||
68 | regs->cp0_epc); | ||
69 | printk("Hub information:\n"); | ||
70 | printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND)); | ||
71 | errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A); | ||
72 | errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A); | ||
73 | dump_hub_information(errst0, errst1); | ||
74 | show_regs(regs); | ||
75 | dump_tlb_all(); | ||
76 | while(1); | ||
77 | force_sig(SIGBUS, current); | ||
78 | } | ||
79 | |||
80 | void __init ip27_be_init(void) | ||
81 | { | ||
82 | /* XXX Initialize all the Hub & Bridge error handling here. */ | ||
83 | int cpu = LOCAL_HUB_L(PI_CPU_NUM); | ||
84 | int cpuoff = cpu << 8; | ||
85 | |||
86 | board_be_handler = ip27_be_handler; | ||
87 | |||
88 | LOCAL_HUB_S(PI_ERR_INT_PEND, | ||
89 | cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A); | ||
90 | LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0); | ||
91 | LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0); | ||
92 | LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0); /* Disable error stack */ | ||
93 | LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL); | ||
94 | } | ||