aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/traps.c')
-rw-r--r--arch/sparc64/kernel/traps.c72
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
133static DEFINE_SPINLOCK(dimm_handler_lock);
134static dimm_printer_t dimm_handler;
135
136static 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
156int 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}
170EXPORT_SYMBOL_GPL(register_dimm_printer);
171
172void 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}
181EXPORT_SYMBOL_GPL(unregister_dimm_printer);
182
131void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) 183void 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"
294extern volatile int pci_poke_in_progress;
295extern volatile int pci_poke_cpu;
296extern 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
1064extern int chmc_getunumber(int, unsigned long, char *, int);
1065
1066static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *info, 1111static 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
2224extern int handle_popc(u32 insn, struct pt_regs *regs); 2269extern int handle_popc(u32 insn, struct pt_regs *regs);
2225extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); 2270extern int handle_ldf_stq(u32 insn, struct pt_regs *regs);
2226extern int vis_emul(struct pt_regs *, unsigned int);
2227 2271
2228void do_illegal_instruction(struct pt_regs *regs) 2272void 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 */
2456void init_cur_cpu_trap(struct thread_info *t) 2500void 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];