1/* 2 * arch/score/mm/tlbex.S 3 * 4 * Score Processor version. 5 * 6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd. 7 * Lennox Wu <lennox.wu@sunplusct.com> 8 * Chen Liqin <liqin.chen@sunplusct.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, see the file COPYING, or write 22 * to the Free Software Foundation, Inc., 23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 */ 25 26#include <asm/asmmacro.h> 27#include <asm/pgtable-bits.h> 28#include <asm/scoreregs.h> 29 30/* 31* After this macro runs, the pte faulted on is 32* in register PTE, a ptr into the table in which 33* the pte belongs is in PTR. 34*/ 35 .macro load_pte, pte, ptr 36 la \ptr, pgd_current 37 lw \ptr, [\ptr, 0] 38 mfcr \pte, cr6 39 srli \pte, \pte, 22 40 slli \pte, \pte, 2 41 add \ptr, \ptr, \pte 42 lw \ptr, [\ptr, 0] 43 mfcr \pte, cr6 44 srli \pte, \pte, 10 45 andi \pte, 0xffc 46 add \ptr, \ptr, \pte 47 lw \pte, [\ptr, 0] 48 .endm 49 50 .macro pte_reload, ptr 51 lw \ptr, [\ptr, 0] 52 mtcr \ptr, cr12 53 nop 54 nop 55 nop 56 nop 57 nop 58 .endm 59 60 .macro do_fault, write 61 SAVE_ALL 62 mfcr r6, cr6 63 mv r4, r0 64 ldi r5, \write 65 la r8, do_page_fault 66 brl r8 67 j ret_from_exception 68 .endm 69 70 .macro pte_writable, pte, ptr, label 71 andi \pte, 0x280 72 cmpi.c \pte, 0x280 73 bne \label 74 lw \pte, [\ptr, 0] /*reload PTE*/ 75 .endm 76 77/* 78 * Make PTE writable, update software status bits as well, 79 * then store at PTR. 80 */ 81 .macro pte_makewrite, pte, ptr 82 ori \pte, 0x426 83 sw \pte, [\ptr, 0] 84 .endm 85 86 .text 87ENTRY(score7_FTLB_refill_Handler) 88 la r31, pgd_current /* get pgd pointer */ 89 lw r31, [r31, 0] /* get the address of PGD */ 90 mfcr r30, cr6 91 srli r30, r30, 22 /* PGDIR_SHIFT = 22*/ 92 slli r30, r30, 2 93 add r31, r31, r30 94 lw r31, [r31, 0] /* get the address of the start address of PTE table */ 95 96 mfcr r30, cr9 97 andi r30, 0xfff /* equivalent to get PET index and right shift 2 bits */ 98 add r31, r31, r30 99 lw r30, [r31, 0] /* load pte entry */ 100 mtcr r30, cr12 101 nop 102 nop 103 nop 104 nop 105 nop 106 mtrtlb 107 nop 108 nop 109 nop 110 nop 111 nop 112 rte /* 6 cycles to make sure tlb entry works */ 113 114ENTRY(score7_KSEG_refill_Handler) 115 la r31, pgd_current /* get pgd pointer */ 116 lw r31, [r31, 0] /* get the address of PGD */ 117 mfcr r30, cr6 118 srli r30, r30, 22 /* PGDIR_SHIFT = 22 */ 119 slli r30, r30, 2 120 add r31, r31, r30 121 lw r31, [r31, 0] /* get the address of the start address of PTE table */ 122 123 mfcr r30, cr6 /* get Bad VPN */ 124 srli r30, r30, 10 125 andi r30, 0xffc /* PTE VPN mask (bit 11~2) */ 126 127 add r31, r31, r30 128 lw r30, [r31, 0] /* load pte entry */ 129 mtcr r30, cr12 130 nop 131 nop 132 nop 133 nop 134 nop 135 mtrtlb 136 nop 137 nop 138 nop 139 nop 140 nop 141 rte /* 6 cycles to make sure tlb entry works */ 142 143nopage_tlbl: 144 do_fault 0 /* Read */ 145 146ENTRY(handle_tlb_refill) 147 load_pte r30, r31 148 pte_writable r30, r31, handle_tlb_refill_nopage 149 pte_makewrite r30, r31 /* Access|Modify|Dirty|Valid */ 150 pte_reload r31 151 mtrtlb 152 nop 153 nop 154 nop 155 nop 156 nop 157 rte 158handle_tlb_refill_nopage: 159 do_fault 0 /* Read */ 160 161ENTRY(handle_tlb_invaild) 162 load_pte r30, r31 163 stlb /* find faulting entry */ 164 pte_writable r30, r31, handle_tlb_invaild_nopage 165 pte_makewrite r30, r31 /* Access|Modify|Dirty|Valid */ 166 pte_reload r31 167 mtptlb 168 nop 169 nop 170 nop 171 nop 172 nop 173 rte 174handle_tlb_invaild_nopage: 175 do_fault 0 /* Read */ 176 177ENTRY(handle_mod) 178 load_pte r30, r31 179 stlb /* find faulting entry */ 180 andi r30, _PAGE_WRITE /* Writable? */ 181 cmpz.c r30 182 beq nowrite_mod 183 lw r30, [r31, 0] /* reload into r30 */ 184 185 /* Present and writable bits set, set accessed and dirty bits. */ 186 pte_makewrite r30, r31 187 188 /* Now reload the entry into the tlb. */ 189 pte_reload r31 190 mtptlb 191 nop 192 nop 193 nop 194 nop 195 nop 196 rte 197 198nowrite_mod: 199 do_fault 1 /* Write */ 200