2 * Copyright (C) 2003 Axis Communications AB
4 * Authors: Mikael Starvik (starvik@axis.com)
6 * Code for the fault low-level handling routines.
11 #include <asm/pgtable.h>
13 ; Save all register. Must save in same order as struct pt_regs.
35 ; Bus fault handler. Extracts relevant information and calls mm subsystem
36 ; to handle the fault.
37 .macro MMU_BUS_FAULT_HANDLER handler, mmu, we, ex
41 move \mmu, $srs ; Select MMU support register bank
42 move.d $sp, $r11 ; regs
43 moveq 1, $r12 ; protection fault
44 moveq \we, $r13 ; write exception?
45 orq \ex << 1, $r13 ; execute?
46 move $s3, $r10 ; rw_mm_cause
47 and.d ~8191, $r10 ; Get faulting page start address
55 ; Refill handler. Three cases may occur:
56 ; 1. PMD and PTE exists in mm subsystem but not in TLB
57 ; 2. PMD exists but not PTE
58 ; 3. PMD doesn't exist
59 ; The code below handles case 1 and calls the mm subsystem for case 2 and 3.
60 ; Do not touch this code without very good reasons and extensive testing.
61 ; Note that the code is optimized to minimize stalls (makes the code harder
64 ; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each
65 ; PMD holds 16 MB of virtual memory.
66 ; Bits 0-12 : Offset within a page
67 ; Bits 13-23 : PTE offset within a PMD
68 ; Bits 24-31 : PMD offset within the PGD
70 .macro MMU_REFILL_HANDLER handler, mmu
74 ; (The pipeline stalls for one cycle; $sp used as address in the next cycle.)
77 move \mmu, $srs ; Select MMU support register bank
84 move.d per_cpu__current_pgd, $acr ; PGD
87 move $s3, $r0 ; rw_mm_cause
88 lsrq 24, $r0 ; Get PMD index into PGD (bit 24-31)
89 move.d [$acr], $acr ; PGD for the current process
90 addi $r0.d, $acr, $acr
91 move $s3, $r0 ; rw_mm_cause
92 move.d [$acr], $acr ; Get PMD
96 and.w PAGE_MASK, $acr ; Remove PMD flags
97 and.d 0x7ff, $r0 ; Get PTE index into PMD (bit 13-23)
98 addi $r0.d, $acr, $acr
99 move.d [$acr], $acr ; Get PTE
101 move.d [$sp+], $r0 ; Pop r0 in delayslot
110 1: ; PMD missing, let the mm subsystem fix it up.
111 move.d [$sp+], $r0 ; Pop r0
112 2: ; PTE missing, let the mm subsystem fix it up.
118 move.d $sp, $r11 ; regs
119 clear.d $r12 ; Not a protection fault
120 move.w PAGE_MASK, $acr
121 move $s3, $r10 ; rw_mm_cause
122 btstq 9, $r10 ; Check if write access
124 and.w PAGE_MASK, $r10 ; Get VPN (virtual address)
132 ; This is the MMU bus fault handlers.
134 MMU_REFILL_HANDLER i_mmu_refill, 1
135 MMU_BUS_FAULT_HANDLER i_mmu_invalid, 1, 0, 0
136 MMU_BUS_FAULT_HANDLER i_mmu_access, 1, 0, 0
137 MMU_BUS_FAULT_HANDLER i_mmu_execute, 1, 0, 1
138 MMU_REFILL_HANDLER d_mmu_refill, 2
139 MMU_BUS_FAULT_HANDLER d_mmu_invalid, 2, 0, 0
140 MMU_BUS_FAULT_HANDLER d_mmu_access, 2, 0, 0
141 MMU_BUS_FAULT_HANDLER d_mmu_write, 2, 1, 0