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 | } |