mmu.S 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright (C) 2003 Axis Communications AB
  3. *
  4. * Authors: Mikael Starvik (starvik@axis.com)
  5. *
  6. * Code for the fault low-level handling routines.
  7. *
  8. */
  9. #include <asm/page.h>
  10. #include <asm/pgtable.h>
  11. ; Save all register. Must save in same order as struct pt_regs.
  12. .macro SAVE_ALL
  13. subq 12, $sp
  14. move $erp, [$sp]
  15. subq 4, $sp
  16. move $srp, [$sp]
  17. subq 4, $sp
  18. move $ccs, [$sp]
  19. subq 4, $sp
  20. move $spc, [$sp]
  21. subq 4, $sp
  22. move $mof, [$sp]
  23. subq 4, $sp
  24. move $srs, [$sp]
  25. subq 4, $sp
  26. move.d $acr, [$sp]
  27. subq 14*4, $sp
  28. movem $r13, [$sp]
  29. subq 4, $sp
  30. move.d $r10, [$sp]
  31. .endm
  32. ; Bus fault handler. Extracts relevant information and calls mm subsystem
  33. ; to handle the fault.
  34. .macro MMU_BUS_FAULT_HANDLER handler, mmu, we, ex
  35. .globl \handler
  36. \handler:
  37. SAVE_ALL
  38. move \mmu, $srs ; Select MMU support register bank
  39. move.d $sp, $r11 ; regs
  40. moveq 1, $r12 ; protection fault
  41. moveq \we, $r13 ; write exception?
  42. orq \ex << 1, $r13 ; execute?
  43. move $s3, $r10 ; rw_mm_cause
  44. and.d ~8191, $r10 ; Get faulting page start address
  45. jsr do_page_fault
  46. nop
  47. ba ret_from_intr
  48. nop
  49. .endm
  50. ; Refill handler. Three cases may occur:
  51. ; 1. PMD and PTE exists in mm subsystem but not in TLB
  52. ; 2. PMD exists but not PTE
  53. ; 3. PMD doesn't exist
  54. ; The code below handles case 1 and calls the mm subsystem for case 2 and 3.
  55. ; Do not touch this code without very good reasons and extensive testing.
  56. ; Note that the code is optimized to minimize stalls (makes the code harder
  57. ; to read).
  58. ;
  59. ; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each
  60. ; PMD holds 16 MB of virtual memory.
  61. ; Bits 0-12 : Offset within a page
  62. ; Bits 13-23 : PTE offset within a PMD
  63. ; Bits 24-31 : PMD offset within the PGD
  64. .macro MMU_REFILL_HANDLER handler, mmu
  65. .globl \handler
  66. \handler:
  67. subq 4, $sp
  68. ; (The pipeline stalls for one cycle; $sp used as address in the next cycle.)
  69. move $srs, [$sp]
  70. subq 4, $sp
  71. move \mmu, $srs ; Select MMU support register bank
  72. move.d $acr, [$sp]
  73. subq 4, $sp
  74. move.d $r0, [$sp]
  75. #ifdef CONFIG_SMP
  76. move $s7, $acr ; PGD
  77. #else
  78. move.d per_cpu__current_pgd, $acr ; PGD
  79. #endif
  80. ; Look up PMD in PGD
  81. move $s3, $r0 ; rw_mm_cause
  82. lsrq 24, $r0 ; Get PMD index into PGD (bit 24-31)
  83. move.d [$acr], $acr ; PGD for the current process
  84. addi $r0.d, $acr, $acr
  85. move $s3, $r0 ; rw_mm_cause
  86. move.d [$acr], $acr ; Get PMD
  87. beq 1f
  88. ; Look up PTE in PMD
  89. lsrq PAGE_SHIFT, $r0
  90. and.w PAGE_MASK, $acr ; Remove PMD flags
  91. and.d 0x7ff, $r0 ; Get PTE index into PMD (bit 13-23)
  92. addi $r0.d, $acr, $acr
  93. move.d [$acr], $acr ; Get PTE
  94. beq 2f
  95. move.d [$sp+], $r0 ; Pop r0 in delayslot
  96. ; Store in TLB
  97. move $acr, $s5
  98. ; Return
  99. move.d [$sp+], $acr
  100. move [$sp], $srs
  101. addq 4, $sp
  102. rete
  103. rfe
  104. 1: ; PMD missing, let the mm subsystem fix it up.
  105. move.d [$sp+], $r0 ; Pop r0
  106. 2: ; PTE missing, let the mm subsystem fix it up.
  107. move.d [$sp+], $acr
  108. move [$sp], $srs
  109. addq 4, $sp
  110. SAVE_ALL
  111. move \mmu, $srs
  112. move.d $sp, $r11 ; regs
  113. clear.d $r12 ; Not a protection fault
  114. move.w PAGE_MASK, $acr
  115. move $s3, $r10 ; rw_mm_cause
  116. btstq 9, $r10 ; Check if write access
  117. smi $r13
  118. and.w PAGE_MASK, $r10 ; Get VPN (virtual address)
  119. jsr do_page_fault
  120. and.w $acr, $r10
  121. ; Return
  122. ba ret_from_intr
  123. nop
  124. .endm
  125. ; This is the MMU bus fault handlers.
  126. MMU_REFILL_HANDLER i_mmu_refill, 1
  127. MMU_BUS_FAULT_HANDLER i_mmu_invalid, 1, 0, 0
  128. MMU_BUS_FAULT_HANDLER i_mmu_access, 1, 0, 0
  129. MMU_BUS_FAULT_HANDLER i_mmu_execute, 1, 0, 1
  130. MMU_REFILL_HANDLER d_mmu_refill, 2
  131. MMU_BUS_FAULT_HANDLER d_mmu_invalid, 2, 0, 0
  132. MMU_BUS_FAULT_HANDLER d_mmu_access, 2, 0, 0
  133. MMU_BUS_FAULT_HANDLER d_mmu_write, 2, 1, 0