1 // SPDX-License-Identifier: GPL-2.0-only !! 1 /* $Id: traps.c,v 1.82 2001/11/18 00:12:56 davem Exp $ 2 /* !! 2 * arch/sparc64/kernel/traps.c 3 * Traps/Non-MMU Exception handling for ARC << 4 * << 5 * Copyright (C) 2004, 2007-2010, 2011-2012 Sy << 6 * << 7 * vineetg: May 2011 << 8 * -user-space unaligned access emulation << 9 * 3 * 10 * Rahul Trivedi: Codito Technologies 2004 !! 4 * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) >> 5 * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com) 11 */ 6 */ 12 7 13 #include <linux/sched/signal.h> !! 8 /* 14 #include <linux/kdebug.h> !! 9 * I like traps on v9, :)))) 15 #include <linux/uaccess.h> !! 10 */ 16 #include <linux/ptrace.h> << 17 #include <linux/kprobes.h> << 18 #include <linux/kgdb.h> << 19 #include <asm/entry.h> << 20 #include <asm/setup.h> << 21 #include <asm/unaligned.h> << 22 #include <asm/kprobes.h> << 23 11 24 void die(const char *str, struct pt_regs *regs !! 12 #include <linux/config.h> >> 13 #include <linux/sched.h> /* for jiffies */ >> 14 #include <linux/kernel.h> >> 15 #include <linux/signal.h> >> 16 #include <linux/smp.h> >> 17 #include <linux/smp_lock.h> >> 18 #include <linux/mm.h> >> 19 >> 20 #include <asm/delay.h> >> 21 #include <asm/system.h> >> 22 #include <asm/ptrace.h> >> 23 #include <asm/oplib.h> >> 24 #include <asm/page.h> >> 25 #include <asm/pgtable.h> >> 26 #include <asm/unistd.h> >> 27 #include <asm/uaccess.h> >> 28 #include <asm/fpumacro.h> >> 29 #include <asm/lsu.h> >> 30 #include <asm/dcu.h> >> 31 #include <asm/estate.h> >> 32 #include <asm/chafsr.h> >> 33 #include <asm/sfafsr.h> >> 34 #include <asm/psrcompat.h> >> 35 #include <asm/processor.h> >> 36 #ifdef CONFIG_KMOD >> 37 #include <linux/kmod.h> >> 38 #endif >> 39 >> 40 /* When an irrecoverable trap occurs at tl > 0, the trap entry >> 41 * code logs the trap state registers at every level in the trap >> 42 * stack. It is found at (pt_regs + sizeof(pt_regs)) and the layout >> 43 * is as follows: >> 44 */ >> 45 struct tl1_traplog { >> 46 struct { >> 47 unsigned long tstate; >> 48 unsigned long tpc; >> 49 unsigned long tnpc; >> 50 unsigned long tt; >> 51 } trapstack[4]; >> 52 unsigned long tl; >> 53 }; >> 54 >> 55 static void dump_tl1_traplog(struct tl1_traplog *p) 25 { 56 { 26 show_kernel_fault_diag(str, regs, addr !! 57 int i; 27 58 28 /* DEAD END */ !! 59 printk("TRAPLOG: Error at trap level 0x%lx, dumping track stack.\n", 29 __asm__("flag 1"); !! 60 p->tl); >> 61 for (i = 0; i < 4; i++) { >> 62 printk(KERN_CRIT >> 63 "TRAPLOG: Trap level %d TSTATE[%016lx] TPC[%016lx] " >> 64 "TNPC[%016lx] TT[%lx]\n", >> 65 i + 1, >> 66 p->trapstack[i].tstate, p->trapstack[i].tpc, >> 67 p->trapstack[i].tnpc, p->trapstack[i].tt); >> 68 } 30 } 69 } 31 70 32 /* !! 71 void bad_trap (struct pt_regs *regs, long lvl) 33 * Helper called for bulk of exceptions NOT ne !! 72 { 34 * -for user faults enqueues requested signal !! 73 char buffer[32]; 35 * -for kernel, chk if due to copy_(to|from)_ !! 74 siginfo_t info; >> 75 >> 76 if (lvl < 0x100) { >> 77 sprintf(buffer, "Bad hw trap %lx at tl0\n", lvl); >> 78 die_if_kernel(buffer, regs); >> 79 } >> 80 >> 81 lvl -= 0x100; >> 82 if (regs->tstate & TSTATE_PRIV) { >> 83 sprintf(buffer, "Kernel bad sw trap %lx", lvl); >> 84 die_if_kernel (buffer, regs); >> 85 } >> 86 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { >> 87 regs->tpc &= 0xffffffff; >> 88 regs->tnpc &= 0xffffffff; >> 89 } >> 90 info.si_signo = SIGILL; >> 91 info.si_errno = 0; >> 92 info.si_code = ILL_ILLTRP; >> 93 info.si_addr = (void *)regs->tpc; >> 94 info.si_trapno = lvl; >> 95 force_sig_info(SIGILL, &info, current); >> 96 } >> 97 >> 98 void bad_trap_tl1 (struct pt_regs *regs, long lvl) >> 99 { >> 100 char buffer[32]; >> 101 >> 102 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 103 >> 104 sprintf (buffer, "Bad trap %lx at tl>0", lvl); >> 105 die_if_kernel (buffer, regs); >> 106 } >> 107 >> 108 #ifdef CONFIG_DEBUG_BUGVERBOSE >> 109 void do_BUG(const char *file, int line) >> 110 { >> 111 bust_spinlocks(1); >> 112 printk("kernel BUG at %s:%d!\n", file, line); >> 113 } >> 114 #endif >> 115 >> 116 void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) >> 117 { >> 118 siginfo_t info; >> 119 >> 120 if (regs->tstate & TSTATE_PRIV) { >> 121 printk("spitfire_insn_access_exception: SFSR[%016lx] " >> 122 "SFAR[%016lx], going.\n", sfsr, sfar); >> 123 die_if_kernel("Iax", regs); >> 124 } >> 125 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { >> 126 regs->tpc &= 0xffffffff; >> 127 regs->tnpc &= 0xffffffff; >> 128 } >> 129 info.si_signo = SIGSEGV; >> 130 info.si_errno = 0; >> 131 info.si_code = SEGV_MAPERR; >> 132 info.si_addr = (void *)regs->tpc; >> 133 info.si_trapno = 0; >> 134 force_sig_info(SIGSEGV, &info, current); >> 135 } >> 136 >> 137 void spitfire_insn_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) >> 138 { >> 139 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 140 spitfire_insn_access_exception(regs, sfsr, sfar); >> 141 } >> 142 >> 143 void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) >> 144 { >> 145 siginfo_t info; >> 146 >> 147 if (regs->tstate & TSTATE_PRIV) { >> 148 /* Test if this comes from uaccess places. */ >> 149 unsigned long fixup, g2; >> 150 >> 151 g2 = regs->u_regs[UREG_G2]; >> 152 if ((fixup = search_exception_table (regs->tpc, &g2))) { >> 153 /* Ouch, somebody is trying ugly VM hole tricks on us... */ >> 154 #ifdef DEBUG_EXCEPTIONS >> 155 printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs->tpc); >> 156 printk("EX_TABLE: insn<%016lx> fixup<%016lx> " >> 157 "g2<%016lx>\n", regs->tpc, fixup, g2); >> 158 #endif >> 159 regs->tpc = fixup; >> 160 regs->tnpc = regs->tpc + 4; >> 161 regs->u_regs[UREG_G2] = g2; >> 162 return; >> 163 } >> 164 /* Shit... */ >> 165 printk("spitfire_data_access_exception: SFSR[%016lx] " >> 166 "SFAR[%016lx], going.\n", sfsr, sfar); >> 167 die_if_kernel("Dax", regs); >> 168 } >> 169 >> 170 info.si_signo = SIGSEGV; >> 171 info.si_errno = 0; >> 172 info.si_code = SEGV_MAPERR; >> 173 info.si_addr = (void *)sfar; >> 174 info.si_trapno = 0; >> 175 force_sig_info(SIGSEGV, &info, current); >> 176 } >> 177 >> 178 void spitfire_data_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) >> 179 { >> 180 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 181 spitfire_data_access_exception(regs, sfsr, sfar); >> 182 } >> 183 >> 184 #ifdef CONFIG_PCI >> 185 /* This is really pathetic... */ >> 186 extern volatile int pci_poke_in_progress; >> 187 extern volatile int pci_poke_cpu; >> 188 extern volatile int pci_poke_faulted; >> 189 #endif >> 190 >> 191 /* When access exceptions happen, we must do this. */ >> 192 static void spitfire_clean_and_reenable_l1_caches(void) >> 193 { >> 194 unsigned long va; >> 195 >> 196 if (tlb_type != spitfire) >> 197 BUG(); >> 198 >> 199 /* Clean 'em. */ >> 200 for (va = 0; va < (PAGE_SIZE << 1); va += 32) { >> 201 spitfire_put_icache_tag(va, 0x0); >> 202 spitfire_put_dcache_tag(va, 0x0); >> 203 } >> 204 >> 205 /* Re-enable in LSU. */ >> 206 __asm__ __volatile__("flush %%g6\n\t" >> 207 "membar #Sync\n\t" >> 208 "stxa %0, [%%g0] %1\n\t" >> 209 "membar #Sync" >> 210 : /* no outputs */ >> 211 : "r" (LSU_CONTROL_IC | LSU_CONTROL_DC | >> 212 LSU_CONTROL_IM | LSU_CONTROL_DM), >> 213 "i" (ASI_LSU_CONTROL) >> 214 : "memory"); >> 215 } >> 216 >> 217 static void spitfire_enable_estate_errors(void) >> 218 { >> 219 __asm__ __volatile__("stxa %0, [%%g0] %1\n\t" >> 220 "membar #Sync" >> 221 : /* no outputs */ >> 222 : "r" (ESTATE_ERR_ALL), >> 223 "i" (ASI_ESTATE_ERROR_EN)); >> 224 } >> 225 >> 226 static char ecc_syndrome_table[] = { >> 227 0x4c, 0x40, 0x41, 0x48, 0x42, 0x48, 0x48, 0x49, >> 228 0x43, 0x48, 0x48, 0x49, 0x48, 0x49, 0x49, 0x4a, >> 229 0x44, 0x48, 0x48, 0x20, 0x48, 0x39, 0x4b, 0x48, >> 230 0x48, 0x25, 0x31, 0x48, 0x28, 0x48, 0x48, 0x2c, >> 231 0x45, 0x48, 0x48, 0x21, 0x48, 0x3d, 0x04, 0x48, >> 232 0x48, 0x4b, 0x35, 0x48, 0x2d, 0x48, 0x48, 0x29, >> 233 0x48, 0x00, 0x01, 0x48, 0x0a, 0x48, 0x48, 0x4b, >> 234 0x0f, 0x48, 0x48, 0x4b, 0x48, 0x49, 0x49, 0x48, >> 235 0x46, 0x48, 0x48, 0x2a, 0x48, 0x3b, 0x27, 0x48, >> 236 0x48, 0x4b, 0x33, 0x48, 0x22, 0x48, 0x48, 0x2e, >> 237 0x48, 0x19, 0x1d, 0x48, 0x1b, 0x4a, 0x48, 0x4b, >> 238 0x1f, 0x48, 0x4a, 0x4b, 0x48, 0x4b, 0x4b, 0x48, >> 239 0x48, 0x4b, 0x24, 0x48, 0x07, 0x48, 0x48, 0x36, >> 240 0x4b, 0x48, 0x48, 0x3e, 0x48, 0x30, 0x38, 0x48, >> 241 0x49, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x16, 0x48, >> 242 0x48, 0x12, 0x4b, 0x48, 0x49, 0x48, 0x48, 0x4b, >> 243 0x47, 0x48, 0x48, 0x2f, 0x48, 0x3f, 0x4b, 0x48, >> 244 0x48, 0x06, 0x37, 0x48, 0x23, 0x48, 0x48, 0x2b, >> 245 0x48, 0x05, 0x4b, 0x48, 0x4b, 0x48, 0x48, 0x32, >> 246 0x26, 0x48, 0x48, 0x3a, 0x48, 0x34, 0x3c, 0x48, >> 247 0x48, 0x11, 0x15, 0x48, 0x13, 0x4a, 0x48, 0x4b, >> 248 0x17, 0x48, 0x4a, 0x4b, 0x48, 0x4b, 0x4b, 0x48, >> 249 0x49, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x1e, 0x48, >> 250 0x48, 0x1a, 0x4b, 0x48, 0x49, 0x48, 0x48, 0x4b, >> 251 0x48, 0x08, 0x0d, 0x48, 0x02, 0x48, 0x48, 0x49, >> 252 0x03, 0x48, 0x48, 0x49, 0x48, 0x4b, 0x4b, 0x48, >> 253 0x49, 0x48, 0x48, 0x49, 0x48, 0x4b, 0x10, 0x48, >> 254 0x48, 0x14, 0x4b, 0x48, 0x4b, 0x48, 0x48, 0x4b, >> 255 0x49, 0x48, 0x48, 0x49, 0x48, 0x4b, 0x18, 0x48, >> 256 0x48, 0x1c, 0x4b, 0x48, 0x4b, 0x48, 0x48, 0x4b, >> 257 0x4a, 0x0c, 0x09, 0x48, 0x0e, 0x48, 0x48, 0x4b, >> 258 0x0b, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x4b, 0x4a >> 259 }; >> 260 >> 261 static char *syndrome_unknown = "<Unknown>"; >> 262 >> 263 static void spitfire_log_udb_syndrome(unsigned long afar, unsigned long udbh, unsigned long udbl, unsigned long bit) >> 264 { >> 265 unsigned short scode; >> 266 char memmod_str[64], *p; >> 267 >> 268 if (udbl & bit) { >> 269 scode = ecc_syndrome_table[udbl & 0xff]; >> 270 if (prom_getunumber(scode, afar, >> 271 memmod_str, sizeof(memmod_str)) == -1) >> 272 p = syndrome_unknown; >> 273 else >> 274 p = memmod_str; >> 275 printk(KERN_WARNING "CPU[%d]: UDBL Syndrome[%x] " >> 276 "Memory Module \"%s\"\n", >> 277 smp_processor_id(), scode, p); >> 278 } >> 279 >> 280 if (udbh & bit) { >> 281 scode = ecc_syndrome_table[udbh & 0xff]; >> 282 if (prom_getunumber(scode, afar, >> 283 memmod_str, sizeof(memmod_str)) == -1) >> 284 p = syndrome_unknown; >> 285 else >> 286 p = memmod_str; >> 287 printk(KERN_WARNING "CPU[%d]: UDBH Syndrome[%x] " >> 288 "Memory Module \"%s\"\n", >> 289 smp_processor_id(), scode, p); >> 290 } >> 291 >> 292 } >> 293 >> 294 static void spitfire_cee_log(unsigned long afsr, unsigned long afar, unsigned long udbh, unsigned long udbl, int tl1, struct pt_regs *regs) >> 295 { >> 296 >> 297 printk(KERN_WARNING "CPU[%d]: Correctable ECC Error " >> 298 "AFSR[%lx] AFAR[%016lx] UDBL[%lx] UDBH[%lx] TL>1[%d]\n", >> 299 smp_processor_id(), afsr, afar, udbl, udbh, tl1); >> 300 >> 301 spitfire_log_udb_syndrome(afar, udbh, udbl, UDBE_CE); >> 302 >> 303 /* The Correctable ECC Error trap does not disable I/D caches. So >> 304 * we only have to restore the ESTATE Error Enable register. >> 305 */ >> 306 spitfire_enable_estate_errors(); >> 307 } >> 308 >> 309 static void spitfire_ue_log(unsigned long afsr, unsigned long afar, unsigned long udbh, unsigned long udbl, unsigned long tt, int tl1, struct pt_regs *regs) >> 310 { >> 311 siginfo_t info; >> 312 >> 313 printk(KERN_WARNING "CPU[%d]: Uncorrectable Error AFSR[%lx] " >> 314 "AFAR[%lx] UDBL[%lx] UDBH[%ld] TT[%lx] TL>1[%d]\n", >> 315 smp_processor_id(), afsr, afar, udbl, udbh, tt, tl1); >> 316 >> 317 /* XXX add more human friendly logging of the error status >> 318 * XXX as is implemented for cheetah >> 319 */ >> 320 >> 321 spitfire_log_udb_syndrome(afar, udbh, udbl, UDBE_UE); >> 322 >> 323 if (regs->tstate & TSTATE_PRIV) { >> 324 if (tl1) >> 325 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 326 die_if_kernel("UE", regs); >> 327 } >> 328 >> 329 /* XXX need more intelligent processing here, such as is implemented >> 330 * XXX for cheetah errors, in fact if the E-cache still holds the >> 331 * XXX line with bad parity this will loop >> 332 */ >> 333 >> 334 spitfire_clean_and_reenable_l1_caches(); >> 335 spitfire_enable_estate_errors(); >> 336 >> 337 if (current->thread.flags & SPARC_FLAG_32BIT) { >> 338 regs->tpc &= 0xffffffff; >> 339 regs->tnpc &= 0xffffffff; >> 340 } >> 341 info.si_signo = SIGBUS; >> 342 info.si_errno = 0; >> 343 info.si_code = BUS_OBJERR; >> 344 info.si_addr = (void *)0; >> 345 info.si_trapno = 0; >> 346 force_sig_info(SIGBUS, &info, current); >> 347 } >> 348 >> 349 void spitfire_access_error(struct pt_regs *regs, unsigned long status_encoded, unsigned long afar) >> 350 { >> 351 unsigned long afsr, tt, udbh, udbl; >> 352 int tl1; >> 353 >> 354 afsr = (status_encoded & SFSTAT_AFSR_MASK) >> SFSTAT_AFSR_SHIFT; >> 355 tt = (status_encoded & SFSTAT_TRAP_TYPE) >> SFSTAT_TRAP_TYPE_SHIFT; >> 356 tl1 = (status_encoded & SFSTAT_TL_GT_ONE) ? 1 : 0; >> 357 udbl = (status_encoded & SFSTAT_UDBL_MASK) >> SFSTAT_UDBL_SHIFT; >> 358 udbh = (status_encoded & SFSTAT_UDBH_MASK) >> SFSTAT_UDBH_SHIFT; >> 359 >> 360 #ifdef CONFIG_PCI >> 361 if (tt == TRAP_TYPE_DAE && >> 362 pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) { >> 363 spitfire_clean_and_reenable_l1_caches(); >> 364 spitfire_enable_estate_errors(); >> 365 >> 366 pci_poke_faulted = 1; >> 367 regs->tnpc = regs->tpc + 4; >> 368 return; >> 369 } >> 370 #endif >> 371 >> 372 if (afsr & SFAFSR_UE) >> 373 spitfire_ue_log(afsr, afar, udbh, udbl, tt, tl1, regs); >> 374 >> 375 if (tt == TRAP_TYPE_CEE) { >> 376 /* Handle the case where we took a CEE trap, but ACK'd >> 377 * only the UE state in the UDB error registers. >> 378 */ >> 379 if (afsr & SFAFSR_UE) { >> 380 if (udbh & UDBE_CE) { >> 381 __asm__ __volatile__( >> 382 "stxa %0, [%1] %2\n\t" >> 383 "membar #Sync" >> 384 : /* no outputs */ >> 385 : "r" (udbh & UDBE_CE), >> 386 "r" (0x0), "i" (ASI_UDB_ERROR_W)); >> 387 } >> 388 if (udbl & UDBE_CE) { >> 389 __asm__ __volatile__( >> 390 "stxa %0, [%1] %2\n\t" >> 391 "membar #Sync" >> 392 : /* no outputs */ >> 393 : "r" (udbl & UDBE_CE), >> 394 "r" (0x18), "i" (ASI_UDB_ERROR_W)); >> 395 } >> 396 } >> 397 >> 398 spitfire_cee_log(afsr, afar, udbh, udbl, tl1, regs); >> 399 } >> 400 } >> 401 >> 402 /* Cheetah error trap handling. */ >> 403 static unsigned long ecache_flush_physbase; >> 404 static unsigned long ecache_flush_linesize; >> 405 static unsigned long ecache_flush_size; >> 406 >> 407 /* WARNING: The error trap handlers in assembly know the precise >> 408 * layout of the following structure. >> 409 * >> 410 * C-level handlers below use this information to log the error >> 411 * and then determine how to recover (if possible). >> 412 */ >> 413 struct cheetah_err_info { >> 414 /*0x00*/u64 afsr; >> 415 /*0x08*/u64 afar; >> 416 >> 417 /* D-cache state */ >> 418 /*0x10*/u64 dcache_data[4]; /* The actual data */ >> 419 /*0x30*/u64 dcache_index; /* D-cache index */ >> 420 /*0x38*/u64 dcache_tag; /* D-cache tag/valid */ >> 421 /*0x40*/u64 dcache_utag; /* D-cache microtag */ >> 422 /*0x48*/u64 dcache_stag; /* D-cache snooptag */ >> 423 >> 424 /* I-cache state */ >> 425 /*0x50*/u64 icache_data[8]; /* The actual insns + predecode */ >> 426 /*0x90*/u64 icache_index; /* I-cache index */ >> 427 /*0x98*/u64 icache_tag; /* I-cache phys tag */ >> 428 /*0xa0*/u64 icache_utag; /* I-cache microtag */ >> 429 /*0xa8*/u64 icache_stag; /* I-cache snooptag */ >> 430 /*0xb0*/u64 icache_upper; /* I-cache upper-tag */ >> 431 /*0xb8*/u64 icache_lower; /* I-cache lower-tag */ >> 432 >> 433 /* E-cache state */ >> 434 /*0xc0*/u64 ecache_data[4]; /* 32 bytes from staging registers */ >> 435 /*0xe0*/u64 ecache_index; /* E-cache index */ >> 436 /*0xe8*/u64 ecache_tag; /* E-cache tag/state */ >> 437 >> 438 /*0xf0*/u64 __pad[32 - 30]; >> 439 }; >> 440 #define CHAFSR_INVALID ((u64)-1L) >> 441 >> 442 /* This table is ordered in priority of errors and matches the >> 443 * AFAR overwrite policy as well. 36 */ 444 */ 37 static noinline int !! 445 38 unhandled_exception(const char *str, struct pt !! 446 struct afsr_error_table { 39 int signo, int si_code, vo !! 447 unsigned long mask; >> 448 const char *name; >> 449 }; >> 450 >> 451 static const char CHAFSR_PERR_msg[] = >> 452 "System interface protocol error"; >> 453 static const char CHAFSR_IERR_msg[] = >> 454 "Internal processor error"; >> 455 static const char CHAFSR_ISAP_msg[] = >> 456 "System request parity error on incoming addresss"; >> 457 static const char CHAFSR_UCU_msg[] = >> 458 "Uncorrectable E-cache ECC error for ifetch/data"; >> 459 static const char CHAFSR_UCC_msg[] = >> 460 "SW Correctable E-cache ECC error for ifetch/data"; >> 461 static const char CHAFSR_UE_msg[] = >> 462 "Uncorrectable system bus data ECC error for read"; >> 463 static const char CHAFSR_EDU_msg[] = >> 464 "Uncorrectable E-cache ECC error for stmerge/blkld"; >> 465 static const char CHAFSR_EMU_msg[] = >> 466 "Uncorrectable system bus MTAG error"; >> 467 static const char CHAFSR_WDU_msg[] = >> 468 "Uncorrectable E-cache ECC error for writeback"; >> 469 static const char CHAFSR_CPU_msg[] = >> 470 "Uncorrectable ECC error for copyout"; >> 471 static const char CHAFSR_CE_msg[] = >> 472 "HW corrected system bus data ECC error for read"; >> 473 static const char CHAFSR_EDC_msg[] = >> 474 "HW corrected E-cache ECC error for stmerge/blkld"; >> 475 static const char CHAFSR_EMC_msg[] = >> 476 "HW corrected system bus MTAG ECC error"; >> 477 static const char CHAFSR_WDC_msg[] = >> 478 "HW corrected E-cache ECC error for writeback"; >> 479 static const char CHAFSR_CPC_msg[] = >> 480 "HW corrected ECC error for copyout"; >> 481 static const char CHAFSR_TO_msg[] = >> 482 "Unmapped error from system bus"; >> 483 static const char CHAFSR_BERR_msg[] = >> 484 "Bus error response from system bus"; >> 485 static const char CHAFSR_IVC_msg[] = >> 486 "HW corrected system bus data ECC error for ivec read"; >> 487 static const char CHAFSR_IVU_msg[] = >> 488 "Uncorrectable system bus data ECC error for ivec read"; >> 489 static struct afsr_error_table __cheetah_error_table[] = { >> 490 { CHAFSR_PERR, CHAFSR_PERR_msg }, >> 491 { CHAFSR_IERR, CHAFSR_IERR_msg }, >> 492 { CHAFSR_ISAP, CHAFSR_ISAP_msg }, >> 493 { CHAFSR_UCU, CHAFSR_UCU_msg }, >> 494 { CHAFSR_UCC, CHAFSR_UCC_msg }, >> 495 { CHAFSR_UE, CHAFSR_UE_msg }, >> 496 { CHAFSR_EDU, CHAFSR_EDU_msg }, >> 497 { CHAFSR_EMU, CHAFSR_EMU_msg }, >> 498 { CHAFSR_WDU, CHAFSR_WDU_msg }, >> 499 { CHAFSR_CPU, CHAFSR_CPU_msg }, >> 500 { CHAFSR_CE, CHAFSR_CE_msg }, >> 501 { CHAFSR_EDC, CHAFSR_EDC_msg }, >> 502 { CHAFSR_EMC, CHAFSR_EMC_msg }, >> 503 { CHAFSR_WDC, CHAFSR_WDC_msg }, >> 504 { CHAFSR_CPC, CHAFSR_CPC_msg }, >> 505 { CHAFSR_TO, CHAFSR_TO_msg }, >> 506 { CHAFSR_BERR, CHAFSR_BERR_msg }, >> 507 /* These two do not update the AFAR. */ >> 508 { CHAFSR_IVC, CHAFSR_IVC_msg }, >> 509 { CHAFSR_IVU, CHAFSR_IVU_msg }, >> 510 { 0, NULL }, >> 511 }; >> 512 static const char CHPAFSR_DTO_msg[] = >> 513 "System bus unmapped error for prefetch/storequeue-read"; >> 514 static const char CHPAFSR_DBERR_msg[] = >> 515 "System bus error for prefetch/storequeue-read"; >> 516 static const char CHPAFSR_THCE_msg[] = >> 517 "Hardware corrected E-cache Tag ECC error"; >> 518 static const char CHPAFSR_TSCE_msg[] = >> 519 "SW handled correctable E-cache Tag ECC error"; >> 520 static const char CHPAFSR_TUE_msg[] = >> 521 "Uncorrectable E-cache Tag ECC error"; >> 522 static const char CHPAFSR_DUE_msg[] = >> 523 "System bus uncorrectable data ECC error due to prefetch/store-fill"; >> 524 static struct afsr_error_table __cheetah_plus_error_table[] = { >> 525 { CHAFSR_PERR, CHAFSR_PERR_msg }, >> 526 { CHAFSR_IERR, CHAFSR_IERR_msg }, >> 527 { CHAFSR_ISAP, CHAFSR_ISAP_msg }, >> 528 { CHAFSR_UCU, CHAFSR_UCU_msg }, >> 529 { CHAFSR_UCC, CHAFSR_UCC_msg }, >> 530 { CHAFSR_UE, CHAFSR_UE_msg }, >> 531 { CHAFSR_EDU, CHAFSR_EDU_msg }, >> 532 { CHAFSR_EMU, CHAFSR_EMU_msg }, >> 533 { CHAFSR_WDU, CHAFSR_WDU_msg }, >> 534 { CHAFSR_CPU, CHAFSR_CPU_msg }, >> 535 { CHAFSR_CE, CHAFSR_CE_msg }, >> 536 { CHAFSR_EDC, CHAFSR_EDC_msg }, >> 537 { CHAFSR_EMC, CHAFSR_EMC_msg }, >> 538 { CHAFSR_WDC, CHAFSR_WDC_msg }, >> 539 { CHAFSR_CPC, CHAFSR_CPC_msg }, >> 540 { CHAFSR_TO, CHAFSR_TO_msg }, >> 541 { CHAFSR_BERR, CHAFSR_BERR_msg }, >> 542 { CHPAFSR_DTO, CHPAFSR_DTO_msg }, >> 543 { CHPAFSR_DBERR, CHPAFSR_DBERR_msg }, >> 544 { CHPAFSR_THCE, CHPAFSR_THCE_msg }, >> 545 { CHPAFSR_TSCE, CHPAFSR_TSCE_msg }, >> 546 { CHPAFSR_TUE, CHPAFSR_TUE_msg }, >> 547 { CHPAFSR_DUE, CHPAFSR_DUE_msg }, >> 548 /* These two do not update the AFAR. */ >> 549 { CHAFSR_IVC, CHAFSR_IVC_msg }, >> 550 { CHAFSR_IVU, CHAFSR_IVU_msg }, >> 551 { 0, NULL }, >> 552 }; >> 553 static const char JPAFSR_JETO_msg[] = >> 554 "System interface protocol error, hw timeout caused"; >> 555 static const char JPAFSR_SCE_msg[] = >> 556 "Parity error on system snoop results"; >> 557 static const char JPAFSR_JEIC_msg[] = >> 558 "System interface protocol error, illegal command detected"; >> 559 static const char JPAFSR_JEIT_msg[] = >> 560 "System interface protocol error, illegal ADTYPE detected"; >> 561 static const char JPAFSR_OM_msg[] = >> 562 "Out of range memory error has occurred"; >> 563 static const char JPAFSR_ETP_msg[] = >> 564 "Parity error on L2 cache tag SRAM"; >> 565 static const char JPAFSR_UMS_msg[] = >> 566 "Error due to unsupported store"; >> 567 static const char JPAFSR_RUE_msg[] = >> 568 "Uncorrectable ECC error from remote cache/memory"; >> 569 static const char JPAFSR_RCE_msg[] = >> 570 "Correctable ECC error from remote cache/memory"; >> 571 static const char JPAFSR_BP_msg[] = >> 572 "JBUS parity error on returned read data"; >> 573 static const char JPAFSR_WBP_msg[] = >> 574 "JBUS parity error on data for writeback or block store"; >> 575 static const char JPAFSR_FRC_msg[] = >> 576 "Foreign read to DRAM incurring correctable ECC error"; >> 577 static const char JPAFSR_FRU_msg[] = >> 578 "Foreign read to DRAM incurring uncorrectable ECC error"; >> 579 static struct afsr_error_table __jalapeno_error_table[] = { >> 580 { JPAFSR_JETO, JPAFSR_JETO_msg }, >> 581 { JPAFSR_SCE, JPAFSR_SCE_msg }, >> 582 { JPAFSR_JEIC, JPAFSR_JEIC_msg }, >> 583 { JPAFSR_JEIT, JPAFSR_JEIT_msg }, >> 584 { CHAFSR_PERR, CHAFSR_PERR_msg }, >> 585 { CHAFSR_IERR, CHAFSR_IERR_msg }, >> 586 { CHAFSR_ISAP, CHAFSR_ISAP_msg }, >> 587 { CHAFSR_UCU, CHAFSR_UCU_msg }, >> 588 { CHAFSR_UCC, CHAFSR_UCC_msg }, >> 589 { CHAFSR_UE, CHAFSR_UE_msg }, >> 590 { CHAFSR_EDU, CHAFSR_EDU_msg }, >> 591 { JPAFSR_OM, JPAFSR_OM_msg }, >> 592 { CHAFSR_WDU, CHAFSR_WDU_msg }, >> 593 { CHAFSR_CPU, CHAFSR_CPU_msg }, >> 594 { CHAFSR_CE, CHAFSR_CE_msg }, >> 595 { CHAFSR_EDC, CHAFSR_EDC_msg }, >> 596 { JPAFSR_ETP, JPAFSR_ETP_msg }, >> 597 { CHAFSR_WDC, CHAFSR_WDC_msg }, >> 598 { CHAFSR_CPC, CHAFSR_CPC_msg }, >> 599 { CHAFSR_TO, CHAFSR_TO_msg }, >> 600 { CHAFSR_BERR, CHAFSR_BERR_msg }, >> 601 { JPAFSR_UMS, JPAFSR_UMS_msg }, >> 602 { JPAFSR_RUE, JPAFSR_RUE_msg }, >> 603 { JPAFSR_RCE, JPAFSR_RCE_msg }, >> 604 { JPAFSR_BP, JPAFSR_BP_msg }, >> 605 { JPAFSR_WBP, JPAFSR_WBP_msg }, >> 606 { JPAFSR_FRC, JPAFSR_FRC_msg }, >> 607 { JPAFSR_FRU, JPAFSR_FRU_msg }, >> 608 /* These two do not update the AFAR. */ >> 609 { CHAFSR_IVU, CHAFSR_IVU_msg }, >> 610 { 0, NULL }, >> 611 }; >> 612 static struct afsr_error_table *cheetah_error_table; >> 613 static unsigned long cheetah_afsr_errors; >> 614 >> 615 /* This is allocated at boot time based upon the largest hardware >> 616 * cpu ID in the system. We allocate two entries per cpu, one for >> 617 * TL==0 logging and one for TL >= 1 logging. >> 618 */ >> 619 struct cheetah_err_info *cheetah_error_log; >> 620 >> 621 static __inline__ struct cheetah_err_info *cheetah_get_error_log(unsigned long afsr) >> 622 { >> 623 struct cheetah_err_info *p; >> 624 int cpu = smp_processor_id(); >> 625 >> 626 if (!cheetah_error_log) >> 627 return NULL; >> 628 >> 629 p = cheetah_error_log + (cpu * 2); >> 630 if ((afsr & CHAFSR_TL1) != 0UL) >> 631 p++; >> 632 >> 633 return p; >> 634 } >> 635 >> 636 extern unsigned int tl0_icpe[], tl1_icpe[]; >> 637 extern unsigned int tl0_dcpe[], tl1_dcpe[]; >> 638 extern unsigned int tl0_fecc[], tl1_fecc[]; >> 639 extern unsigned int tl0_cee[], tl1_cee[]; >> 640 extern unsigned int tl0_iae[], tl1_iae[]; >> 641 extern unsigned int tl0_dae[], tl1_dae[]; >> 642 extern unsigned int cheetah_plus_icpe_trap_vector[], cheetah_plus_icpe_trap_vector_tl1[]; >> 643 extern unsigned int cheetah_plus_dcpe_trap_vector[], cheetah_plus_dcpe_trap_vector_tl1[]; >> 644 extern unsigned int cheetah_fecc_trap_vector[], cheetah_fecc_trap_vector_tl1[]; >> 645 extern unsigned int cheetah_cee_trap_vector[], cheetah_cee_trap_vector_tl1[]; >> 646 extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector_tl1[]; >> 647 >> 648 void cheetah_ecache_flush_init(void) 40 { 649 { 41 if (user_mode(regs)) { !! 650 unsigned long largest_size, smallest_linesize, order, ver; 42 struct task_struct *tsk = curr !! 651 char type[16]; >> 652 int node, highest_cpu, i; >> 653 >> 654 /* Scan all cpu device tree nodes, note two values: >> 655 * 1) largest E-cache size >> 656 * 2) smallest E-cache line size >> 657 */ >> 658 largest_size = 0UL; >> 659 smallest_linesize = ~0UL; >> 660 node = prom_getchild(prom_root_node); >> 661 while ((node = prom_getsibling(node)) != 0) { >> 662 prom_getstring(node, "device_type", type, sizeof(type)); >> 663 if (!strcmp(type, "cpu")) { >> 664 unsigned long val; >> 665 >> 666 val = prom_getintdefault(node, "ecache-size", >> 667 (2 * 1024 * 1024)); >> 668 if (val > largest_size) >> 669 largest_size = val; >> 670 val = prom_getintdefault(node, "ecache-line-size", 64); >> 671 if (val < smallest_linesize) >> 672 smallest_linesize = val; >> 673 } >> 674 } >> 675 if (largest_size == 0UL || smallest_linesize == ~0UL) { >> 676 prom_printf("cheetah_ecache_flush_init: Cannot probe cpu E-cache " >> 677 "parameters.\n"); >> 678 prom_halt(); >> 679 } >> 680 >> 681 ecache_flush_size = (2 * largest_size); >> 682 ecache_flush_linesize = smallest_linesize; 43 683 44 tsk->thread.fault_address = (_ !! 684 /* Discover a physically contiguous chunk of physical >> 685 * memory in 'sp_banks' of size ecache_flush_size calculated >> 686 * above. Store the physical base of this area at >> 687 * ecache_flush_physbase. >> 688 */ >> 689 for (node = 0; ; node++) { >> 690 if (sp_banks[node].num_bytes == 0) >> 691 break; >> 692 if (sp_banks[node].num_bytes >= ecache_flush_size) { >> 693 ecache_flush_physbase = sp_banks[node].base_addr; >> 694 break; >> 695 } >> 696 } 45 697 46 force_sig_fault(signo, si_code !! 698 /* Note: Zero would be a valid value of ecache_flush_physbase so >> 699 * don't use that as the success test. :-) >> 700 */ >> 701 if (sp_banks[node].num_bytes == 0) { >> 702 prom_printf("cheetah_ecache_flush_init: Cannot find %d byte " >> 703 "contiguous physical memory.\n", ecache_flush_size); >> 704 prom_halt(); >> 705 } >> 706 >> 707 /* Now allocate error trap reporting scoreboard. */ >> 708 highest_cpu = 0; >> 709 #ifdef CONFIG_SMP >> 710 for (i = 0; i < NR_CPUS; i++) { >> 711 if ((1UL << i) & cpu_present_map) >> 712 highest_cpu = i; >> 713 } >> 714 #endif >> 715 highest_cpu++; >> 716 node = highest_cpu * (2 * sizeof(struct cheetah_err_info)); >> 717 for (order = 0; order < MAX_ORDER; order++) { >> 718 if ((PAGE_SIZE << order) >= node) >> 719 break; >> 720 } >> 721 cheetah_error_log = (struct cheetah_err_info *) >> 722 __get_free_pages(GFP_KERNEL, order); >> 723 if (!cheetah_error_log) { >> 724 prom_printf("cheetah_ecache_flush_init: Failed to allocate " >> 725 "error logging scoreboard (%d bytes).\n", node); >> 726 prom_halt(); >> 727 } >> 728 memset(cheetah_error_log, 0, PAGE_SIZE << order); 47 729 >> 730 /* Mark all AFSRs as invalid so that the trap handler will >> 731 * log new new information there. >> 732 */ >> 733 for (i = 0; i < 2 * highest_cpu; i++) >> 734 cheetah_error_log[i].afsr = CHAFSR_INVALID; >> 735 >> 736 __asm__ ("rdpr %%ver, %0" : "=r" (ver)); >> 737 if ((ver >> 32) == 0x003e0016) { >> 738 cheetah_error_table = &__jalapeno_error_table[0]; >> 739 cheetah_afsr_errors = JPAFSR_ERRORS; >> 740 } else if ((ver >> 32) == 0x003e0015) { >> 741 cheetah_error_table = &__cheetah_plus_error_table[0]; >> 742 cheetah_afsr_errors = CHPAFSR_ERRORS; 48 } else { 743 } else { 49 /* If not due to copy_(to|from !! 744 cheetah_error_table = &__cheetah_error_table[0]; 50 if (fixup_exception(regs)) !! 745 cheetah_afsr_errors = CHAFSR_ERRORS; 51 return 0; !! 746 } 52 747 53 die(str, regs, (unsigned long) !! 748 /* Now patch trap tables. */ >> 749 memcpy(tl0_fecc, cheetah_fecc_trap_vector, (8 * 4)); >> 750 memcpy(tl1_fecc, cheetah_fecc_trap_vector_tl1, (8 * 4)); >> 751 memcpy(tl0_cee, cheetah_cee_trap_vector, (8 * 4)); >> 752 memcpy(tl1_cee, cheetah_cee_trap_vector_tl1, (8 * 4)); >> 753 memcpy(tl0_iae, cheetah_deferred_trap_vector, (8 * 4)); >> 754 memcpy(tl1_iae, cheetah_deferred_trap_vector_tl1, (8 * 4)); >> 755 memcpy(tl0_dae, cheetah_deferred_trap_vector, (8 * 4)); >> 756 memcpy(tl1_dae, cheetah_deferred_trap_vector_tl1, (8 * 4)); >> 757 if (tlb_type == cheetah_plus) { >> 758 memcpy(tl0_dcpe, cheetah_plus_dcpe_trap_vector, (8 * 4)); >> 759 memcpy(tl1_dcpe, cheetah_plus_dcpe_trap_vector_tl1, (8 * 4)); >> 760 memcpy(tl0_icpe, cheetah_plus_icpe_trap_vector, (8 * 4)); >> 761 memcpy(tl1_icpe, cheetah_plus_icpe_trap_vector_tl1, (8 * 4)); 54 } 762 } >> 763 flushi(PAGE_OFFSET); >> 764 } 55 765 56 return 1; !! 766 static void cheetah_flush_ecache(void) >> 767 { >> 768 unsigned long flush_base = ecache_flush_physbase; >> 769 unsigned long flush_linesize = ecache_flush_linesize; >> 770 unsigned long flush_size = ecache_flush_size; >> 771 >> 772 __asm__ __volatile__("1: subcc %0, %4, %0\n\t" >> 773 " bne,pt %%xcc, 1b\n\t" >> 774 " ldxa [%2 + %0] %3, %%g0\n\t" >> 775 : "=&r" (flush_size) >> 776 : "" (flush_size), "r" (flush_base), >> 777 "i" (ASI_PHYS_USE_EC), "r" (flush_linesize)); 57 } 778 } 58 779 59 #define DO_ERROR_INFO(signr, str, name, sicode !! 780 static void cheetah_flush_ecache_line(unsigned long physaddr) 60 int name(unsigned long address, struct pt_regs !! 781 { 61 { !! 782 unsigned long alias; 62 return unhandled_exception(str, regs, !! 783 63 (void __use !! 784 physaddr &= ~(8UL - 1UL); >> 785 physaddr = (ecache_flush_physbase + >> 786 (physaddr & ((ecache_flush_size>>1UL) - 1UL))); >> 787 alias = physaddr + (ecache_flush_size >> 1UL); >> 788 __asm__ __volatile__("ldxa [%0] %2, %%g0\n\t" >> 789 "ldxa [%1] %2, %%g0\n\t" >> 790 "membar #Sync" >> 791 : /* no outputs */ >> 792 : "r" (physaddr), "r" (alias), >> 793 "i" (ASI_PHYS_USE_EC)); 64 } 794 } 65 795 66 /* !! 796 /* Unfortunately, the diagnostic access to the I-cache tags we need to 67 * Entry points for exceptions NOT needing spe !! 797 * use to clear the thing interferes with I-cache coherency transactions. >> 798 * >> 799 * So we must only flush the I-cache when it is disabled. 68 */ 800 */ 69 DO_ERROR_INFO(SIGILL, "Priv Op/Disabled Extn", !! 801 static void __cheetah_flush_icache(void) 70 DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_ !! 802 { 71 DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", !! 803 unsigned long i; 72 DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", __ << 73 DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_ << 74 DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_ << 75 DO_ERROR_INFO(SIGSEGV, "gcc generated __builti << 76 804 77 /* !! 805 /* Clear the valid bits in all the tags. */ 78 * Entry Point for Misaligned Data access Exce !! 806 for (i = 0; i < (1 << 15); i += (1 << 5)) { >> 807 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" >> 808 "membar #Sync" >> 809 : /* no outputs */ >> 810 : "r" (i | (2 << 3)), "i" (ASI_IC_TAG)); >> 811 } >> 812 } >> 813 >> 814 static void cheetah_flush_icache(void) >> 815 { >> 816 unsigned long dcu_save; >> 817 >> 818 /* Save current DCU, disable I-cache. */ >> 819 __asm__ __volatile__("ldxa [%%g0] %1, %0\n\t" >> 820 "or %0, %2, %%g1\n\t" >> 821 "stxa %%g1, [%%g0] %1\n\t" >> 822 "membar #Sync" >> 823 : "=r" (dcu_save) >> 824 : "i" (ASI_DCU_CONTROL_REG), "i" (DCU_IC) >> 825 : "g1"); >> 826 >> 827 __cheetah_flush_icache(); >> 828 >> 829 /* Restore DCU register */ >> 830 __asm__ __volatile__("stxa %0, [%%g0] %1\n\t" >> 831 "membar #Sync" >> 832 : /* no outputs */ >> 833 : "r" (dcu_save), "i" (ASI_DCU_CONTROL_REG)); >> 834 } >> 835 >> 836 static void cheetah_flush_dcache(void) >> 837 { >> 838 unsigned long i; >> 839 >> 840 for (i = 0; i < (1 << 16); i += (1 << 5)) { >> 841 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" >> 842 "membar #Sync" >> 843 : /* no outputs */ >> 844 : "r" (i), "i" (ASI_DCACHE_TAG)); >> 845 } >> 846 } >> 847 >> 848 /* In order to make the even parity correct we must do two things. >> 849 * First, we clear DC_data_parity and set DC_utag to an appropriate value. >> 850 * Next, we clear out all 32-bytes of data for that line. Data of >> 851 * all-zero + tag parity value of zero == correct parity. 79 */ 852 */ 80 int do_misaligned_access(unsigned long address !! 853 static void cheetah_plus_zap_dcache_parity(void) 81 struct callee_regs *c << 82 { 854 { 83 /* If emulation not enabled, or failed !! 855 unsigned long i; 84 if (misaligned_fixup(address, regs, cr << 85 return do_misaligned_error(add << 86 856 87 return 0; !! 857 for (i = 0; i < (1 << 16); i += (1 << 5)) { >> 858 unsigned long tag = (i >> 14); >> 859 unsigned long j; >> 860 >> 861 __asm__ __volatile__("membar #Sync\n\t" >> 862 "stxa %0, [%1] %2\n\t" >> 863 "membar #Sync" >> 864 : /* no outputs */ >> 865 : "r" (tag), "r" (i), >> 866 "i" (ASI_DCACHE_UTAG)); >> 867 for (j = i; j < i + (1 << 5); j += (1 << 3)) >> 868 __asm__ __volatile__("membar #Sync\n\t" >> 869 "stxa %%g0, [%0] %1\n\t" >> 870 "membar #Sync" >> 871 : /* no outputs */ >> 872 : "r" (j), "i" (ASI_DCACHE_DATA)); >> 873 } 88 } 874 } 89 875 90 /* !! 876 /* Conversion tables used to frob Cheetah AFSR syndrome values into 91 * Entry point for miscll errors such as Neste !! 877 * something palatable to the memory controller driver get_unumber 92 * -Duplicate TLB entry is handled separately !! 878 * routine. 93 */ 879 */ 94 void do_machine_check_fault(unsigned long addr !! 880 #define MT0 137 >> 881 #define MT1 138 >> 882 #define MT2 139 >> 883 #define NONE 254 >> 884 #define MTC0 140 >> 885 #define MTC1 141 >> 886 #define MTC2 142 >> 887 #define MTC3 143 >> 888 #define C0 128 >> 889 #define C1 129 >> 890 #define C2 130 >> 891 #define C3 131 >> 892 #define C4 132 >> 893 #define C5 133 >> 894 #define C6 134 >> 895 #define C7 135 >> 896 #define C8 136 >> 897 #define M2 144 >> 898 #define M3 145 >> 899 #define M4 146 >> 900 #define M 147 >> 901 static unsigned char cheetah_ecc_syntab[] = { >> 902 /*00*/NONE, C0, C1, M2, C2, M2, M3, 47, C3, M2, M2, 53, M2, 41, 29, M, >> 903 /*01*/C4, M, M, 50, M2, 38, 25, M2, M2, 33, 24, M2, 11, M, M2, 16, >> 904 /*02*/C5, M, M, 46, M2, 37, 19, M2, M, 31, 32, M, 7, M2, M2, 10, >> 905 /*03*/M2, 40, 13, M2, 59, M, M2, 66, M, M2, M2, 0, M2, 67, 71, M, >> 906 /*04*/C6, M, M, 43, M, 36, 18, M, M2, 49, 15, M, 63, M2, M2, 6, >> 907 /*05*/M2, 44, 28, M2, M, M2, M2, 52, 68, M2, M2, 62, M2, M3, M3, M4, >> 908 /*06*/M2, 26, 106, M2, 64, M, M2, 2, 120, M, M2, M3, M, M3, M3, M4, >> 909 /*07*/116, M2, M2, M3, M2, M3, M, M4, M2, 58, 54, M2, M, M4, M4, M3, >> 910 /*08*/C7, M2, M, 42, M, 35, 17, M2, M, 45, 14, M2, 21, M2, M2, 5, >> 911 /*09*/M, 27, M, M, 99, M, M, 3, 114, M2, M2, 20, M2, M3, M3, M, >> 912 /*0a*/M2, 23, 113, M2, 112, M2, M, 51, 95, M, M2, M3, M2, M3, M3, M2, >> 913 /*0b*/103, M, M2, M3, M2, M3, M3, M4, M2, 48, M, M, 73, M2, M, M3, >> 914 /*0c*/M2, 22, 110, M2, 109, M2, M, 9, 108, M2, M, M3, M2, M3, M3, M, >> 915 /*0d*/102, M2, M, M, M2, M3, M3, M, M2, M3, M3, M2, M, M4, M, M3, >> 916 /*0e*/98, M, M2, M3, M2, M, M3, M4, M2, M3, M3, M4, M3, M, M, M, >> 917 /*0f*/M2, M3, M3, M, M3, M, M, M, 56, M4, M, M3, M4, M, M, M, >> 918 /*10*/C8, M, M2, 39, M, 34, 105, M2, M, 30, 104, M, 101, M, M, 4, >> 919 /*11*/M, M, 100, M, 83, M, M2, 12, 87, M, M, 57, M2, M, M3, M, >> 920 /*12*/M2, 97, 82, M2, 78, M2, M2, 1, 96, M, M, M, M, M, M3, M2, >> 921 /*13*/94, M, M2, M3, M2, M, M3, M, M2, M, 79, M, 69, M, M4, M, >> 922 /*14*/M2, 93, 92, M, 91, M, M2, 8, 90, M2, M2, M, M, M, M, M4, >> 923 /*15*/89, M, M, M3, M2, M3, M3, M, M, M, M3, M2, M3, M2, M, M3, >> 924 /*16*/86, M, M2, M3, M2, M, M3, M, M2, M, M3, M, M3, M, M, M3, >> 925 /*17*/M, M, M3, M2, M3, M2, M4, M, 60, M, M2, M3, M4, M, M, M2, >> 926 /*18*/M2, 88, 85, M2, 84, M, M2, 55, 81, M2, M2, M3, M2, M3, M3, M4, >> 927 /*19*/77, M, M, M, M2, M3, M, M, M2, M3, M3, M4, M3, M2, M, M, >> 928 /*1a*/74, M, M2, M3, M, M, M3, M, M, M, M3, M, M3, M, M4, M3, >> 929 /*1b*/M2, 70, 107, M4, 65, M2, M2, M, 127, M, M, M, M2, M3, M3, M, >> 930 /*1c*/80, M2, M2, 72, M, 119, 118, M, M2, 126, 76, M, 125, M, M4, M3, >> 931 /*1d*/M2, 115, 124, M, 75, M, M, M3, 61, M, M4, M, M4, M, M, M, >> 932 /*1e*/M, 123, 122, M4, 121, M4, M, M3, 117, M2, M2, M3, M4, M3, M, M, >> 933 /*1f*/111, M, M, M, M4, M3, M3, M, M, M, M3, M, M3, M2, M, M >> 934 }; >> 935 static unsigned char cheetah_mtag_syntab[] = { >> 936 NONE, MTC0, >> 937 MTC1, NONE, >> 938 MTC2, NONE, >> 939 NONE, MT0, >> 940 MTC3, NONE, >> 941 NONE, MT1, >> 942 NONE, MT2, >> 943 NONE, NONE >> 944 }; >> 945 >> 946 /* Return the highest priority error conditon mentioned. */ >> 947 static __inline__ unsigned long cheetah_get_hipri(unsigned long afsr) 95 { 948 { 96 die("Unhandled Machine Check Exception !! 949 unsigned long tmp = 0; >> 950 int i; >> 951 >> 952 for (i = 0; cheetah_error_table[i].mask; i++) { >> 953 if ((tmp = (afsr & cheetah_error_table[i].mask)) != 0UL) >> 954 return tmp; >> 955 } >> 956 return tmp; 97 } 957 } 98 958 >> 959 static const char *cheetah_get_string(unsigned long bit) >> 960 { >> 961 int i; 99 962 100 /* !! 963 for (i = 0; cheetah_error_table[i].mask; i++) { 101 * Entry point for traps induced by ARCompact !! 964 if ((bit & cheetah_error_table[i].mask) != 0UL) 102 * This is same family as TRAP0/SWI insn (use !! 965 return cheetah_error_table[i].name; 103 * The only difference being SWI insn take no !! 966 } 104 * which reflects in ECR Reg as 8 bit param. !! 967 return "???"; 105 * Thus TRAP_S <n> can be used for specific pu !! 968 } 106 * -1 used for software breakpointing (gdb) << 107 * -2 used by kprobes << 108 * -5 __builtin_trap() generated by gcc (2018 << 109 * -fno-isolate-erroneous-paths-dereferenc << 110 */ << 111 void do_non_swi_trap(unsigned long address, st << 112 { << 113 switch (regs->ecr.param) { << 114 case 1: << 115 trap_is_brkpt(address, regs); << 116 break; << 117 969 118 case 2: !! 970 extern int chmc_getunumber(int, unsigned long, char *, int); 119 trap_is_kprobe(address, regs); << 120 break; << 121 971 122 case 3: !! 972 static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *info, 123 case 4: !! 973 unsigned long afsr, unsigned long afar, int recoverable) 124 kgdb_trap(regs); !! 974 { 125 break; !! 975 unsigned long hipri; >> 976 char unum[256]; 126 977 127 case 5: !! 978 printk("%s" "ERROR(%d): Cheetah error trap taken afsr[%016lx] afar[%016lx] TL1(%d)\n", 128 do_trap5_error(address, regs); !! 979 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), 129 break; !! 980 afsr, afar, 130 default: !! 981 (afsr & CHAFSR_TL1) ? 1 : 0); 131 break; !! 982 printk("%s" "ERROR(%d): TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n", >> 983 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 984 regs->tpc, regs->tnpc, regs->tstate); >> 985 printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n", >> 986 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 987 (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT, >> 988 (afsr & CHAFSR_E_SYNDROME) >> CHAFSR_E_SYNDROME_SHIFT, >> 989 (afsr & CHAFSR_ME) ? ", Multiple Errors" : "", >> 990 (afsr & CHAFSR_PRIV) ? ", Privileged" : ""); >> 991 hipri = cheetah_get_hipri(afsr); >> 992 printk("%s" "ERROR(%d): Highest priority error (%016lx) \"%s\"\n", >> 993 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 994 hipri, cheetah_get_string(hipri)); >> 995 >> 996 /* Try to get unumber if relevant. */ >> 997 #define ESYND_ERRORS (CHAFSR_IVC | CHAFSR_IVU | \ >> 998 CHAFSR_CPC | CHAFSR_CPU | \ >> 999 CHAFSR_UE | CHAFSR_CE | \ >> 1000 CHAFSR_EDC | CHAFSR_EDU | \ >> 1001 CHAFSR_UCC | CHAFSR_UCU | \ >> 1002 CHAFSR_WDU | CHAFSR_WDC) >> 1003 #define MSYND_ERRORS (CHAFSR_EMC | CHAFSR_EMU) >> 1004 if (afsr & ESYND_ERRORS) { >> 1005 int syndrome; >> 1006 int ret; >> 1007 >> 1008 syndrome = (afsr & CHAFSR_E_SYNDROME) >> CHAFSR_E_SYNDROME_SHIFT; >> 1009 syndrome = cheetah_ecc_syntab[syndrome]; >> 1010 ret = chmc_getunumber(syndrome, afar, unum, sizeof(unum)); >> 1011 if (ret != -1) >> 1012 printk("%s" "ERROR(%d): AFAR E-syndrome [%s]\n", >> 1013 (recoverable ? KERN_WARNING : KERN_CRIT), >> 1014 smp_processor_id(), unum); >> 1015 } else if (afsr & MSYND_ERRORS) { >> 1016 int syndrome; >> 1017 int ret; >> 1018 >> 1019 syndrome = (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT; >> 1020 syndrome = cheetah_mtag_syntab[syndrome]; >> 1021 ret = chmc_getunumber(syndrome, afar, unum, sizeof(unum)); >> 1022 if (ret != -1) >> 1023 printk("%s" "ERROR(%d): AFAR M-syndrome [%s]\n", >> 1024 (recoverable ? KERN_WARNING : KERN_CRIT), >> 1025 smp_processor_id(), unum); 132 } 1026 } >> 1027 >> 1028 /* Now dump the cache snapshots. */ >> 1029 printk("%s" "ERROR(%d): D-cache idx[%x] tag[%016lx] utag[%016lx] stag[%016lx]\n", >> 1030 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 1031 (int) info->dcache_index, >> 1032 info->dcache_tag, >> 1033 info->dcache_utag, >> 1034 info->dcache_stag); >> 1035 printk("%s" "ERROR(%d): D-cache data0[%016lx] data1[%016lx] data2[%016lx] data3[%016lx]\n", >> 1036 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 1037 info->dcache_data[0], >> 1038 info->dcache_data[1], >> 1039 info->dcache_data[2], >> 1040 info->dcache_data[3]); >> 1041 printk("%s" "ERROR(%d): I-cache idx[%x] tag[%016lx] utag[%016lx] stag[%016lx] " >> 1042 "u[%016lx] l[%016lx]\n", >> 1043 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 1044 (int) info->icache_index, >> 1045 info->icache_tag, >> 1046 info->icache_utag, >> 1047 info->icache_stag, >> 1048 info->icache_upper, >> 1049 info->icache_lower); >> 1050 printk("%s" "ERROR(%d): I-cache INSN0[%016lx] INSN1[%016lx] INSN2[%016lx] INSN3[%016lx]\n", >> 1051 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 1052 info->icache_data[0], >> 1053 info->icache_data[1], >> 1054 info->icache_data[2], >> 1055 info->icache_data[3]); >> 1056 printk("%s" "ERROR(%d): I-cache INSN4[%016lx] INSN5[%016lx] INSN6[%016lx] INSN7[%016lx]\n", >> 1057 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 1058 info->icache_data[4], >> 1059 info->icache_data[5], >> 1060 info->icache_data[6], >> 1061 info->icache_data[7]); >> 1062 printk("%s" "ERROR(%d): E-cache idx[%x] tag[%016lx]\n", >> 1063 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 1064 (int) info->ecache_index, info->ecache_tag); >> 1065 printk("%s" "ERROR(%d): E-cache data0[%016lx] data1[%016lx] data2[%016lx] data3[%016lx]\n", >> 1066 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), >> 1067 info->ecache_data[0], >> 1068 info->ecache_data[1], >> 1069 info->ecache_data[2], >> 1070 info->ecache_data[3]); >> 1071 >> 1072 afsr = (afsr & ~hipri) & cheetah_afsr_errors; >> 1073 while (afsr != 0UL) { >> 1074 unsigned long bit = cheetah_get_hipri(afsr); >> 1075 >> 1076 printk("%s" "ERROR: Multiple-error (%016lx) \"%s\"\n", >> 1077 (recoverable ? KERN_WARNING : KERN_CRIT), >> 1078 bit, cheetah_get_string(bit)); >> 1079 >> 1080 afsr &= ~bit; >> 1081 } >> 1082 >> 1083 if (!recoverable) >> 1084 printk(KERN_CRIT "ERROR: This condition is not recoverable.\n"); 133 } 1085 } 134 1086 135 /* !! 1087 static int cheetah_recheck_errors(struct cheetah_err_info *logp) 136 * Entry point for Instruction Error Exception !! 1088 { 137 * -For a corner case, ARC kprobes implementa !! 1089 unsigned long afsr, afar; 138 * this exception, hence the check !! 1090 int ret = 0; >> 1091 >> 1092 __asm__ __volatile__("ldxa [%%g0] %1, %0\n\t" >> 1093 : "=r" (afsr) >> 1094 : "i" (ASI_AFSR)); >> 1095 if ((afsr & cheetah_afsr_errors) != 0) { >> 1096 if (logp != NULL) { >> 1097 __asm__ __volatile__("ldxa [%%g0] %1, %0\n\t" >> 1098 : "=r" (afar) >> 1099 : "i" (ASI_AFAR)); >> 1100 logp->afsr = afsr; >> 1101 logp->afar = afar; >> 1102 } >> 1103 ret = 1; >> 1104 } >> 1105 __asm__ __volatile__("stxa %0, [%%g0] %1\n\t" >> 1106 "membar #Sync\n\t" >> 1107 : : "r" (afsr), "i" (ASI_AFSR)); >> 1108 >> 1109 return ret; >> 1110 } >> 1111 >> 1112 void cheetah_fecc_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar) >> 1113 { >> 1114 struct cheetah_err_info local_snapshot, *p; >> 1115 int recoverable; >> 1116 >> 1117 /* Flush E-cache */ >> 1118 cheetah_flush_ecache(); >> 1119 >> 1120 p = cheetah_get_error_log(afsr); >> 1121 if (!p) { >> 1122 prom_printf("ERROR: Early Fast-ECC error afsr[%016lx] afar[%016lx]\n", >> 1123 afsr, afar); >> 1124 prom_printf("ERROR: CPU(%d) TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n", >> 1125 smp_processor_id(), regs->tpc, regs->tnpc, regs->tstate); >> 1126 prom_halt(); >> 1127 } >> 1128 >> 1129 /* Grab snapshot of logged error. */ >> 1130 memcpy(&local_snapshot, p, sizeof(local_snapshot)); >> 1131 >> 1132 /* If the current trap snapshot does not match what the >> 1133 * trap handler passed along into our args, big trouble. >> 1134 * In such a case, mark the local copy as invalid. >> 1135 * >> 1136 * Else, it matches and we mark the afsr in the non-local >> 1137 * copy as invalid so we may log new error traps there. >> 1138 */ >> 1139 if (p->afsr != afsr || p->afar != afar) >> 1140 local_snapshot.afsr = CHAFSR_INVALID; >> 1141 else >> 1142 p->afsr = CHAFSR_INVALID; >> 1143 >> 1144 cheetah_flush_icache(); >> 1145 cheetah_flush_dcache(); >> 1146 >> 1147 /* Re-enable I-cache/D-cache */ >> 1148 __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t" >> 1149 "or %%g1, %1, %%g1\n\t" >> 1150 "stxa %%g1, [%%g0] %0\n\t" >> 1151 "membar #Sync" >> 1152 : /* no outputs */ >> 1153 : "i" (ASI_DCU_CONTROL_REG), >> 1154 "i" (DCU_DC | DCU_IC) >> 1155 : "g1"); >> 1156 >> 1157 /* Re-enable error reporting */ >> 1158 __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t" >> 1159 "or %%g1, %1, %%g1\n\t" >> 1160 "stxa %%g1, [%%g0] %0\n\t" >> 1161 "membar #Sync" >> 1162 : /* no outputs */ >> 1163 : "i" (ASI_ESTATE_ERROR_EN), >> 1164 "i" (ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN) >> 1165 : "g1"); >> 1166 >> 1167 /* Decide if we can continue after handling this trap and >> 1168 * logging the error. >> 1169 */ >> 1170 recoverable = 1; >> 1171 if (afsr & (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP)) >> 1172 recoverable = 0; >> 1173 >> 1174 /* Re-check AFSR/AFAR. What we are looking for here is whether a new >> 1175 * error was logged while we had error reporting traps disabled. >> 1176 */ >> 1177 if (cheetah_recheck_errors(&local_snapshot)) { >> 1178 unsigned long new_afsr = local_snapshot.afsr; >> 1179 >> 1180 /* If we got a new asynchronous error, die... */ >> 1181 if (new_afsr & (CHAFSR_EMU | CHAFSR_EDU | >> 1182 CHAFSR_WDU | CHAFSR_CPU | >> 1183 CHAFSR_IVU | CHAFSR_UE | >> 1184 CHAFSR_BERR | CHAFSR_TO)) >> 1185 recoverable = 0; >> 1186 } >> 1187 >> 1188 /* Log errors. */ >> 1189 cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable); >> 1190 >> 1191 if (!recoverable) >> 1192 panic("Irrecoverable Fast-ECC error trap.\n"); >> 1193 >> 1194 /* Flush E-cache to kick the error trap handlers out. */ >> 1195 cheetah_flush_ecache(); >> 1196 } >> 1197 >> 1198 /* Try to fix a correctable error by pushing the line out from >> 1199 * the E-cache. Recheck error reporting registers to see if the >> 1200 * problem is intermittent. 139 */ 1201 */ 140 void do_insterror_or_kprobe(unsigned long addr !! 1202 static int cheetah_fix_ce(unsigned long physaddr) >> 1203 { >> 1204 unsigned long orig_estate; >> 1205 unsigned long alias1, alias2; >> 1206 int ret; >> 1207 >> 1208 /* Make sure correctable error traps are disabled. */ >> 1209 __asm__ __volatile__("ldxa [%%g0] %2, %0\n\t" >> 1210 "andn %0, %1, %%g1\n\t" >> 1211 "stxa %%g1, [%%g0] %2\n\t" >> 1212 "membar #Sync" >> 1213 : "=&r" (orig_estate) >> 1214 : "i" (ESTATE_ERROR_CEEN), >> 1215 "i" (ASI_ESTATE_ERROR_EN) >> 1216 : "g1"); >> 1217 >> 1218 /* We calculate alias addresses that will force the >> 1219 * cache line in question out of the E-cache. Then >> 1220 * we bring it back in with an atomic instruction so >> 1221 * that we get it in some modified/exclusive state, >> 1222 * then we displace it again to try and get proper ECC >> 1223 * pushed back into the system. >> 1224 */ >> 1225 physaddr &= ~(8UL - 1UL); >> 1226 alias1 = (ecache_flush_physbase + >> 1227 (physaddr & ((ecache_flush_size >> 1) - 1))); >> 1228 alias2 = alias1 + (ecache_flush_size >> 1); >> 1229 __asm__ __volatile__("ldxa [%0] %3, %%g0\n\t" >> 1230 "ldxa [%1] %3, %%g0\n\t" >> 1231 "casxa [%2] %3, %%g0, %%g0\n\t" >> 1232 "membar #StoreLoad | #StoreStore\n\t" >> 1233 "ldxa [%0] %3, %%g0\n\t" >> 1234 "ldxa [%1] %3, %%g0\n\t" >> 1235 "membar #Sync" >> 1236 : /* no outputs */ >> 1237 : "r" (alias1), "r" (alias2), >> 1238 "r" (physaddr), "i" (ASI_PHYS_USE_EC)); >> 1239 >> 1240 /* Did that trigger another error? */ >> 1241 if (cheetah_recheck_errors(NULL)) { >> 1242 /* Try one more time. */ >> 1243 __asm__ __volatile__("ldxa [%0] %1, %%g0\n\t" >> 1244 "membar #Sync" >> 1245 : : "r" (physaddr), "i" (ASI_PHYS_USE_EC)); >> 1246 if (cheetah_recheck_errors(NULL)) >> 1247 ret = 2; >> 1248 else >> 1249 ret = 1; >> 1250 } else { >> 1251 /* No new error, intermittent problem. */ >> 1252 ret = 0; >> 1253 } >> 1254 >> 1255 /* Restore error enables. */ >> 1256 __asm__ __volatile__("stxa %0, [%%g0] %1\n\t" >> 1257 "membar #Sync" >> 1258 : : "r" (orig_estate), "i" (ASI_ESTATE_ERROR_EN)); >> 1259 >> 1260 return ret; >> 1261 } >> 1262 >> 1263 /* Return non-zero if PADDR is a valid physical memory address. */ >> 1264 static int cheetah_check_main_memory(unsigned long paddr) 141 { 1265 { 142 int rc; !! 1266 int i; >> 1267 >> 1268 for (i = 0; ; i++) { >> 1269 if (sp_banks[i].num_bytes == 0) >> 1270 break; >> 1271 if (paddr >= sp_banks[i].base_addr && >> 1272 paddr < (sp_banks[i].base_addr + sp_banks[i].num_bytes)) >> 1273 return 1; >> 1274 } >> 1275 return 0; >> 1276 } >> 1277 >> 1278 void cheetah_cee_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar) >> 1279 { >> 1280 struct cheetah_err_info local_snapshot, *p; >> 1281 int recoverable, is_memory; >> 1282 >> 1283 p = cheetah_get_error_log(afsr); >> 1284 if (!p) { >> 1285 prom_printf("ERROR: Early CEE error afsr[%016lx] afar[%016lx]\n", >> 1286 afsr, afar); >> 1287 prom_printf("ERROR: CPU(%d) TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n", >> 1288 smp_processor_id(), regs->tpc, regs->tnpc, regs->tstate); >> 1289 prom_halt(); >> 1290 } >> 1291 >> 1292 /* Grab snapshot of logged error. */ >> 1293 memcpy(&local_snapshot, p, sizeof(local_snapshot)); >> 1294 >> 1295 /* If the current trap snapshot does not match what the >> 1296 * trap handler passed along into our args, big trouble. >> 1297 * In such a case, mark the local copy as invalid. >> 1298 * >> 1299 * Else, it matches and we mark the afsr in the non-local >> 1300 * copy as invalid so we may log new error traps there. >> 1301 */ >> 1302 if (p->afsr != afsr || p->afar != afar) >> 1303 local_snapshot.afsr = CHAFSR_INVALID; >> 1304 else >> 1305 p->afsr = CHAFSR_INVALID; >> 1306 >> 1307 is_memory = cheetah_check_main_memory(afar); >> 1308 >> 1309 if (is_memory && (afsr & CHAFSR_CE) != 0UL) { >> 1310 /* XXX Might want to log the results of this operation >> 1311 * XXX somewhere... -DaveM >> 1312 */ >> 1313 cheetah_fix_ce(afar); >> 1314 } >> 1315 >> 1316 { >> 1317 int flush_all, flush_line; >> 1318 >> 1319 flush_all = flush_line = 0; >> 1320 if ((afsr & CHAFSR_EDC) != 0UL) { >> 1321 if ((afsr & cheetah_afsr_errors) == CHAFSR_EDC) >> 1322 flush_line = 1; >> 1323 else >> 1324 flush_all = 1; >> 1325 } else if ((afsr & CHAFSR_CPC) != 0UL) { >> 1326 if ((afsr & cheetah_afsr_errors) == CHAFSR_CPC) >> 1327 flush_line = 1; >> 1328 else >> 1329 flush_all = 1; >> 1330 } >> 1331 >> 1332 /* Trap handler only disabled I-cache, flush it. */ >> 1333 cheetah_flush_icache(); >> 1334 >> 1335 /* Re-enable I-cache */ >> 1336 __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t" >> 1337 "or %%g1, %1, %%g1\n\t" >> 1338 "stxa %%g1, [%%g0] %0\n\t" >> 1339 "membar #Sync" >> 1340 : /* no outputs */ >> 1341 : "i" (ASI_DCU_CONTROL_REG), >> 1342 "i" (DCU_IC) >> 1343 : "g1"); >> 1344 >> 1345 if (flush_all) >> 1346 cheetah_flush_ecache(); >> 1347 else if (flush_line) >> 1348 cheetah_flush_ecache_line(afar); >> 1349 } >> 1350 >> 1351 /* Re-enable error reporting */ >> 1352 __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t" >> 1353 "or %%g1, %1, %%g1\n\t" >> 1354 "stxa %%g1, [%%g0] %0\n\t" >> 1355 "membar #Sync" >> 1356 : /* no outputs */ >> 1357 : "i" (ASI_ESTATE_ERROR_EN), >> 1358 "i" (ESTATE_ERROR_CEEN) >> 1359 : "g1"); >> 1360 >> 1361 /* Decide if we can continue after handling this trap and >> 1362 * logging the error. >> 1363 */ >> 1364 recoverable = 1; >> 1365 if (afsr & (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP)) >> 1366 recoverable = 0; >> 1367 >> 1368 /* Re-check AFSR/AFAR */ >> 1369 (void) cheetah_recheck_errors(&local_snapshot); >> 1370 >> 1371 /* Log errors. */ >> 1372 cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable); >> 1373 >> 1374 if (!recoverable) >> 1375 panic("Irrecoverable Correctable-ECC error trap.\n"); >> 1376 } 143 1377 144 /* Check if this exception is caused b !! 1378 void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar) 145 rc = notify_die(DIE_IERR, "kprobe_ierr !! 1379 { 146 if (rc == NOTIFY_STOP) !! 1380 struct cheetah_err_info local_snapshot, *p; >> 1381 int recoverable, is_memory; >> 1382 >> 1383 #ifdef CONFIG_PCI >> 1384 /* Check for the special PCI poke sequence. */ >> 1385 if (pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) { >> 1386 cheetah_flush_icache(); >> 1387 cheetah_flush_dcache(); >> 1388 >> 1389 /* Re-enable I-cache/D-cache */ >> 1390 __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t" >> 1391 "or %%g1, %1, %%g1\n\t" >> 1392 "stxa %%g1, [%%g0] %0\n\t" >> 1393 "membar #Sync" >> 1394 : /* no outputs */ >> 1395 : "i" (ASI_DCU_CONTROL_REG), >> 1396 "i" (DCU_DC | DCU_IC) >> 1397 : "g1"); >> 1398 >> 1399 /* Re-enable error reporting */ >> 1400 __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t" >> 1401 "or %%g1, %1, %%g1\n\t" >> 1402 "stxa %%g1, [%%g0] %0\n\t" >> 1403 "membar #Sync" >> 1404 : /* no outputs */ >> 1405 : "i" (ASI_ESTATE_ERROR_EN), >> 1406 "i" (ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN) >> 1407 : "g1"); >> 1408 >> 1409 (void) cheetah_recheck_errors(NULL); >> 1410 >> 1411 pci_poke_faulted = 1; >> 1412 regs->tpc += 4; >> 1413 regs->tnpc = regs->tpc + 4; 147 return; 1414 return; >> 1415 } >> 1416 #endif >> 1417 >> 1418 p = cheetah_get_error_log(afsr); >> 1419 if (!p) { >> 1420 prom_printf("ERROR: Early deferred error afsr[%016lx] afar[%016lx]\n", >> 1421 afsr, afar); >> 1422 prom_printf("ERROR: CPU(%d) TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n", >> 1423 smp_processor_id(), regs->tpc, regs->tnpc, regs->tstate); >> 1424 prom_halt(); >> 1425 } >> 1426 >> 1427 /* Grab snapshot of logged error. */ >> 1428 memcpy(&local_snapshot, p, sizeof(local_snapshot)); >> 1429 >> 1430 /* If the current trap snapshot does not match what the >> 1431 * trap handler passed along into our args, big trouble. >> 1432 * In such a case, mark the local copy as invalid. >> 1433 * >> 1434 * Else, it matches and we mark the afsr in the non-local >> 1435 * copy as invalid so we may log new error traps there. >> 1436 */ >> 1437 if (p->afsr != afsr || p->afar != afar) >> 1438 local_snapshot.afsr = CHAFSR_INVALID; >> 1439 else >> 1440 p->afsr = CHAFSR_INVALID; >> 1441 >> 1442 is_memory = cheetah_check_main_memory(afar); >> 1443 >> 1444 { >> 1445 int flush_all, flush_line; >> 1446 >> 1447 flush_all = flush_line = 0; >> 1448 if ((afsr & CHAFSR_EDU) != 0UL) { >> 1449 if ((afsr & cheetah_afsr_errors) == CHAFSR_EDU) >> 1450 flush_line = 1; >> 1451 else >> 1452 flush_all = 1; >> 1453 } else if ((afsr & CHAFSR_BERR) != 0UL) { >> 1454 if ((afsr & cheetah_afsr_errors) == CHAFSR_BERR) >> 1455 flush_line = 1; >> 1456 else >> 1457 flush_all = 1; >> 1458 } >> 1459 >> 1460 cheetah_flush_icache(); >> 1461 cheetah_flush_dcache(); >> 1462 >> 1463 /* Re-enable I/D caches */ >> 1464 __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t" >> 1465 "or %%g1, %1, %%g1\n\t" >> 1466 "stxa %%g1, [%%g0] %0\n\t" >> 1467 "membar #Sync" >> 1468 : /* no outputs */ >> 1469 : "i" (ASI_DCU_CONTROL_REG), >> 1470 "i" (DCU_IC | DCU_DC) >> 1471 : "g1"); >> 1472 >> 1473 if (flush_all) >> 1474 cheetah_flush_ecache(); >> 1475 else if (flush_line) >> 1476 cheetah_flush_ecache_line(afar); >> 1477 } >> 1478 >> 1479 /* Re-enable error reporting */ >> 1480 __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t" >> 1481 "or %%g1, %1, %%g1\n\t" >> 1482 "stxa %%g1, [%%g0] %0\n\t" >> 1483 "membar #Sync" >> 1484 : /* no outputs */ >> 1485 : "i" (ASI_ESTATE_ERROR_EN), >> 1486 "i" (ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN) >> 1487 : "g1"); >> 1488 >> 1489 /* Decide if we can continue after handling this trap and >> 1490 * logging the error. >> 1491 */ >> 1492 recoverable = 1; >> 1493 if (afsr & (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP)) >> 1494 recoverable = 0; >> 1495 >> 1496 /* Re-check AFSR/AFAR. What we are looking for here is whether a new >> 1497 * error was logged while we had error reporting traps disabled. >> 1498 */ >> 1499 if (cheetah_recheck_errors(&local_snapshot)) { >> 1500 unsigned long new_afsr = local_snapshot.afsr; >> 1501 >> 1502 /* If we got a new asynchronous error, die... */ >> 1503 if (new_afsr & (CHAFSR_EMU | CHAFSR_EDU | >> 1504 CHAFSR_WDU | CHAFSR_CPU | >> 1505 CHAFSR_IVU | CHAFSR_UE | >> 1506 CHAFSR_BERR | CHAFSR_TO)) >> 1507 recoverable = 0; >> 1508 } >> 1509 >> 1510 /* Log errors. */ >> 1511 cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable); 148 1512 149 insterror_is_error(address, regs); !! 1513 /* "Recoverable" here means we try to yank the page from ever >> 1514 * being newly used again. This depends upon a few things: >> 1515 * 1) Must be main memory, and AFAR must be valid. >> 1516 * 2) If we trapped from use, OK. >> 1517 * 3) Else, if we trapped from kernel we must find exception >> 1518 * table entry (ie. we have to have been accessing user >> 1519 * space). >> 1520 * >> 1521 * If AFAR is not in main memory, or we trapped from kernel >> 1522 * and cannot find an exception table entry, it is unacceptable >> 1523 * to try and continue. >> 1524 */ >> 1525 if (recoverable && is_memory) { >> 1526 if ((regs->tstate & TSTATE_PRIV) == 0UL) { >> 1527 /* OK, usermode access. */ >> 1528 recoverable = 1; >> 1529 } else { >> 1530 unsigned long g2 = regs->u_regs[UREG_G2]; >> 1531 unsigned long fixup = search_exception_table(regs->tpc, &g2); >> 1532 >> 1533 if (fixup != 0UL) { >> 1534 /* OK, kernel access to userspace. */ >> 1535 recoverable = 1; >> 1536 >> 1537 } else { >> 1538 /* BAD, privileged state is corrupted. */ >> 1539 recoverable = 0; >> 1540 } >> 1541 >> 1542 if (recoverable) { >> 1543 struct page *page = virt_to_page(__va(afar)); >> 1544 >> 1545 if (VALID_PAGE(page)) >> 1546 get_page(page); >> 1547 else >> 1548 recoverable = 0; >> 1549 >> 1550 /* Only perform fixup if we still have a >> 1551 * recoverable condition. >> 1552 */ >> 1553 if (fixup != 0UL && recoverable) { >> 1554 regs->tpc = fixup; >> 1555 regs->tnpc = regs->tpc + 4; >> 1556 regs->u_regs[UREG_G2] = g2; >> 1557 } >> 1558 } >> 1559 } >> 1560 } else { >> 1561 recoverable = 0; >> 1562 } >> 1563 >> 1564 if (!recoverable) >> 1565 panic("Irrecoverable deferred error trap.\n"); 150 } 1566 } 151 1567 152 /* !! 1568 /* Handle a D/I cache parity error trap. TYPE is encoded as: 153 * abort() call generated by older gcc for __b !! 1569 * >> 1570 * Bit0: 0=dcache,1=icache >> 1571 * Bit1: 0=recoverable,1=unrecoverable >> 1572 * >> 1573 * The hardware has disabled both the I-cache and D-cache in >> 1574 * the %dcr register. 154 */ 1575 */ 155 void abort(void) !! 1576 void cheetah_plus_parity_error(int type, struct pt_regs *regs) >> 1577 { >> 1578 if (type & 0x1) >> 1579 __cheetah_flush_icache(); >> 1580 else >> 1581 cheetah_plus_zap_dcache_parity(); >> 1582 cheetah_flush_dcache(); >> 1583 >> 1584 /* Re-enable I-cache/D-cache */ >> 1585 __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t" >> 1586 "or %%g1, %1, %%g1\n\t" >> 1587 "stxa %%g1, [%%g0] %0\n\t" >> 1588 "membar #Sync" >> 1589 : /* no outputs */ >> 1590 : "i" (ASI_DCU_CONTROL_REG), >> 1591 "i" (DCU_DC | DCU_IC) >> 1592 : "g1"); >> 1593 >> 1594 if (type & 0x2) { >> 1595 printk(KERN_EMERG "CPU[%d]: Cheetah+ %c-cache parity error at TPC[%016lx]\n", >> 1596 smp_processor_id(), >> 1597 (type & 0x1) ? 'I' : 'D', >> 1598 regs->tpc); >> 1599 panic("Irrecoverable Cheetah+ parity error."); >> 1600 } >> 1601 >> 1602 printk(KERN_WARNING "CPU[%d]: Cheetah+ %c-cache parity error at TPC[%016lx]\n", >> 1603 smp_processor_id(), >> 1604 (type & 0x1) ? 'I' : 'D', >> 1605 regs->tpc); >> 1606 } >> 1607 >> 1608 void do_fpe_common(struct pt_regs *regs) >> 1609 { >> 1610 if(regs->tstate & TSTATE_PRIV) { >> 1611 regs->tpc = regs->tnpc; >> 1612 regs->tnpc += 4; >> 1613 } else { >> 1614 unsigned long fsr = current->thread.xfsr[0]; >> 1615 siginfo_t info; >> 1616 >> 1617 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { >> 1618 regs->tpc &= 0xffffffff; >> 1619 regs->tnpc &= 0xffffffff; >> 1620 } >> 1621 info.si_signo = SIGFPE; >> 1622 info.si_errno = 0; >> 1623 info.si_addr = (void *)regs->tpc; >> 1624 info.si_trapno = 0; >> 1625 info.si_code = __SI_FAULT; >> 1626 if ((fsr & 0x1c000) == (1 << 14)) { >> 1627 if (fsr & 0x10) >> 1628 info.si_code = FPE_FLTINV; >> 1629 else if (fsr & 0x08) >> 1630 info.si_code = FPE_FLTOVF; >> 1631 else if (fsr & 0x04) >> 1632 info.si_code = FPE_FLTUND; >> 1633 else if (fsr & 0x02) >> 1634 info.si_code = FPE_FLTDIV; >> 1635 else if (fsr & 0x01) >> 1636 info.si_code = FPE_FLTRES; >> 1637 } >> 1638 force_sig_info(SIGFPE, &info, current); >> 1639 } >> 1640 } >> 1641 >> 1642 void do_fpieee(struct pt_regs *regs) >> 1643 { >> 1644 do_fpe_common(regs); >> 1645 } >> 1646 >> 1647 extern int do_mathemu(struct pt_regs *, struct fpustate *); >> 1648 >> 1649 void do_fpother(struct pt_regs *regs) >> 1650 { >> 1651 struct fpustate *f = FPUSTATE; >> 1652 int ret = 0; >> 1653 >> 1654 switch ((current->thread.xfsr[0] & 0x1c000)) { >> 1655 case (2 << 14): /* unfinished_FPop */ >> 1656 case (3 << 14): /* unimplemented_FPop */ >> 1657 ret = do_mathemu(regs, f); >> 1658 break; >> 1659 } >> 1660 if (ret) >> 1661 return; >> 1662 do_fpe_common(regs); >> 1663 } >> 1664 >> 1665 void do_tof(struct pt_regs *regs) >> 1666 { >> 1667 siginfo_t info; >> 1668 >> 1669 if(regs->tstate & TSTATE_PRIV) >> 1670 die_if_kernel("Penguin overflow trap from kernel mode", regs); >> 1671 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { >> 1672 regs->tpc &= 0xffffffff; >> 1673 regs->tnpc &= 0xffffffff; >> 1674 } >> 1675 info.si_signo = SIGEMT; >> 1676 info.si_errno = 0; >> 1677 info.si_code = EMT_TAGOVF; >> 1678 info.si_addr = (void *)regs->tpc; >> 1679 info.si_trapno = 0; >> 1680 force_sig_info(SIGEMT, &info, current); >> 1681 } >> 1682 >> 1683 void do_div0(struct pt_regs *regs) >> 1684 { >> 1685 siginfo_t info; >> 1686 >> 1687 if (regs->tstate & TSTATE_PRIV) >> 1688 die_if_kernel("TL0: Kernel divide by zero.", regs); >> 1689 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { >> 1690 regs->tpc &= 0xffffffff; >> 1691 regs->tnpc &= 0xffffffff; >> 1692 } >> 1693 info.si_signo = SIGFPE; >> 1694 info.si_errno = 0; >> 1695 info.si_code = FPE_INTDIV; >> 1696 info.si_addr = (void *)regs->tpc; >> 1697 info.si_trapno = 0; >> 1698 force_sig_info(SIGFPE, &info, current); >> 1699 } >> 1700 >> 1701 void instruction_dump (unsigned int *pc) >> 1702 { >> 1703 int i; >> 1704 >> 1705 if((((unsigned long) pc) & 3)) >> 1706 return; >> 1707 >> 1708 printk("Instruction DUMP:"); >> 1709 for(i = -3; i < 6; i++) >> 1710 printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>'); >> 1711 printk("\n"); >> 1712 } >> 1713 >> 1714 void user_instruction_dump (unsigned int *pc) >> 1715 { >> 1716 int i; >> 1717 unsigned int buf[9]; >> 1718 >> 1719 if((((unsigned long) pc) & 3)) >> 1720 return; >> 1721 >> 1722 if(copy_from_user(buf, pc - 3, sizeof(buf))) >> 1723 return; >> 1724 >> 1725 printk("Instruction DUMP:"); >> 1726 for(i = 0; i < 9; i++) >> 1727 printk("%c%08x%c",i==3?' ':'<',buf[i],i==3?' ':'>'); >> 1728 printk("\n"); >> 1729 } >> 1730 >> 1731 void show_trace_raw(struct task_struct *tsk, unsigned long ksp) >> 1732 { >> 1733 unsigned long pc, fp; >> 1734 unsigned long task_base = (unsigned long)tsk; >> 1735 struct reg_window *rw; >> 1736 int count = 0; >> 1737 >> 1738 if (tsk == current) >> 1739 flushw_all(); >> 1740 >> 1741 fp = ksp + STACK_BIAS; >> 1742 do { >> 1743 /* Bogus frame pointer? */ >> 1744 if (fp < (task_base + sizeof(struct task_struct)) || >> 1745 fp >= (task_base + THREAD_SIZE)) >> 1746 break; >> 1747 rw = (struct reg_window *)fp; >> 1748 pc = rw->ins[7]; >> 1749 printk("[%016lx] ", pc); >> 1750 fp = rw->ins[6] + STACK_BIAS; >> 1751 } while (++count < 16); >> 1752 printk("\n"); >> 1753 } >> 1754 >> 1755 void show_trace_task(struct task_struct *tsk) >> 1756 { >> 1757 if (tsk) >> 1758 show_trace_raw(tsk, tsk->thread.ksp); >> 1759 } >> 1760 >> 1761 void dump_stack(void) >> 1762 { >> 1763 unsigned long ksp; >> 1764 >> 1765 __asm__ __volatile__("mov %%fp, %0" >> 1766 : "=r" (ksp)); >> 1767 show_trace_raw(current, ksp); >> 1768 } >> 1769 >> 1770 void die_if_kernel(char *str, struct pt_regs *regs) >> 1771 { >> 1772 extern void __show_regs(struct pt_regs * regs); >> 1773 extern void smp_report_regs(void); >> 1774 int count = 0; >> 1775 struct reg_window *lastrw; >> 1776 >> 1777 /* Amuse the user. */ >> 1778 printk( >> 1779 " \\|/ ____ \\|/\n" >> 1780 " \"@'/ .. \\`@\"\n" >> 1781 " /_| \\__/ |_\\\n" >> 1782 " \\__U_/\n"); >> 1783 >> 1784 printk("%s(%d): %s\n", current->comm, current->pid, str); >> 1785 __asm__ __volatile__("flushw"); >> 1786 __show_regs(regs); >> 1787 if(regs->tstate & TSTATE_PRIV) { >> 1788 struct reg_window *rw = (struct reg_window *) >> 1789 (regs->u_regs[UREG_FP] + STACK_BIAS); >> 1790 >> 1791 /* Stop the back trace when we hit userland or we >> 1792 * find some badly aligned kernel stack. >> 1793 */ >> 1794 lastrw = (struct reg_window *)current; >> 1795 while(rw && >> 1796 count++ < 30 && >> 1797 rw >= lastrw && >> 1798 (char *) rw < ((char *) current) >> 1799 + sizeof (union task_union) && >> 1800 !(((unsigned long) rw) & 0x7)) { >> 1801 printk("Caller[%016lx]\n", rw->ins[7]); >> 1802 lastrw = rw; >> 1803 rw = (struct reg_window *) >> 1804 (rw->ins[6] + STACK_BIAS); >> 1805 } >> 1806 instruction_dump ((unsigned int *) regs->tpc); >> 1807 } else { >> 1808 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { >> 1809 regs->tpc &= 0xffffffff; >> 1810 regs->tnpc &= 0xffffffff; >> 1811 } >> 1812 user_instruction_dump ((unsigned int *) regs->tpc); >> 1813 } >> 1814 #ifdef CONFIG_SMP >> 1815 smp_report_regs(); >> 1816 #endif >> 1817 >> 1818 if(regs->tstate & TSTATE_PRIV) >> 1819 do_exit(SIGKILL); >> 1820 do_exit(SIGSEGV); >> 1821 } >> 1822 >> 1823 extern int handle_popc(u32 insn, struct pt_regs *regs); >> 1824 extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); >> 1825 >> 1826 void do_illegal_instruction(struct pt_regs *regs) >> 1827 { >> 1828 unsigned long pc = regs->tpc; >> 1829 unsigned long tstate = regs->tstate; >> 1830 u32 insn; >> 1831 siginfo_t info; >> 1832 >> 1833 if(tstate & TSTATE_PRIV) >> 1834 die_if_kernel("Kernel illegal instruction", regs); >> 1835 if(current->thread.flags & SPARC_FLAG_32BIT) >> 1836 pc = (u32)pc; >> 1837 if (get_user(insn, (u32 *)pc) != -EFAULT) { >> 1838 if ((insn & 0xc1ffc000) == 0x81700000) /* POPC */ { >> 1839 if (handle_popc(insn, regs)) >> 1840 return; >> 1841 } else if ((insn & 0xc1580000) == 0xc1100000) /* LDQ/STQ */ { >> 1842 if (handle_ldf_stq(insn, regs)) >> 1843 return; >> 1844 } >> 1845 } >> 1846 info.si_signo = SIGILL; >> 1847 info.si_errno = 0; >> 1848 info.si_code = ILL_ILLOPC; >> 1849 info.si_addr = (void *)pc; >> 1850 info.si_trapno = 0; >> 1851 force_sig_info(SIGILL, &info, current); >> 1852 } >> 1853 >> 1854 void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) >> 1855 { >> 1856 siginfo_t info; >> 1857 >> 1858 if(regs->tstate & TSTATE_PRIV) { >> 1859 extern void kernel_unaligned_trap(struct pt_regs *regs, >> 1860 unsigned int insn, >> 1861 unsigned long sfar, unsigned long sfsr); >> 1862 >> 1863 return kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc), sfar, sfsr); >> 1864 } >> 1865 info.si_signo = SIGBUS; >> 1866 info.si_errno = 0; >> 1867 info.si_code = BUS_ADRALN; >> 1868 info.si_addr = (void *)sfar; >> 1869 info.si_trapno = 0; >> 1870 force_sig_info(SIGBUS, &info, current); >> 1871 } >> 1872 >> 1873 void do_privop(struct pt_regs *regs) >> 1874 { >> 1875 siginfo_t info; >> 1876 >> 1877 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { >> 1878 regs->tpc &= 0xffffffff; >> 1879 regs->tnpc &= 0xffffffff; >> 1880 } >> 1881 info.si_signo = SIGILL; >> 1882 info.si_errno = 0; >> 1883 info.si_code = ILL_PRVOPC; >> 1884 info.si_addr = (void *)regs->tpc; >> 1885 info.si_trapno = 0; >> 1886 force_sig_info(SIGILL, &info, current); >> 1887 } >> 1888 >> 1889 void do_privact(struct pt_regs *regs) >> 1890 { >> 1891 do_privop(regs); >> 1892 } >> 1893 >> 1894 /* Trap level 1 stuff or other traps we should never see... */ >> 1895 void do_cee(struct pt_regs *regs) >> 1896 { >> 1897 die_if_kernel("TL0: Cache Error Exception", regs); >> 1898 } >> 1899 >> 1900 void do_cee_tl1(struct pt_regs *regs) >> 1901 { >> 1902 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1903 die_if_kernel("TL1: Cache Error Exception", regs); >> 1904 } >> 1905 >> 1906 void do_dae_tl1(struct pt_regs *regs) >> 1907 { >> 1908 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1909 die_if_kernel("TL1: Data Access Exception", regs); >> 1910 } >> 1911 >> 1912 void do_iae_tl1(struct pt_regs *regs) >> 1913 { >> 1914 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1915 die_if_kernel("TL1: Instruction Access Exception", regs); >> 1916 } >> 1917 >> 1918 void do_div0_tl1(struct pt_regs *regs) >> 1919 { >> 1920 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1921 die_if_kernel("TL1: DIV0 Exception", regs); >> 1922 } >> 1923 >> 1924 void do_fpdis_tl1(struct pt_regs *regs) >> 1925 { >> 1926 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1927 die_if_kernel("TL1: FPU Disabled", regs); >> 1928 } >> 1929 >> 1930 void do_fpieee_tl1(struct pt_regs *regs) >> 1931 { >> 1932 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1933 die_if_kernel("TL1: FPU IEEE Exception", regs); >> 1934 } >> 1935 >> 1936 void do_fpother_tl1(struct pt_regs *regs) >> 1937 { >> 1938 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1939 die_if_kernel("TL1: FPU Other Exception", regs); >> 1940 } >> 1941 >> 1942 void do_ill_tl1(struct pt_regs *regs) >> 1943 { >> 1944 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1945 die_if_kernel("TL1: Illegal Instruction Exception", regs); >> 1946 } >> 1947 >> 1948 void do_irq_tl1(struct pt_regs *regs) >> 1949 { >> 1950 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1951 die_if_kernel("TL1: IRQ Exception", regs); >> 1952 } >> 1953 >> 1954 void do_lddfmna_tl1(struct pt_regs *regs) >> 1955 { >> 1956 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1957 die_if_kernel("TL1: LDDF Exception", regs); >> 1958 } >> 1959 >> 1960 void do_stdfmna_tl1(struct pt_regs *regs) >> 1961 { >> 1962 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1963 die_if_kernel("TL1: STDF Exception", regs); >> 1964 } >> 1965 >> 1966 void do_paw(struct pt_regs *regs) >> 1967 { >> 1968 die_if_kernel("TL0: Phys Watchpoint Exception", regs); >> 1969 } >> 1970 >> 1971 void do_paw_tl1(struct pt_regs *regs) >> 1972 { >> 1973 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1974 die_if_kernel("TL1: Phys Watchpoint Exception", regs); >> 1975 } >> 1976 >> 1977 void do_vaw(struct pt_regs *regs) >> 1978 { >> 1979 die_if_kernel("TL0: Virt Watchpoint Exception", regs); >> 1980 } >> 1981 >> 1982 void do_vaw_tl1(struct pt_regs *regs) >> 1983 { >> 1984 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1985 die_if_kernel("TL1: Virt Watchpoint Exception", regs); >> 1986 } >> 1987 >> 1988 void do_tof_tl1(struct pt_regs *regs) >> 1989 { >> 1990 dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); >> 1991 die_if_kernel("TL1: Tag Overflow Exception", regs); >> 1992 } >> 1993 >> 1994 void do_getpsr(struct pt_regs *regs) >> 1995 { >> 1996 regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate); >> 1997 regs->tpc = regs->tnpc; >> 1998 regs->tnpc += 4; >> 1999 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { >> 2000 regs->tpc &= 0xffffffff; >> 2001 regs->tnpc &= 0xffffffff; >> 2002 } >> 2003 } >> 2004 >> 2005 void trap_init(void) 156 { 2006 { 157 __asm__ __volatile__("trap_s 5\n"); !! 2007 /* Attach to the address space of init_task. */ >> 2008 atomic_inc(&init_mm.mm_count); >> 2009 current->active_mm = &init_mm; >> 2010 >> 2011 /* NOTE: Other cpus have this done as they are started >> 2012 * up on SMP. >> 2013 */ 158 } 2014 } 159 2015
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.