11 #include <linux/signal.h>
12 #include <linux/sched.h>
13 #include <linux/kernel.h>
14 #include <linux/errno.h>
15 #include <linux/string.h>
16 #include <linux/types.h>
17 #include <linux/ptrace.h>
18 #include <linux/mman.h>
23 #include <linux/tty.h>
26 #include <linux/module.h>
29 #include <asm/uaccess.h>
30 #include <asm/hardirq.h>
31 #include <asm/mmu_context.h>
32 #include <asm/tlbflush.h>
34 extern void die(
const char *,
struct pt_regs *,
long);
39 #define tlb_entry_i tlb_entry_i_dat
40 #define tlb_entry_d tlb_entry_d_dat
44 #define tlb_entry_i tlb_entry_i_dat[smp_processor_id()]
45 #define tlb_entry_d tlb_entry_d_dat[smp_processor_id()]
69 #define ACE_PROTECTION 1
71 #define ACE_USERMODE 4
72 #define ACE_INSTRUCTION 8
118 goto bad_area_nosemaphore;
136 if ((error_code & ACE_USERMODE) == 0 &&
138 goto bad_area_nosemaphore;
147 if (!(vma->
vm_flags & VM_GROWSDOWN))
150 if (error_code & ACE_USERMODE) {
157 if (address + 4 < regs->
spu)
180 if (!(vma->
vm_flags & (VM_READ | VM_EXEC)))
196 set_thread_fault_code(error_code);
198 if (
unlikely(fault & VM_FAULT_ERROR)) {
199 if (fault & VM_FAULT_OOM)
201 else if (fault & VM_FAULT_SIGBUS)
205 if (fault & VM_FAULT_MAJOR)
209 set_thread_fault_code(0);
220 bad_area_nosemaphore:
222 if (error_code & ACE_USERMODE) {
229 info.si_addr = (
void __user *)address;
250 printk(
" at virtual address %08lx\n",address);
253 page = *(
unsigned long *)
MPTB;
254 page = ((
unsigned long *) page)[address >>
PGDIR_SHIFT];
258 address &= 0x003ff000;
262 die(
"Oops", regs, error_code);
272 if (!(error_code & ACE_USERMODE))
281 if (!(error_code & ACE_USERMODE))
290 info.si_addr = (
void __user *)address;
309 pgd = offset + (
pgd_t *)pgd;
331 set_thread_fault_code(error_code);
333 set_thread_fault_code(0);
341 #define TLB_MASK (NR_TLB_ENTRIES - 1)
342 #define ITLB_END (unsigned long *)(ITLB_BASE + (NR_TLB_ENTRIES * 8))
343 #define DTLB_END (unsigned long *)(DTLB_BASE + (NR_TLB_ENTRIES * 8))
347 volatile unsigned long *entry1, *entry2;
348 unsigned long pte_data,
flags;
349 unsigned int *entry_dat;
359 vaddr = (vaddr &
PAGE_MASK) | get_asid();
363 #ifdef CONFIG_CHIP_OPSP
366 if (*entry1++ == vaddr) {
367 set_tlb_data(entry1, pte_data);
374 if (*entry2++ == vaddr) {
375 set_tlb_data(entry2, pte_data);
387 "seth %0, #high(%4) \n\t"
388 "st %2, @(%5, %0) \n\t"
390 "st %1, @(%6, %0) \n\t"
391 "add3 r4, %0, %7 \n\t"
394 "ld %1, @(%6, %0) \n\t"
400 :
"=&r" (entry1),
"=&r" (entry2)
429 entry1 = entry2 + (((*entry_dat - 1) &
TLB_MASK) << 1);
432 if (!(entry1[1] & 2))
435 if (entry1 != entry2)
441 if (i >= NR_TLB_ENTRIES) {
442 entry1 = entry2 + (*entry_dat << 1);
443 *entry_dat = (*entry_dat + 1) &
TLB_MASK;
446 set_tlb_data(entry1, pte_data);
496 while (start < end) {