diff options
Diffstat (limited to 'arch/sparc64/kernel/traps.c')
-rw-r--r-- | arch/sparc64/kernel/traps.c | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 3d924121c796..81ccd22e78d4 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/linkage.h> | ||
13 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
14 | #include <linux/signal.h> | 15 | #include <linux/signal.h> |
15 | #include <linux/smp.h> | 16 | #include <linux/smp.h> |
@@ -37,6 +38,7 @@ | |||
37 | #include <asm/timer.h> | 38 | #include <asm/timer.h> |
38 | #include <asm/head.h> | 39 | #include <asm/head.h> |
39 | #include <asm/prom.h> | 40 | #include <asm/prom.h> |
41 | #include <asm/memctrl.h> | ||
40 | 42 | ||
41 | #include "entry.h" | 43 | #include "entry.h" |
42 | #include "kstack.h" | 44 | #include "kstack.h" |
@@ -128,6 +130,56 @@ void do_BUG(const char *file, int line) | |||
128 | } | 130 | } |
129 | #endif | 131 | #endif |
130 | 132 | ||
133 | static DEFINE_SPINLOCK(dimm_handler_lock); | ||
134 | static dimm_printer_t dimm_handler; | ||
135 | |||
136 | static int sprintf_dimm(int synd_code, unsigned long paddr, char *buf, int buflen) | ||
137 | { | ||
138 | unsigned long flags; | ||
139 | int ret = -ENODEV; | ||
140 | |||
141 | spin_lock_irqsave(&dimm_handler_lock, flags); | ||
142 | if (dimm_handler) { | ||
143 | ret = dimm_handler(synd_code, paddr, buf, buflen); | ||
144 | } else if (tlb_type == spitfire) { | ||
145 | if (prom_getunumber(synd_code, paddr, buf, buflen) == -1) | ||
146 | ret = -EINVAL; | ||
147 | else | ||
148 | ret = 0; | ||
149 | } else | ||
150 | ret = -ENODEV; | ||
151 | spin_unlock_irqrestore(&dimm_handler_lock, flags); | ||
152 | |||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | int register_dimm_printer(dimm_printer_t func) | ||
157 | { | ||
158 | unsigned long flags; | ||
159 | int ret = 0; | ||
160 | |||
161 | spin_lock_irqsave(&dimm_handler_lock, flags); | ||
162 | if (!dimm_handler) | ||
163 | dimm_handler = func; | ||
164 | else | ||
165 | ret = -EEXIST; | ||
166 | spin_unlock_irqrestore(&dimm_handler_lock, flags); | ||
167 | |||
168 | return ret; | ||
169 | } | ||
170 | EXPORT_SYMBOL_GPL(register_dimm_printer); | ||
171 | |||
172 | void unregister_dimm_printer(dimm_printer_t func) | ||
173 | { | ||
174 | unsigned long flags; | ||
175 | |||
176 | spin_lock_irqsave(&dimm_handler_lock, flags); | ||
177 | if (dimm_handler == func) | ||
178 | dimm_handler = NULL; | ||
179 | spin_unlock_irqrestore(&dimm_handler_lock, flags); | ||
180 | } | ||
181 | EXPORT_SYMBOL_GPL(unregister_dimm_printer); | ||
182 | |||
131 | void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) | 183 | void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) |
132 | { | 184 | { |
133 | siginfo_t info; | 185 | siginfo_t info; |
@@ -290,10 +342,7 @@ void sun4v_data_access_exception_tl1(struct pt_regs *regs, unsigned long addr, u | |||
290 | } | 342 | } |
291 | 343 | ||
292 | #ifdef CONFIG_PCI | 344 | #ifdef CONFIG_PCI |
293 | /* This is really pathetic... */ | 345 | #include "pci_impl.h" |
294 | extern volatile int pci_poke_in_progress; | ||
295 | extern volatile int pci_poke_cpu; | ||
296 | extern volatile int pci_poke_faulted; | ||
297 | #endif | 346 | #endif |
298 | 347 | ||
299 | /* When access exceptions happen, we must do this. */ | 348 | /* When access exceptions happen, we must do this. */ |
@@ -375,8 +424,7 @@ static void spitfire_log_udb_syndrome(unsigned long afar, unsigned long udbh, un | |||
375 | 424 | ||
376 | if (udbl & bit) { | 425 | if (udbl & bit) { |
377 | scode = ecc_syndrome_table[udbl & 0xff]; | 426 | scode = ecc_syndrome_table[udbl & 0xff]; |
378 | if (prom_getunumber(scode, afar, | 427 | if (sprintf_dimm(scode, afar, memmod_str, sizeof(memmod_str)) < 0) |
379 | memmod_str, sizeof(memmod_str)) == -1) | ||
380 | p = syndrome_unknown; | 428 | p = syndrome_unknown; |
381 | else | 429 | else |
382 | p = memmod_str; | 430 | p = memmod_str; |
@@ -387,8 +435,7 @@ static void spitfire_log_udb_syndrome(unsigned long afar, unsigned long udbh, un | |||
387 | 435 | ||
388 | if (udbh & bit) { | 436 | if (udbh & bit) { |
389 | scode = ecc_syndrome_table[udbh & 0xff]; | 437 | scode = ecc_syndrome_table[udbh & 0xff]; |
390 | if (prom_getunumber(scode, afar, | 438 | if (sprintf_dimm(scode, afar, memmod_str, sizeof(memmod_str)) < 0) |
391 | memmod_str, sizeof(memmod_str)) == -1) | ||
392 | p = syndrome_unknown; | 439 | p = syndrome_unknown; |
393 | else | 440 | else |
394 | p = memmod_str; | 441 | p = memmod_str; |
@@ -1061,8 +1108,6 @@ static const char *cheetah_get_string(unsigned long bit) | |||
1061 | return "???"; | 1108 | return "???"; |
1062 | } | 1109 | } |
1063 | 1110 | ||
1064 | extern int chmc_getunumber(int, unsigned long, char *, int); | ||
1065 | |||
1066 | static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *info, | 1111 | static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *info, |
1067 | unsigned long afsr, unsigned long afar, int recoverable) | 1112 | unsigned long afsr, unsigned long afar, int recoverable) |
1068 | { | 1113 | { |
@@ -1104,7 +1149,7 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in | |||
1104 | 1149 | ||
1105 | syndrome = (afsr & CHAFSR_E_SYNDROME) >> CHAFSR_E_SYNDROME_SHIFT; | 1150 | syndrome = (afsr & CHAFSR_E_SYNDROME) >> CHAFSR_E_SYNDROME_SHIFT; |
1106 | syndrome = cheetah_ecc_syntab[syndrome]; | 1151 | syndrome = cheetah_ecc_syntab[syndrome]; |
1107 | ret = chmc_getunumber(syndrome, afar, unum, sizeof(unum)); | 1152 | ret = sprintf_dimm(syndrome, afar, unum, sizeof(unum)); |
1108 | if (ret != -1) | 1153 | if (ret != -1) |
1109 | printk("%s" "ERROR(%d): AFAR E-syndrome [%s]\n", | 1154 | printk("%s" "ERROR(%d): AFAR E-syndrome [%s]\n", |
1110 | (recoverable ? KERN_WARNING : KERN_CRIT), | 1155 | (recoverable ? KERN_WARNING : KERN_CRIT), |
@@ -1115,7 +1160,7 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in | |||
1115 | 1160 | ||
1116 | syndrome = (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT; | 1161 | syndrome = (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT; |
1117 | syndrome = cheetah_mtag_syntab[syndrome]; | 1162 | syndrome = cheetah_mtag_syntab[syndrome]; |
1118 | ret = chmc_getunumber(syndrome, afar, unum, sizeof(unum)); | 1163 | ret = sprintf_dimm(syndrome, afar, unum, sizeof(unum)); |
1119 | if (ret != -1) | 1164 | if (ret != -1) |
1120 | printk("%s" "ERROR(%d): AFAR M-syndrome [%s]\n", | 1165 | printk("%s" "ERROR(%d): AFAR M-syndrome [%s]\n", |
1121 | (recoverable ? KERN_WARNING : KERN_CRIT), | 1166 | (recoverable ? KERN_WARNING : KERN_CRIT), |
@@ -2223,7 +2268,6 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2223 | 2268 | ||
2224 | extern int handle_popc(u32 insn, struct pt_regs *regs); | 2269 | extern int handle_popc(u32 insn, struct pt_regs *regs); |
2225 | extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); | 2270 | extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); |
2226 | extern int vis_emul(struct pt_regs *, unsigned int); | ||
2227 | 2271 | ||
2228 | void do_illegal_instruction(struct pt_regs *regs) | 2272 | void do_illegal_instruction(struct pt_regs *regs) |
2229 | { | 2273 | { |
@@ -2453,7 +2497,7 @@ struct trap_per_cpu trap_block[NR_CPUS]; | |||
2453 | /* This can get invoked before sched_init() so play it super safe | 2497 | /* This can get invoked before sched_init() so play it super safe |
2454 | * and use hard_smp_processor_id(). | 2498 | * and use hard_smp_processor_id(). |
2455 | */ | 2499 | */ |
2456 | void init_cur_cpu_trap(struct thread_info *t) | 2500 | void notrace init_cur_cpu_trap(struct thread_info *t) |
2457 | { | 2501 | { |
2458 | int cpu = hard_smp_processor_id(); | 2502 | int cpu = hard_smp_processor_id(); |
2459 | struct trap_per_cpu *p = &trap_block[cpu]; | 2503 | struct trap_per_cpu *p = &trap_block[cpu]; |