dtlb_backend.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: dtlb_backend.S,v 1.16 2001/10/09 04:02:11 davem Exp $
  2.  * dtlb_backend.S: Back end to DTLB 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. #include <asm/pgtable.h>
  9. #if PAGE_SHIFT == 13
  10. #define FILL_VALID_SZ_BITS1(r1) 
  11.  sllx %g2, 62, r1
  12. #define FILL_VALID_SZ_BITS2(r1)
  13. #define FILL_VALID_SZ_BITS_NOP nop
  14. #elif PAGE_SHIFT == 16
  15. #define FILL_VALID_SZ_BITS1(r1) 
  16. or %g0, 5, r1
  17. #define FILL_VALID_SZ_BITS2(r1) 
  18. sllx r1, 61, r1
  19. #define FILL_VALID_SZ_BITS_NOP
  20. #else
  21. #error unsupported PAGE_SIZE
  22. #endif /* PAGE_SHIFT */
  23. #define VPTE_BITS (_PAGE_CP | _PAGE_CV | _PAGE_P )
  24. #define VPTE_SHIFT (PAGE_SHIFT - 3)
  25. #define TLB_PMD_SHIFT (PAGE_SHIFT - 3 + 3)
  26. #define TLB_PGD_SHIFT (PMD_BITS + PAGE_SHIFT - 3 + 3)
  27. #define TLB_PMD_MASK (((1 << PMD_BITS) - 1) << 1)
  28. #define TLB_PGD_MASK (((1 << (VA_BITS - PAGE_SHIFT - (PAGE_SHIFT - 3) - PMD_BITS)) - 1) << 2)
  29. /* Ways we can get here:
  30.  *
  31.  * 1) Nucleus loads and stores to/from PA-->VA direct mappings at tl>1.
  32.  * 2) Nucleus loads and stores to/from user/kernel window save areas.
  33.  * 3) VPTE misses from dtlb_base and itlb_base.
  34.  */
  35. /* TLB1 ** ICACHE line 1: tl1 DTLB and quick VPTE miss */
  36. ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
  37. add %g3, %g3, %g5 ! Compute VPTE base
  38. cmp %g4, %g5 ! VPTE miss?
  39. bgeu,pt %xcc, 1f ! Continue here
  40.  andcc %g4, TAG_CONTEXT_BITS, %g5 ! From Nucleus? (for tl0 miss)
  41. ba,pt %xcc, from_tl1_trap ! Fall to tl0 miss
  42.  rdpr %tl, %g5 ! For tl0 miss TL==3 test
  43. 1: sllx %g6, VPTE_SHIFT, %g4 ! Position TAG_ACCESS
  44. /* TLB1 ** ICACHE line 2: Quick VPTE miss    */
  45. or %g4, %g5, %g4 ! Prepare TAG_ACCESS
  46. mov TSB_REG, %g1 ! Grab TSB reg
  47. ldxa [%g1] ASI_DMMU, %g5 ! Doing PGD caching?
  48. srlx %g6, (TLB_PMD_SHIFT - 1), %g1 ! Position PMD offset
  49. be,pn %xcc, sparc64_vpte_nucleus ! Is it from Nucleus?
  50.  and %g1, TLB_PMD_MASK, %g1 ! Mask PMD offset bits
  51. brnz,pt %g5, sparc64_vpte_continue ! Yep, go like smoke
  52.  add %g1, %g1, %g1 ! Position PMD offset some more
  53. /* TLB1 ** ICACHE line 3: Quick VPTE miss    */
  54. srlx %g6, (TLB_PGD_SHIFT - 2), %g5 ! Position PGD offset
  55. and %g5, TLB_PGD_MASK, %g5 ! Mask PGD offset
  56. lduwa [%g7 + %g5] ASI_PHYS_USE_EC, %g5! Load PGD
  57. brz,pn %g5, vpte_noent ! Valid?
  58. sparc64_kpte_continue:
  59.  sllx %g5, 11, %g5 ! Shift into place
  60. sparc64_vpte_continue:
  61. lduwa [%g5 + %g1] ASI_PHYS_USE_EC, %g5! Load PMD
  62. sllx %g5, 11, %g5 ! Shift into place
  63. brz,pn %g5, vpte_noent ! Valid?
  64. /* TLB1 ** ICACHE line 4: Quick VPTE miss    */
  65.  FILL_VALID_SZ_BITS1(%g1) ! Put _PAGE_VALID into %g1
  66. FILL_VALID_SZ_BITS2(%g1) ! Put _PAGE_VALID into %g1
  67. or %g5, VPTE_BITS, %g5 ! Prepare VPTE data
  68. or %g5, %g1, %g5 ! ...
  69. mov TLB_SFSR, %g1 ! Restore %g1 value
  70. stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Load VPTE into TLB
  71. stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS
  72. retry ! Load PTE once again
  73. FILL_VALID_SZ_BITS_NOP
  74. #undef VPTE_SHIFT
  75. #undef TLB_PMD_SHIFT
  76. #undef TLB_PGD_SHIFT
  77. #undef VPTE_BITS
  78. #undef TLB_PMD_MASK
  79. #undef TLB_PGD_MASK
  80. #undef FILL_VALID_SZ_BITS1
  81. #undef FILL_VALID_SZ_BITS2
  82. #undef FILL_VALID_SZ_BITS_NOP