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