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
6 * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
7 * Copyright (C) 1999, 2000 by Silicon Graphics
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <asm/sn/addrs.h>
12 #include <asm/sn/arch.h>
13 #include <asm/sn/sn0/hub.h>
14 #include <asm/uaccess.h>
16 extern void dump_tlb_addr(unsigned long addr
);
17 extern void dump_tlb_all(void);
19 extern asmlinkage
void handle_ibe(void);
20 extern asmlinkage
void handle_dbe(void);
22 extern const struct exception_table_entry __start___dbe_table
[];
23 extern const struct exception_table_entry __stop___dbe_table
[];
25 static inline unsigned long
26 search_one_table(const struct exception_table_entry
*first
,
27 const struct exception_table_entry
*last
,
30 while (first
<= last
) {
31 const struct exception_table_entry
*mid
;
34 mid
= (last
- first
) / 2 + first
;
35 diff
= mid
->insn
- value
;
46 static inline unsigned long
47 search_dbe_table(unsigned long addr
)
51 /* There is only the kernel to search. */
52 ret
= search_one_table(__start___dbe_table
, __stop___dbe_table
-1, addr
);
58 void do_ibe(struct pt_regs
*regs
)
60 printk("Got ibe at 0x%lx\n", regs
->cp0_epc
);
62 dump_tlb_addr(regs
->cp0_epc
);
63 force_sig(SIGBUS
, current
);
67 void do_dbe(struct pt_regs
*regs
)
71 fixup
= search_dbe_table(regs
->cp0_epc
);
75 new_epc
= fixup_exception(dpf_reg
, fixup
, regs
->cp0_epc
);
76 regs
->cp0_epc
= new_epc
;
80 printk("Got dbe at 0x%lx\n", regs
->cp0_epc
);
84 force_sig(SIGBUS
, current
);
90 /* XXX Initialize all the Hub & Bridge error handling here. */
91 int cpu
= LOCAL_HUB_L(PI_CPU_NUM
);
92 int cpuoff
= cpu
<< 8;
94 set_except_vector(6, handle_ibe
);
95 set_except_vector(7, handle_dbe
);
97 LOCAL_HUB_S(PI_ERR_INT_PEND
,
98 cpu
? PI_ERR_CLEAR_ALL_A
: PI_ERR_CLEAR_ALL_B
);
99 LOCAL_HUB_S(PI_ERR_INT_MASK_A
+ cpuoff
, 0);
100 LOCAL_HUB_S(PI_ERR_STACK_ADDR_A
+ cpuoff
, 0);
101 LOCAL_HUB_S(PI_ERR_STACK_SIZE
, 0); /* Disable error stack */
102 LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN
, PI_SYSAD_CHECK_ALL
);