[15ebdf1f] | 1 | /* |
---|
| 2 | |
---|
| 3 | Based upon IDT provided code with the following release: |
---|
| 4 | |
---|
| 5 | This source code has been made available to you by IDT on an AS-IS |
---|
| 6 | basis. Anyone receiving this source is licensed under IDT copyrights |
---|
| 7 | to use it in any way he or she deems fit, including copying it, |
---|
| 8 | modifying it, compiling it, and redistributing it either with or |
---|
| 9 | without modifications. No license under IDT patents or patent |
---|
| 10 | applications is to be implied by the copyright license. |
---|
| 11 | |
---|
| 12 | Any user of this software should understand that IDT cannot provide |
---|
| 13 | technical support for this software and will not be responsible for |
---|
| 14 | any consequences resulting from the use of this software. |
---|
| 15 | |
---|
| 16 | Any person who transfers this source code or any derivative work must |
---|
| 17 | include the IDT copyright notice, this paragraph, and the preceeding |
---|
| 18 | two paragraphs in the transferred software. |
---|
| 19 | |
---|
| 20 | COPYRIGHT IDT CORPORATION 1996 |
---|
| 21 | LICENSED MATERIAL - PROGRAM PROPERTY OF IDT |
---|
| 22 | */ |
---|
| 23 | |
---|
| 24 | |
---|
| 25 | /* |
---|
| 26 | ** idttlb.s - fetch the registers associated with and the contents |
---|
| 27 | ** of the tlb. |
---|
| 28 | ** |
---|
| 29 | */ |
---|
| 30 | /* 950308: Ketan patched a few tlb functions that would not have worked.*/ |
---|
| 31 | #include <rtems/mips/iregdef.h> |
---|
| 32 | #include <rtems/mips/idtcpu.h> |
---|
| 33 | #include <rtems/asm.h> |
---|
| 34 | |
---|
| 35 | |
---|
| 36 | .text |
---|
| 37 | |
---|
| 38 | #if __mips == 1 |
---|
| 39 | /* |
---|
| 40 | ** ret_tlblo -- returns the 'entrylo' contents for the TLB |
---|
| 41 | ** 'c' callable - as ret_tlblo(index) - where index is the |
---|
| 42 | ** tlb entry to return the lo value for - if called from assembly |
---|
| 43 | ** language then index should be in register a0. |
---|
| 44 | */ |
---|
| 45 | FRAME(ret_tlblo,sp,0,ra) |
---|
| 46 | .set noreorder |
---|
| 47 | mfc0 t0,C0_SR # save sr |
---|
| 48 | nop |
---|
| 49 | and t0,~SR_PE # dont inadvertantly clear PE |
---|
| 50 | mtc0 zero,C0_SR # clear interrupts |
---|
| 51 | mfc0 t1,C0_TLBHI # save pid |
---|
| 52 | sll a0,TLBINX_INXSHIFT # position index |
---|
| 53 | mtc0 a0,C0_INX # write to index register |
---|
| 54 | nop |
---|
| 55 | tlbr # put tlb entry in entrylo and hi |
---|
| 56 | nop |
---|
| 57 | mfc0 v0,C0_TLBLO # get the requested entry lo |
---|
| 58 | mtc0 t1,C0_TLBHI # restore pid |
---|
| 59 | mtc0 t0,C0_SR # restore status register |
---|
| 60 | j ra |
---|
| 61 | nop |
---|
| 62 | .set reorder |
---|
| 63 | ENDFRAME(ret_tlblo) |
---|
| 64 | #endif |
---|
| 65 | #if __mips == 3 |
---|
| 66 | /* |
---|
| 67 | ** ret_tlblo[01] -- returns the 'entrylo' contents for the TLB |
---|
| 68 | ** 'c' callable - as ret_tlblo(index) - where index is the |
---|
| 69 | ** tlb entry to return the lo value for - if called from assembly |
---|
| 70 | ** language then index should be in register a0. |
---|
| 71 | */ |
---|
| 72 | FRAME(ret_tlblo0,sp,0,ra) |
---|
| 73 | mfc0 t0,C0_SR # save sr |
---|
| 74 | mtc0 zero,C0_SR # clear interrupts |
---|
| 75 | mfc0 t1,C0_TLBHI # save pid |
---|
| 76 | mtc0 a0,C0_INX # write to index register |
---|
| 77 | .set noreorder |
---|
| 78 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 79 | .set reorder |
---|
| 80 | tlbr # put tlb entry in entrylo and hi |
---|
| 81 | .set noreorder |
---|
| 82 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 83 | .set reorder |
---|
| 84 | mfc0 v0,C0_TLBLO0 # get the requested entry lo |
---|
| 85 | mtc0 t1,C0_TLBHI # restore pid |
---|
| 86 | mtc0 t0,C0_SR # restore status register |
---|
| 87 | j ra |
---|
| 88 | ENDFRAME(ret_tlblo0) |
---|
| 89 | |
---|
| 90 | FRAME(ret_tlblo1,sp,0,ra) |
---|
| 91 | mfc0 t0,C0_SR # save sr |
---|
| 92 | mtc0 zero,C0_SR # clear interrupts |
---|
| 93 | mfc0 t1,C0_TLBHI # save pid |
---|
| 94 | mtc0 a0,C0_INX # write to index register |
---|
| 95 | .set noreorder |
---|
| 96 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 97 | .set reorder |
---|
| 98 | tlbr # put tlb entry in entrylo and hi |
---|
| 99 | .set noreorder |
---|
| 100 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 101 | .set reorder |
---|
| 102 | mfc0 v0,C0_TLBLO1 # get the requested entry lo |
---|
| 103 | mtc0 t1,C0_TLBHI # restore pid |
---|
| 104 | mtc0 t0,C0_SR # restore status register |
---|
| 105 | j ra |
---|
| 106 | ENDFRAME(ret_tlblo1) |
---|
| 107 | |
---|
| 108 | /* |
---|
| 109 | ** ret_pagemask(index) -- return pagemask contents of tlb entry "index" |
---|
| 110 | */ |
---|
| 111 | FRAME(ret_pagemask,sp,0,ra) |
---|
| 112 | mfc0 t0,C0_SR # save sr |
---|
| 113 | mtc0 zero,C0_SR # disable interrupts |
---|
| 114 | mfc0 t1,C0_TLBHI # save current pid |
---|
| 115 | mtc0 a0,C0_INX # drop it in C0 register |
---|
| 116 | .set noreorder |
---|
| 117 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 118 | .set reorder |
---|
| 119 | tlbr # read entry to entry hi/lo |
---|
| 120 | .set noreorder |
---|
| 121 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 122 | .set reorder |
---|
| 123 | mfc0 v0,C0_PAGEMASK # to return value |
---|
| 124 | mtc0 t1,C0_TLBHI # restore current pid |
---|
| 125 | mtc0 t0,C0_SR # restore sr |
---|
| 126 | j ra |
---|
| 127 | ENDFRAME(ret_pagemask) |
---|
| 128 | |
---|
| 129 | /* |
---|
| 130 | ** ret_tlbwired(void) -- return wired register |
---|
| 131 | */ |
---|
| 132 | FRAME(ret_tlbwired,sp,0,ra) |
---|
| 133 | mfc0 v0,C0_WIRED |
---|
| 134 | j ra |
---|
| 135 | ENDFRAME(ret_tlbwired) |
---|
| 136 | #endif |
---|
| 137 | |
---|
| 138 | /* |
---|
| 139 | ** ret_tlbhi -- return the tlb entry high content for tlb entry |
---|
| 140 | ** index |
---|
| 141 | */ |
---|
| 142 | FRAME(ret_tlbhi,sp,0,ra) |
---|
| 143 | #if __mips == 1 |
---|
| 144 | .set noreorder |
---|
| 145 | mfc0 t0,C0_SR # save sr |
---|
| 146 | nop |
---|
| 147 | and t0,~SR_PE |
---|
| 148 | mtc0 zero,C0_SR # disable interrupts |
---|
| 149 | mfc0 t1,C0_TLBHI # save current pid |
---|
| 150 | sll a0,TLBINX_INXSHIFT # position index |
---|
| 151 | mtc0 a0,C0_INX # drop it in C0 register |
---|
| 152 | nop |
---|
| 153 | tlbr # read entry to entry hi/lo |
---|
| 154 | nop |
---|
| 155 | mfc0 v0,C0_TLBHI # to return value |
---|
| 156 | mtc0 t1,C0_TLBHI # restore current pid |
---|
| 157 | mtc0 t0,C0_SR # restore sr |
---|
| 158 | j ra |
---|
| 159 | nop |
---|
| 160 | .set reorder |
---|
| 161 | #endif |
---|
| 162 | #if __mips == 3 |
---|
| 163 | mfc0 t0,C0_SR # save sr |
---|
| 164 | mtc0 zero,C0_SR # disable interrupts |
---|
| 165 | mfc0 t1,C0_TLBHI # save current pid |
---|
| 166 | mtc0 a0,C0_INX # drop it in C0 register |
---|
| 167 | .set noreorder |
---|
| 168 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 169 | .set reorder |
---|
| 170 | tlbr # read entry to entry hi/lo0/lo1/mask |
---|
| 171 | .set noreorder |
---|
| 172 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 173 | .set reorder |
---|
| 174 | mfc0 v0,C0_TLBHI # to return value |
---|
| 175 | mtc0 t1,C0_TLBHI # restore current pid |
---|
| 176 | mtc0 t0,C0_SR # restore sr |
---|
| 177 | j ra |
---|
| 178 | #endif |
---|
| 179 | ENDFRAME(ret_tlbhi) |
---|
| 180 | |
---|
| 181 | /* |
---|
| 182 | ** ret_tlbpid() -- return tlb pid contained in the current entry hi |
---|
| 183 | */ |
---|
| 184 | FRAME(ret_tlbpid,sp,0,ra) |
---|
| 185 | #if __mips == 1 |
---|
| 186 | .set noreorder |
---|
[efdfd48] | 187 | mfc0 v0,C0_TLBHI # fetch tlb high |
---|
[15ebdf1f] | 188 | nop |
---|
| 189 | and v0,TLBHI_PIDMASK # isolate and position |
---|
| 190 | srl v0,TLBHI_PIDSHIFT |
---|
| 191 | j ra |
---|
| 192 | nop |
---|
| 193 | .set reorder |
---|
| 194 | #endif |
---|
| 195 | #if __mips == 3 |
---|
| 196 | mfc0 v0,C0_TLBHI # to return value |
---|
| 197 | nop |
---|
| 198 | and v0,TLBHI_PIDMASK |
---|
| 199 | j ra |
---|
| 200 | #endif |
---|
| 201 | ENDFRAME(ret_tlbpid) |
---|
| 202 | |
---|
| 203 | /* |
---|
| 204 | ** tlbprobe(address, pid) -- probe the tlb to see if address is currently |
---|
| 205 | ** mapped |
---|
| 206 | ** a0 = vpn - virtual page numbers are 0=0 1=0x1000, 2=0x2000... |
---|
| 207 | ** virtual page numbers for the r3000 are in |
---|
| 208 | ** entry hi bits 31-12 |
---|
| 209 | ** a1 = pid - this is a process id ranging from 0 to 63 |
---|
| 210 | ** this process id is shifted left 6 bits and or'ed into |
---|
| 211 | ** the entry hi register |
---|
| 212 | ** returns an index value (0-63) if successful -1 -f not |
---|
| 213 | */ |
---|
| 214 | FRAME(tlbprobe,sp,0,ra) |
---|
| 215 | #if __mips == 1 |
---|
| 216 | .set noreorder |
---|
| 217 | mfc0 t0,C0_SR /* fetch status reg */ |
---|
| 218 | and a0,TLBHI_VPNMASK /* isolate just the vpn */ |
---|
| 219 | and t0,~SR_PE /* don't inadvertantly clear pe */ |
---|
[efdfd48] | 220 | mtc0 zero,C0_SR |
---|
| 221 | mfc0 t1,C0_TLBHI |
---|
[15ebdf1f] | 222 | sll a1,TLBHI_PIDSHIFT /* possition the pid */ |
---|
| 223 | and a1,TLBHI_PIDMASK |
---|
| 224 | or a0,a1 /* build entry hi value */ |
---|
| 225 | mtc0 a0,C0_TLBHI |
---|
| 226 | nop |
---|
| 227 | tlbp /* do the probe */ |
---|
| 228 | nop |
---|
| 229 | mfc0 v1,C0_INX |
---|
| 230 | li v0,-1 |
---|
| 231 | bltz v1,1f |
---|
| 232 | nop |
---|
| 233 | sra v0,v1,TLBINX_INXSHIFT /* get index positioned for return */ |
---|
| 234 | 1: |
---|
| 235 | mtc0 t1,C0_TLBHI /* restore tlb hi */ |
---|
| 236 | mtc0 t0,C0_SR /* restore the status reg */ |
---|
| 237 | j ra |
---|
| 238 | nop |
---|
| 239 | .set reorder |
---|
| 240 | #endif |
---|
| 241 | #if __mips == 3 |
---|
| 242 | mfc0 t0,C0_SR # save sr |
---|
| 243 | mtc0 zero,C0_SR # disable interrupts |
---|
| 244 | mfc0 t1,C0_TLBHI # save current pid |
---|
| 245 | and a0,TLBHI_VPN2MASK # construct tlbhi for probe |
---|
| 246 | and a1,TLBHI_PIDMASK |
---|
| 247 | or a0,a1 |
---|
| 248 | mtc0 a0,C0_TLBHI |
---|
| 249 | .set noreorder |
---|
| 250 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 251 | .set reorder |
---|
| 252 | tlbp # probe entry to entry hi/lo0/lo1/mask |
---|
| 253 | .set noreorder |
---|
| 254 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 255 | .set reorder |
---|
| 256 | mfc0 v1,C0_INX |
---|
| 257 | li v0,-1 |
---|
| 258 | bltz v1,1f |
---|
| 259 | move v0,v1 |
---|
| 260 | 1: mtc0 t1,C0_TLBHI # restore current pid |
---|
| 261 | mtc0 t0,C0_SR # restore sr |
---|
| 262 | j ra |
---|
| 263 | #endif |
---|
| 264 | ENDFRAME(tlbprobe) |
---|
| 265 | |
---|
| 266 | /* |
---|
| 267 | ** resettlb(index) Invalidate the TLB entry specified by index |
---|
| 268 | */ |
---|
| 269 | FRAME(resettlb,sp,0,ra) |
---|
| 270 | #if __mips == 1 |
---|
| 271 | .set noreorder |
---|
[efdfd48] | 272 | mfc0 t0,C0_TLBHI # fetch the current hi |
---|
[15ebdf1f] | 273 | mfc0 v0,C0_SR # fetch the status reg. |
---|
| 274 | li t2,K0BASE&TLBHI_VPNMASK |
---|
| 275 | and v0,~SR_PE # dont inadvertantly clear PE |
---|
| 276 | mtc0 zero,C0_SR |
---|
| 277 | mtc0 t2,C0_TLBHI # set up tlbhi |
---|
| 278 | mtc0 zero,C0_TLBLO |
---|
| 279 | sll a0,TLBINX_INXSHIFT |
---|
| 280 | mtc0 a0,C0_INX |
---|
| 281 | nop |
---|
| 282 | tlbwi # do actual invalidate |
---|
| 283 | nop |
---|
| 284 | mtc0 t0,C0_TLBHI |
---|
| 285 | mtc0 v0,C0_SR |
---|
| 286 | j ra |
---|
| 287 | nop |
---|
| 288 | .set reorder |
---|
| 289 | #endif |
---|
| 290 | #if __mips == 3 |
---|
| 291 | li t2,K0BASE&TLBHI_VPN2MASK |
---|
| 292 | mfc0 t0,C0_TLBHI # save current TLBHI |
---|
| 293 | mfc0 v0,C0_SR # save SR and disable interrupts |
---|
| 294 | mtc0 zero,C0_SR |
---|
| 295 | mtc0 t2,C0_TLBHI # invalidate entry |
---|
| 296 | mtc0 zero,C0_TLBLO0 |
---|
| 297 | mtc0 zero,C0_TLBLO1 |
---|
| 298 | mtc0 a0,C0_INX |
---|
| 299 | .set noreorder |
---|
| 300 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 301 | .set reorder |
---|
| 302 | tlbwi |
---|
| 303 | .set noreorder |
---|
| 304 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 305 | .set reorder |
---|
| 306 | mtc0 t0,C0_TLBHI |
---|
| 307 | mtc0 v0,C0_SR |
---|
| 308 | j ra |
---|
| 309 | #endif |
---|
| 310 | ENDFRAME(resettlb) |
---|
| 311 | |
---|
| 312 | #if __mips == 1 |
---|
| 313 | /* |
---|
| 314 | ** Setup TLB entry |
---|
| 315 | ** |
---|
| 316 | ** map_tlb(index, tlbhi, phypage) |
---|
| 317 | ** a0 = TLB entry index |
---|
| 318 | ** a1 = virtual page number and PID |
---|
| 319 | ** a2 = physical page |
---|
| 320 | */ |
---|
| 321 | FRAME(map_tlb,sp,0,ra) |
---|
| 322 | .set noreorder |
---|
| 323 | sll a0,TLBINX_INXSHIFT |
---|
| 324 | mfc0 v0,C0_SR # fetch the current status |
---|
| 325 | mfc0 a3,C0_TLBHI # save the current hi |
---|
| 326 | and v0,~SR_PE # dont inadvertantly clear parity |
---|
| 327 | |
---|
| 328 | mtc0 zero,C0_SR |
---|
| 329 | mtc0 a1,C0_TLBHI # set the hi entry |
---|
[efdfd48] | 330 | mtc0 a2,C0_TLBLO # set the lo entry |
---|
[15ebdf1f] | 331 | mtc0 a0,C0_INX # load the index |
---|
| 332 | nop |
---|
| 333 | tlbwi # put the hi/lo in tlb entry indexed |
---|
| 334 | nop |
---|
[efdfd48] | 335 | mtc0 a3,C0_TLBHI # put back the tlb hi reg |
---|
| 336 | mtc0 v0,C0_SR # restore the status register |
---|
[15ebdf1f] | 337 | j ra |
---|
| 338 | nop |
---|
| 339 | .set reorder |
---|
| 340 | ENDFRAME(map_tlb) |
---|
| 341 | #endif |
---|
| 342 | #if __mips == 3 |
---|
| 343 | /* |
---|
| 344 | ** Setup R4000 TLB entry |
---|
| 345 | ** |
---|
| 346 | ** map_tlb4000(mask_index, tlbhi, pte_even, pte_odd) |
---|
| 347 | ** a0 = TLB entry index and page mask |
---|
| 348 | ** a1 = virtual page number and PID |
---|
| 349 | ** a2 = pte -- contents of even pte |
---|
| 350 | ** a3 = pte -- contents of odd pte |
---|
| 351 | */ |
---|
| 352 | FRAME(map_tlb4000,sp,0,ra) |
---|
| 353 | and t2,a0,TLBPGMASK_MASK |
---|
| 354 | and a0,TLBINX_INXMASK |
---|
| 355 | mfc0 t1,C0_TLBHI # save current TLBPID |
---|
| 356 | mfc0 v0,C0_SR # save SR and disable interrupts |
---|
| 357 | mtc0 zero,C0_SR |
---|
[efdfd48] | 358 | mtc0 t2,C0_PAGEMASK # set |
---|
[15ebdf1f] | 359 | mtc0 a1,C0_TLBHI # set VPN and TLBPID |
---|
| 360 | mtc0 a2,C0_TLBLO0 # set PPN and access bits |
---|
| 361 | mtc0 a3,C0_TLBLO1 # set PPN and access bits |
---|
| 362 | mtc0 a0,C0_INX # set INDEX to wired entry |
---|
| 363 | .set noreorder |
---|
| 364 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 365 | .set reorder |
---|
| 366 | tlbwi # drop it in |
---|
| 367 | .set noreorder |
---|
| 368 | nop; nop; nop; nop; nop; nop; nop; nop |
---|
| 369 | .set reorder |
---|
| 370 | mtc0 t1,C0_TLBHI # restore TLBPID |
---|
| 371 | mtc0 v0,C0_SR # restore SR |
---|
| 372 | j ra |
---|
| 373 | ENDFRAME(map_tlb4000) |
---|
| 374 | #endif |
---|
| 375 | |
---|
| 376 | |
---|
| 377 | /* |
---|
| 378 | ** Set current TLBPID. This assumes PID is positioned correctly in reg. |
---|
| 379 | ** a0. |
---|
| 380 | */ |
---|
| 381 | FRAME(set_tlbpid,sp,0,ra) |
---|
| 382 | .set noreorder |
---|
| 383 | mtc0 a0,C0_TLBHI |
---|
| 384 | j ra |
---|
| 385 | nop |
---|
| 386 | .set reorder |
---|
| 387 | ENDFRAME(set_tlbpid) |
---|
| 388 | |
---|