diff options
Diffstat (limited to 'arch/sparc64/mm/fault.c')
| -rw-r--r-- | arch/sparc64/mm/fault.c | 69 |
1 files changed, 5 insertions, 64 deletions
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index db1e3310e907..31fbc67719a1 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c | |||
| @@ -32,8 +32,6 @@ | |||
| 32 | 32 | ||
| 33 | #define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0])) | 33 | #define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0])) |
| 34 | 34 | ||
| 35 | extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; | ||
| 36 | |||
| 37 | /* | 35 | /* |
| 38 | * To debug kernel to catch accesses to certain virtual/physical addresses. | 36 | * To debug kernel to catch accesses to certain virtual/physical addresses. |
| 39 | * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints. | 37 | * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints. |
| @@ -71,53 +69,6 @@ void set_brkpt(unsigned long addr, unsigned char mask, int flags, int mode) | |||
| 71 | : "memory"); | 69 | : "memory"); |
| 72 | } | 70 | } |
| 73 | 71 | ||
| 74 | /* Nice, simple, prom library does all the sweating for us. ;) */ | ||
| 75 | unsigned long __init prom_probe_memory (void) | ||
| 76 | { | ||
| 77 | register struct linux_mlist_p1275 *mlist; | ||
| 78 | register unsigned long bytes, base_paddr, tally; | ||
| 79 | register int i; | ||
| 80 | |||
| 81 | i = 0; | ||
| 82 | mlist = *prom_meminfo()->p1275_available; | ||
| 83 | bytes = tally = mlist->num_bytes; | ||
| 84 | base_paddr = mlist->start_adr; | ||
| 85 | |||
| 86 | sp_banks[0].base_addr = base_paddr; | ||
| 87 | sp_banks[0].num_bytes = bytes; | ||
| 88 | |||
| 89 | while (mlist->theres_more != (void *) 0) { | ||
| 90 | i++; | ||
| 91 | mlist = mlist->theres_more; | ||
| 92 | bytes = mlist->num_bytes; | ||
| 93 | tally += bytes; | ||
| 94 | if (i >= SPARC_PHYS_BANKS-1) { | ||
| 95 | printk ("The machine has more banks than " | ||
| 96 | "this kernel can support\n" | ||
| 97 | "Increase the SPARC_PHYS_BANKS " | ||
| 98 | "setting (currently %d)\n", | ||
| 99 | SPARC_PHYS_BANKS); | ||
| 100 | i = SPARC_PHYS_BANKS-1; | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | |||
| 104 | sp_banks[i].base_addr = mlist->start_adr; | ||
| 105 | sp_banks[i].num_bytes = mlist->num_bytes; | ||
| 106 | } | ||
| 107 | |||
| 108 | i++; | ||
| 109 | sp_banks[i].base_addr = 0xdeadbeefbeefdeadUL; | ||
| 110 | sp_banks[i].num_bytes = 0; | ||
| 111 | |||
| 112 | /* Now mask all bank sizes on a page boundary, it is all we can | ||
| 113 | * use anyways. | ||
| 114 | */ | ||
| 115 | for (i = 0; sp_banks[i].num_bytes != 0; i++) | ||
| 116 | sp_banks[i].num_bytes &= PAGE_MASK; | ||
| 117 | |||
| 118 | return tally; | ||
| 119 | } | ||
| 120 | |||
| 121 | static void __kprobes unhandled_fault(unsigned long address, | 72 | static void __kprobes unhandled_fault(unsigned long address, |
| 122 | struct task_struct *tsk, | 73 | struct task_struct *tsk, |
| 123 | struct pt_regs *regs) | 74 | struct pt_regs *regs) |
| @@ -242,7 +193,6 @@ static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn) | |||
| 242 | static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, | 193 | static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, |
| 243 | unsigned int insn, unsigned long address) | 194 | unsigned int insn, unsigned long address) |
| 244 | { | 195 | { |
| 245 | unsigned long g2; | ||
| 246 | unsigned char asi = ASI_P; | 196 | unsigned char asi = ASI_P; |
| 247 | 197 | ||
| 248 | if ((!insn) && (regs->tstate & TSTATE_PRIV)) | 198 | if ((!insn) && (regs->tstate & TSTATE_PRIV)) |
| @@ -273,11 +223,9 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, | |||
| 273 | } | 223 | } |
| 274 | } | 224 | } |
| 275 | 225 | ||
| 276 | g2 = regs->u_regs[UREG_G2]; | ||
| 277 | |||
| 278 | /* Is this in ex_table? */ | 226 | /* Is this in ex_table? */ |
| 279 | if (regs->tstate & TSTATE_PRIV) { | 227 | if (regs->tstate & TSTATE_PRIV) { |
| 280 | unsigned long fixup; | 228 | const struct exception_table_entry *entry; |
| 281 | 229 | ||
| 282 | if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) { | 230 | if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) { |
| 283 | if (insn & 0x2000) | 231 | if (insn & 0x2000) |
| @@ -288,10 +236,9 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, | |||
| 288 | 236 | ||
| 289 | /* Look in asi.h: All _S asis have LS bit set */ | 237 | /* Look in asi.h: All _S asis have LS bit set */ |
| 290 | if ((asi & 0x1) && | 238 | if ((asi & 0x1) && |
| 291 | (fixup = search_extables_range(regs->tpc, &g2))) { | 239 | (entry = search_exception_tables(regs->tpc))) { |
| 292 | regs->tpc = fixup; | 240 | regs->tpc = entry->fixup; |
| 293 | regs->tnpc = regs->tpc + 4; | 241 | regs->tnpc = regs->tpc + 4; |
| 294 | regs->u_regs[UREG_G2] = g2; | ||
| 295 | return; | 242 | return; |
| 296 | } | 243 | } |
| 297 | } else { | 244 | } else { |
| @@ -461,7 +408,7 @@ good_area: | |||
| 461 | } | 408 | } |
| 462 | 409 | ||
| 463 | up_read(&mm->mmap_sem); | 410 | up_read(&mm->mmap_sem); |
| 464 | goto fault_done; | 411 | return; |
| 465 | 412 | ||
| 466 | /* | 413 | /* |
| 467 | * Something tried to access memory that isn't in our memory map.. | 414 | * Something tried to access memory that isn't in our memory map.. |
| @@ -473,8 +420,7 @@ bad_area: | |||
| 473 | 420 | ||
| 474 | handle_kernel_fault: | 421 | handle_kernel_fault: |
| 475 | do_kernel_fault(regs, si_code, fault_code, insn, address); | 422 | do_kernel_fault(regs, si_code, fault_code, insn, address); |
| 476 | 423 | return; | |
| 477 | goto fault_done; | ||
| 478 | 424 | ||
| 479 | /* | 425 | /* |
| 480 | * We ran out of memory, or some other thing happened to us that made | 426 | * We ran out of memory, or some other thing happened to us that made |
| @@ -505,9 +451,4 @@ do_sigbus: | |||
| 505 | /* Kernel mode? Handle exceptions or die */ | 451 | /* Kernel mode? Handle exceptions or die */ |
| 506 | if (regs->tstate & TSTATE_PRIV) | 452 | if (regs->tstate & TSTATE_PRIV) |
| 507 | goto handle_kernel_fault; | 453 | goto handle_kernel_fault; |
| 508 | |||
| 509 | fault_done: | ||
| 510 | /* These values are no longer needed, clear them. */ | ||
| 511 | set_thread_fault_code(0); | ||
| 512 | current_thread_info()->fault_address = 0; | ||
| 513 | } | 454 | } |
