itlb_base.S 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* $Id: itlb_base.S,v 1.12 2002/02/09 19:49:30 davem Exp $
  2. * itlb_base.S: Front end to ITLB miss replacement strategy.
  3. * This is included directly into the trap table.
  4. *
  5. * Copyright (C) 1996,1998 David S. Miller (davem@redhat.com)
  6. * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
  7. */
  8. #if PAGE_SHIFT == 13
  9. /*
  10. * To compute vpte offset, we need to do ((addr >> 13) << 3),
  11. * which can be optimized to (addr >> 10) if bits 10/11/12 can
  12. * be guaranteed to be 0 ... mmu_context.h does guarantee this
  13. * by only using 10 bits in the hwcontext value.
  14. */
  15. #define CREATE_VPTE_OFFSET1(r1, r2) \
  16. srax r1, 10, r2
  17. #define CREATE_VPTE_OFFSET2(r1, r2)
  18. #define CREATE_VPTE_NOP nop
  19. #else /* PAGE_SHIFT */
  20. #define CREATE_VPTE_OFFSET1(r1, r2) \
  21. srax r1, PAGE_SHIFT, r2
  22. #define CREATE_VPTE_OFFSET2(r1, r2) \
  23. sllx r2, 3, r2
  24. #define CREATE_VPTE_NOP
  25. #endif /* PAGE_SHIFT */
  26. /* Ways we can get here:
  27. *
  28. * 1) Nucleus instruction misses from module code.
  29. * 2) All user instruction misses.
  30. *
  31. * All real page faults merge their code paths to the
  32. * sparc64_realfault_common label below.
  33. */
  34. /* ITLB ** ICACHE line 1: Quick user TLB misses */
  35. ldxa [%g1 + %g1] ASI_IMMU, %g4 ! Get TAG_ACCESS
  36. CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset
  37. CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
  38. ldxa [%g3 + %g6] ASI_P, %g5 ! Load VPTE
  39. 1: brgez,pn %g5, 3f ! Not valid, branch out
  40. sethi %hi(_PAGE_EXEC), %g4 ! Delay-slot
  41. andcc %g5, %g4, %g0 ! Executable?
  42. be,pn %xcc, 3f ! Nope, branch.
  43. nop ! Delay-slot
  44. 2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB
  45. retry ! Trap return
  46. 3: rdpr %pstate, %g4 ! Move into alternate globals
  47. /* ITLB ** ICACHE line 2: Real faults */
  48. wrpr %g4, PSTATE_AG|PSTATE_MG, %pstate
  49. rdpr %tpc, %g5 ! And load faulting VA
  50. mov FAULT_CODE_ITLB, %g4 ! It was read from ITLB
  51. sparc64_realfault_common: ! Called by TL0 dtlb_miss too
  52. stb %g4, [%g6 + TI_FAULT_CODE]
  53. stx %g5, [%g6 + TI_FAULT_ADDR]
  54. ba,pt %xcc, etrap ! Save state
  55. 1: rd %pc, %g7 ! ...
  56. nop
  57. /* ITLB ** ICACHE line 3: Finish faults + window fixups */
  58. call do_sparc64_fault ! Call fault handler
  59. add %sp, PTREGS_OFF, %o0! Compute pt_regs arg
  60. ba,pt %xcc, rtrap_clr_l6 ! Restore cpu state
  61. nop
  62. winfix_trampoline:
  63. rdpr %tpc, %g3 ! Prepare winfixup TNPC
  64. or %g3, 0x7c, %g3 ! Compute offset to branch
  65. wrpr %g3, %tnpc ! Write it into TNPC
  66. done ! Do it to it
  67. /* ITLB ** ICACHE line 4: Unused... */
  68. nop
  69. nop
  70. nop
  71. nop
  72. CREATE_VPTE_NOP
  73. #undef CREATE_VPTE_OFFSET1
  74. #undef CREATE_VPTE_OFFSET2
  75. #undef CREATE_VPTE_NOP