1/* tlb-miss.S: TLB miss handlers 2 * 3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12#include <linux/sys.h> 13#include <linux/linkage.h> 14#include <asm/page.h> 15#include <asm/pgtable.h> 16#include <asm/spr-regs.h> 17 18 .section .text..tlbmiss 19 .balign 4 20 21 .globl __entry_insn_mmu_miss 22__entry_insn_mmu_miss: 23 break 24 nop 25 26 .globl __entry_insn_mmu_exception 27__entry_insn_mmu_exception: 28 break 29 nop 30 31 .globl __entry_data_mmu_miss 32__entry_data_mmu_miss: 33 break 34 nop 35 36 .globl __entry_data_mmu_exception 37__entry_data_mmu_exception: 38 break 39 nop 40 41############################################################################### 42# 43# handle a lookup failure of one sort or another in a kernel TLB handler 44# On entry: 45# GR29 - faulting address 46# SCR2 - saved CCR 47# 48############################################################################### 49 .type __tlb_kernel_fault,@function 50__tlb_kernel_fault: 51 # see if we're supposed to re-enable single-step mode upon return 52 sethi.p %hi(__break_tlb_miss_return_break),gr30 53 setlo %lo(__break_tlb_miss_return_break),gr30 54 movsg pcsr,gr31 55 56 subcc gr31,gr30,gr0,icc0 57 beq icc0,#0,__tlb_kernel_fault_sstep 58 59 movsg scr2,gr30 60 movgs gr30,ccr 61 movgs gr29,scr2 /* save EAR0 value */ 62 sethi.p %hi(__kernel_current_task),gr29 63 setlo %lo(__kernel_current_task),gr29 64 ldi.p @(gr29,#0),gr29 /* restore GR29 */ 65 66 bra __entry_kernel_handle_mmu_fault 67 68 # we've got to re-enable single-stepping 69__tlb_kernel_fault_sstep: 70 sethi.p %hi(__break_tlb_miss_real_return_info),gr30 71 setlo %lo(__break_tlb_miss_real_return_info),gr30 72 lddi @(gr30,0),gr30 73 movgs gr30,pcsr 74 movgs gr31,psr 75 76 movsg scr2,gr30 77 movgs gr30,ccr 78 movgs gr29,scr2 /* save EAR0 value */ 79 sethi.p %hi(__kernel_current_task),gr29 80 setlo %lo(__kernel_current_task),gr29 81 ldi.p @(gr29,#0),gr29 /* restore GR29 */ 82 bra __entry_kernel_handle_mmu_fault_sstep 83 84 .size __tlb_kernel_fault, .-__tlb_kernel_fault 85 86############################################################################### 87# 88# handle a lookup failure of one sort or another in a user TLB handler 89# On entry: 90# GR28 - faulting address 91# SCR2 - saved CCR 92# 93############################################################################### 94 .type __tlb_user_fault,@function 95__tlb_user_fault: 96 # see if we're supposed to re-enable single-step mode upon return 97 sethi.p %hi(__break_tlb_miss_return_break),gr30 98 setlo %lo(__break_tlb_miss_return_break),gr30 99 movsg pcsr,gr31 100 subcc gr31,gr30,gr0,icc0 101 beq icc0,#0,__tlb_user_fault_sstep 102 103 movsg scr2,gr30 104 movgs gr30,ccr 105 bra __entry_uspace_handle_mmu_fault 106 107 # we've got to re-enable single-stepping 108__tlb_user_fault_sstep: 109 sethi.p %hi(__break_tlb_miss_real_return_info),gr30 110 setlo %lo(__break_tlb_miss_real_return_info),gr30 111 lddi @(gr30,0),gr30 112 movgs gr30,pcsr 113 movgs gr31,psr 114 movsg scr2,gr30 115 movgs gr30,ccr 116 bra __entry_uspace_handle_mmu_fault_sstep 117 118 .size __tlb_user_fault, .-__tlb_user_fault 119 120############################################################################### 121# 122# Kernel instruction TLB miss handler 123# On entry: 124# GR1 - kernel stack pointer 125# GR28 - saved exception frame pointer 126# GR29 - faulting address 127# GR31 - EAR0 ^ SCR0 128# SCR0 - base of virtual range covered by cached PGE from last ITLB miss (or 0xffffffff) 129# DAMR3 - mapped page directory 130# DAMR4 - mapped page table as matched by SCR0 131# 132############################################################################### 133 .globl __entry_kernel_insn_tlb_miss 134 .type __entry_kernel_insn_tlb_miss,@function 135__entry_kernel_insn_tlb_miss: 136#if 0 137 sethi.p %hi(0xe1200004),gr30 138 setlo %lo(0xe1200004),gr30 139 st gr0,@(gr30,gr0) 140 sethi.p %hi(0xffc00100),gr30 141 setlo %lo(0xffc00100),gr30 142 sth gr30,@(gr30,gr0) 143 membar 144#endif 145 146 movsg ccr,gr30 /* save CCR */ 147 movgs gr30,scr2 148 149 # see if the cached page table mapping is appropriate 150 srlicc.p gr31,#26,gr0,icc0 151 setlos 0x3ffc,gr30 152 srli.p gr29,#12,gr31 /* use EAR0[25:14] as PTE index */ 153 bne icc0,#0,__itlb_k_PTD_miss 154 155__itlb_k_PTD_mapped: 156 # access the PTD with EAR0[25:14] 157 # - DAMLR4 points to the virtual address of the appropriate page table 158 # - the PTD holds 4096 PTEs 159 # - the PTD must be accessed uncached 160 # - the PTE must be marked accessed if it was valid 161 # 162 and gr31,gr30,gr31 163 movsg damlr4,gr30 164 add gr30,gr31,gr31 165 ldi @(gr31,#0),gr30 /* fetch the PTE */ 166 andicc gr30,#_PAGE_PRESENT,gr0,icc0 167 ori.p gr30,#_PAGE_ACCESSED,gr30 168 beq icc0,#0,__tlb_kernel_fault /* jump if PTE invalid */ 169 sti.p gr30,@(gr31,#0) /* update the PTE */ 170 andi gr30,#~_PAGE_ACCESSED,gr30 171 172 # we're using IAMR1 as an extra TLB entry 173 # - punt the entry here (if valid) to the real TLB and then replace with the new PTE 174 # - need to check DAMR1 lest we cause an multiple-DAT-hit exception 175 # - IAMPR1 has no WP bit, and we mustn't lose WP information 176 movsg iampr1,gr31 177 andicc gr31,#xAMPRx_V,gr0,icc0 178 setlos.p 0xfffff000,gr31 179 beq icc0,#0,__itlb_k_nopunt /* punt not required */ 180 181 movsg iamlr1,gr31 182 movgs gr31,tplr /* set TPLR.CXN */ 183 tlbpr gr31,gr0,#4,#0 /* delete matches from TLB, IAMR1, DAMR1 */ 184 185 movsg dampr1,gr31 186 ori gr31,#xAMPRx_V,gr31 /* entry was invalidated by tlbpr #4 */ 187 movgs gr31,tppr 188 movsg iamlr1,gr31 /* set TPLR.CXN */ 189 movgs gr31,tplr 190 tlbpr gr31,gr0,#2,#0 /* save to the TLB */ 191 movsg tpxr,gr31 /* check the TLB write error flag */ 192 andicc.p gr31,#TPXR_E,gr0,icc0 193 setlos #0xfffff000,gr31 194 bne icc0,#0,__tlb_kernel_fault 195 196__itlb_k_nopunt: 197 198 # assemble the new TLB entry 199 and gr29,gr31,gr29 200 movsg cxnr,gr31 201 or gr29,gr31,gr29 202 movgs gr29,iamlr1 /* xAMLR = address | context number */ 203 movgs gr30,iampr1 204 movgs gr29,damlr1 205 movgs gr30,dampr1 206 207 # return, restoring registers 208 movsg scr2,gr30 209 movgs gr30,ccr 210 sethi.p %hi(__kernel_current_task),gr29 211 setlo %lo(__kernel_current_task),gr29 212 ldi @(gr29,#0),gr29 213 rett #0 214 beq icc0,#3,0 /* prevent icache prefetch */ 215 216 # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more 217 # appropriate page table and map that instead 218 # - access the PGD with EAR0[31:26] 219 # - DAMLR3 points to the virtual address of the page directory 220 # - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables 221__itlb_k_PTD_miss: 222 srli gr29,#26,gr31 /* calculate PGE offset */ 223 slli gr31,#8,gr31 /* and clear bottom bits */ 224 225 movsg damlr3,gr30 226 ld @(gr31,gr30),gr30 /* access the PGE */ 227 228 andicc.p gr30,#_PAGE_PRESENT,gr0,icc0 229 andicc gr30,#xAMPRx_SS,gr0,icc1 230 231 # map this PTD instead and record coverage address 232 ori.p gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30 233 beq icc0,#0,__tlb_kernel_fault /* jump if PGE not present */ 234 slli.p gr31,#18,gr31 235 bne icc1,#0,__itlb_k_bigpage 236 movgs gr30,dampr4 237 movgs gr31,scr0 238 239 # we can now resume normal service 240 setlos 0x3ffc,gr30 241 srli.p gr29,#12,gr31 /* use EAR0[25:14] as PTE index */ 242 bra __itlb_k_PTD_mapped 243 244__itlb_k_bigpage: 245 break 246 nop 247 248 .size __entry_kernel_insn_tlb_miss, .-__entry_kernel_insn_tlb_miss 249 250############################################################################### 251# 252# Kernel data TLB miss handler 253# On entry: 254# GR1 - kernel stack pointer 255# GR28 - saved exception frame pointer 256# GR29 - faulting address 257# GR31 - EAR0 ^ SCR1 258# SCR1 - base of virtual range covered by cached PGE from last DTLB miss (or 0xffffffff) 259# DAMR3 - mapped page directory 260# DAMR5 - mapped page table as matched by SCR1 261# 262############################################################################### 263 .globl __entry_kernel_data_tlb_miss 264 .type __entry_kernel_data_tlb_miss,@function 265__entry_kernel_data_tlb_miss: 266#if 0 267 sethi.p %hi(0xe1200004),gr30 268 setlo %lo(0xe1200004),gr30 269 st gr0,@(gr30,gr0) 270 sethi.p %hi(0xffc00100),gr30 271 setlo %lo(0xffc00100),gr30 272 sth gr30,@(gr30,gr0) 273 membar 274#endif 275 276 movsg ccr,gr30 /* save CCR */ 277 movgs gr30,scr2 278 279 # see if the cached page table mapping is appropriate 280 srlicc.p gr31,#26,gr0,icc0 281 setlos 0x3ffc,gr30 282 srli.p gr29,#12,gr31 /* use EAR0[25:14] as PTE index */ 283 bne icc0,#0,__dtlb_k_PTD_miss 284 285__dtlb_k_PTD_mapped: 286 # access the PTD with EAR0[25:14] 287 # - DAMLR5 points to the virtual address of the appropriate page table 288 # - the PTD holds 4096 PTEs 289 # - the PTD must be accessed uncached 290 # - the PTE must be marked accessed if it was valid 291 # 292 and gr31,gr30,gr31 293 movsg damlr5,gr30 294 add gr30,gr31,gr31 295 ldi @(gr31,#0),gr30 /* fetch the PTE */ 296 andicc gr30,#_PAGE_PRESENT,gr0,icc0 297 ori.p gr30,#_PAGE_ACCESSED,gr30 298 beq icc0,#0,__tlb_kernel_fault /* jump if PTE invalid */ 299 sti.p gr30,@(gr31,#0) /* update the PTE */ 300 andi gr30,#~_PAGE_ACCESSED,gr30 301 302 # we're using DAMR1 as an extra TLB entry 303 # - punt the entry here (if valid) to the real TLB and then replace with the new PTE 304 # - need to check IAMR1 lest we cause an multiple-DAT-hit exception 305 movsg dampr1,gr31 306 andicc gr31,#xAMPRx_V,gr0,icc0 307 setlos.p 0xfffff000,gr31 308 beq icc0,#0,__dtlb_k_nopunt /* punt not required */ 309 310 movsg damlr1,gr31 311 movgs gr31,tplr /* set TPLR.CXN */ 312 tlbpr gr31,gr0,#4,#0 /* delete matches from TLB, IAMR1, DAMR1 */ 313 314 movsg dampr1,gr31 315 ori gr31,#xAMPRx_V,gr31 /* entry was invalidated by tlbpr #4 */ 316 movgs gr31,tppr 317 movsg damlr1,gr31 /* set TPLR.CXN */ 318 movgs gr31,tplr 319 tlbpr gr31,gr0,#2,#0 /* save to the TLB */ 320 movsg tpxr,gr31 /* check the TLB write error flag */ 321 andicc.p gr31,#TPXR_E,gr0,icc0 322 setlos #0xfffff000,gr31 323 bne icc0,#0,__tlb_kernel_fault 324 325__dtlb_k_nopunt: 326 327 # assemble the new TLB entry 328 and gr29,gr31,gr29 329 movsg cxnr,gr31 330 or gr29,gr31,gr29 331 movgs gr29,iamlr1 /* xAMLR = address | context number */ 332 movgs gr30,iampr1 333 movgs gr29,damlr1 334 movgs gr30,dampr1 335 336 # return, restoring registers 337 movsg scr2,gr30 338 movgs gr30,ccr 339 sethi.p %hi(__kernel_current_task),gr29 340 setlo %lo(__kernel_current_task),gr29 341 ldi @(gr29,#0),gr29 342 rett #0 343 beq icc0,#3,0 /* prevent icache prefetch */ 344 345 # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more 346 # appropriate page table and map that instead 347 # - access the PGD with EAR0[31:26] 348 # - DAMLR3 points to the virtual address of the page directory 349 # - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables 350__dtlb_k_PTD_miss: 351 srli gr29,#26,gr31 /* calculate PGE offset */ 352 slli gr31,#8,gr31 /* and clear bottom bits */ 353 354 movsg damlr3,gr30 355 ld @(gr31,gr30),gr30 /* access the PGE */ 356 357 andicc.p gr30,#_PAGE_PRESENT,gr0,icc0 358 andicc gr30,#xAMPRx_SS,gr0,icc1 359 360 # map this PTD instead and record coverage address 361 ori.p gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30 362 beq icc0,#0,__tlb_kernel_fault /* jump if PGE not present */ 363 slli.p gr31,#18,gr31 364 bne icc1,#0,__dtlb_k_bigpage 365 movgs gr30,dampr5 366 movgs gr31,scr1 367 368 # we can now resume normal service 369 setlos 0x3ffc,gr30 370 srli.p gr29,#12,gr31 /* use EAR0[25:14] as PTE index */ 371 bra __dtlb_k_PTD_mapped 372 373__dtlb_k_bigpage: 374 break 375 nop 376 377 .size __entry_kernel_data_tlb_miss, .-__entry_kernel_data_tlb_miss 378 379############################################################################### 380# 381# Userspace instruction TLB miss handler (with PGE prediction) 382# On entry: 383# GR28 - faulting address 384# GR31 - EAR0 ^ SCR0 385# SCR0 - base of virtual range covered by cached PGE from last ITLB miss (or 0xffffffff) 386# DAMR3 - mapped page directory 387# DAMR4 - mapped page table as matched by SCR0 388# 389############################################################################### 390 .globl __entry_user_insn_tlb_miss 391 .type __entry_user_insn_tlb_miss,@function 392__entry_user_insn_tlb_miss: 393#if 0 394 sethi.p %hi(0xe1200004),gr30 395 setlo %lo(0xe1200004),gr30 396 st gr0,@(gr30,gr0) 397 sethi.p %hi(0xffc00100),gr30 398 setlo %lo(0xffc00100),gr30 399 sth gr30,@(gr30,gr0) 400 membar 401#endif 402 403 movsg ccr,gr30 /* save CCR */ 404 movgs gr30,scr2 405 406 # see if the cached page table mapping is appropriate 407 srlicc.p gr31,#26,gr0,icc0 408 setlos 0x3ffc,gr30 409 srli.p gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ 410 bne icc0,#0,__itlb_u_PTD_miss 411 412__itlb_u_PTD_mapped: 413 # access the PTD with EAR0[25:14] 414 # - DAMLR4 points to the virtual address of the appropriate page table 415 # - the PTD holds 4096 PTEs 416 # - the PTD must be accessed uncached 417 # - the PTE must be marked accessed if it was valid 418 # 419 and gr31,gr30,gr31 420 movsg damlr4,gr30 421 add gr30,gr31,gr31 422 ldi @(gr31,#0),gr30 /* fetch the PTE */ 423 andicc gr30,#_PAGE_PRESENT,gr0,icc0 424 ori.p gr30,#_PAGE_ACCESSED,gr30 425 beq icc0,#0,__tlb_user_fault /* jump if PTE invalid */ 426 sti.p gr30,@(gr31,#0) /* update the PTE */ 427 andi gr30,#~_PAGE_ACCESSED,gr30 428 429 # we're using IAMR1/DAMR1 as an extra TLB entry 430 # - punt the entry here (if valid) to the real TLB and then replace with the new PTE 431 movsg dampr1,gr31 432 andicc gr31,#xAMPRx_V,gr0,icc0 433 setlos.p 0xfffff000,gr31 434 beq icc0,#0,__itlb_u_nopunt /* punt not required */ 435 436 movsg dampr1,gr31 437 movgs gr31,tppr 438 movsg damlr1,gr31 /* set TPLR.CXN */ 439 movgs gr31,tplr 440 tlbpr gr31,gr0,#2,#0 /* save to the TLB */ 441 movsg tpxr,gr31 /* check the TLB write error flag */ 442 andicc.p gr31,#TPXR_E,gr0,icc0 443 setlos #0xfffff000,gr31 444 bne icc0,#0,__tlb_user_fault 445 446__itlb_u_nopunt: 447 448 # assemble the new TLB entry 449 and gr28,gr31,gr28 450 movsg cxnr,gr31 451 or gr28,gr31,gr28 452 movgs gr28,iamlr1 /* xAMLR = address | context number */ 453 movgs gr30,iampr1 454 movgs gr28,damlr1 455 movgs gr30,dampr1 456 457 # return, restoring registers 458 movsg scr2,gr30 459 movgs gr30,ccr 460 rett #0 461 beq icc0,#3,0 /* prevent icache prefetch */ 462 463 # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more 464 # appropriate page table and map that instead 465 # - access the PGD with EAR0[31:26] 466 # - DAMLR3 points to the virtual address of the page directory 467 # - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables 468__itlb_u_PTD_miss: 469 srli gr28,#26,gr31 /* calculate PGE offset */ 470 slli gr31,#8,gr31 /* and clear bottom bits */ 471 472 movsg damlr3,gr30 473 ld @(gr31,gr30),gr30 /* access the PGE */ 474 475 andicc.p gr30,#_PAGE_PRESENT,gr0,icc0 476 andicc gr30,#xAMPRx_SS,gr0,icc1 477 478 # map this PTD instead and record coverage address 479 ori.p gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30 480 beq icc0,#0,__tlb_user_fault /* jump if PGE not present */ 481 slli.p gr31,#18,gr31 482 bne icc1,#0,__itlb_u_bigpage 483 movgs gr30,dampr4 484 movgs gr31,scr0 485 486 # we can now resume normal service 487 setlos 0x3ffc,gr30 488 srli.p gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ 489 bra __itlb_u_PTD_mapped 490 491__itlb_u_bigpage: 492 break 493 nop 494 495 .size __entry_user_insn_tlb_miss, .-__entry_user_insn_tlb_miss 496 497############################################################################### 498# 499# Userspace data TLB miss handler 500# On entry: 501# GR28 - faulting address 502# GR31 - EAR0 ^ SCR1 503# SCR1 - base of virtual range covered by cached PGE from last DTLB miss (or 0xffffffff) 504# DAMR3 - mapped page directory 505# DAMR5 - mapped page table as matched by SCR1 506# 507############################################################################### 508 .globl __entry_user_data_tlb_miss 509 .type __entry_user_data_tlb_miss,@function 510__entry_user_data_tlb_miss: 511#if 0 512 sethi.p %hi(0xe1200004),gr30 513 setlo %lo(0xe1200004),gr30 514 st gr0,@(gr30,gr0) 515 sethi.p %hi(0xffc00100),gr30 516 setlo %lo(0xffc00100),gr30 517 sth gr30,@(gr30,gr0) 518 membar 519#endif 520 521 movsg ccr,gr30 /* save CCR */ 522 movgs gr30,scr2 523 524 # see if the cached page table mapping is appropriate 525 srlicc.p gr31,#26,gr0,icc0 526 setlos 0x3ffc,gr30 527 srli.p gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ 528 bne icc0,#0,__dtlb_u_PTD_miss 529 530__dtlb_u_PTD_mapped: 531 # access the PTD with EAR0[25:14] 532 # - DAMLR5 points to the virtual address of the appropriate page table 533 # - the PTD holds 4096 PTEs 534 # - the PTD must be accessed uncached 535 # - the PTE must be marked accessed if it was valid 536 # 537 and gr31,gr30,gr31 538 movsg damlr5,gr30 539 540__dtlb_u_using_iPTD: 541 add gr30,gr31,gr31 542 ldi @(gr31,#0),gr30 /* fetch the PTE */ 543 andicc gr30,#_PAGE_PRESENT,gr0,icc0 544 ori.p gr30,#_PAGE_ACCESSED,gr30 545 beq icc0,#0,__tlb_user_fault /* jump if PTE invalid */ 546 sti.p gr30,@(gr31,#0) /* update the PTE */ 547 andi gr30,#~_PAGE_ACCESSED,gr30 548 549 # we're using DAMR1 as an extra TLB entry 550 # - punt the entry here (if valid) to the real TLB and then replace with the new PTE 551 movsg dampr1,gr31 552 andicc gr31,#xAMPRx_V,gr0,icc0 553 setlos.p 0xfffff000,gr31 554 beq icc0,#0,__dtlb_u_nopunt /* punt not required */ 555 556 movsg dampr1,gr31 557 movgs gr31,tppr 558 movsg damlr1,gr31 /* set TPLR.CXN */ 559 movgs gr31,tplr 560 tlbpr gr31,gr0,#2,#0 /* save to the TLB */ 561 movsg tpxr,gr31 /* check the TLB write error flag */ 562 andicc.p gr31,#TPXR_E,gr0,icc0 563 setlos #0xfffff000,gr31 564 bne icc0,#0,__tlb_user_fault 565 566__dtlb_u_nopunt: 567 568 # assemble the new TLB entry 569 and gr28,gr31,gr28 570 movsg cxnr,gr31 571 or gr28,gr31,gr28 572 movgs gr28,iamlr1 /* xAMLR = address | context number */ 573 movgs gr30,iampr1 574 movgs gr28,damlr1 575 movgs gr30,dampr1 576 577 # return, restoring registers 578 movsg scr2,gr30 579 movgs gr30,ccr 580 rett #0 581 beq icc0,#3,0 /* prevent icache prefetch */ 582 583 # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more 584 # appropriate page table and map that instead 585 # - first of all, check the insn PGE cache - we may well get a hit there 586 # - access the PGD with EAR0[31:26] 587 # - DAMLR3 points to the virtual address of the page directory 588 # - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables 589__dtlb_u_PTD_miss: 590 movsg scr0,gr31 /* consult the insn-PGE-cache key */ 591 xor gr28,gr31,gr31 592 srlicc gr31,#26,gr0,icc0 593 srli gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ 594 bne icc0,#0,__dtlb_u_iPGE_miss 595 596 # what we're looking for is covered by the insn-PGE-cache 597 setlos 0x3ffc,gr30 598 and gr31,gr30,gr31 599 movsg damlr4,gr30 600 bra __dtlb_u_using_iPTD 601 602__dtlb_u_iPGE_miss: 603 srli gr28,#26,gr31 /* calculate PGE offset */ 604 slli gr31,#8,gr31 /* and clear bottom bits */ 605 606 movsg damlr3,gr30 607 ld @(gr31,gr30),gr30 /* access the PGE */ 608 609 andicc.p gr30,#_PAGE_PRESENT,gr0,icc0 610 andicc gr30,#xAMPRx_SS,gr0,icc1 611 612 # map this PTD instead and record coverage address 613 ori.p gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30 614 beq icc0,#0,__tlb_user_fault /* jump if PGE not present */ 615 slli.p gr31,#18,gr31 616 bne icc1,#0,__dtlb_u_bigpage 617 movgs gr30,dampr5 618 movgs gr31,scr1 619 620 # we can now resume normal service 621 setlos 0x3ffc,gr30 622 srli.p gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ 623 bra __dtlb_u_PTD_mapped 624 625__dtlb_u_bigpage: 626 break 627 nop 628 629 .size __entry_user_data_tlb_miss, .-__entry_user_data_tlb_miss 630