spiterrs.S 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /* We need to carefully read the error status, ACK the errors,
  2. * prevent recursive traps, and pass the information on to C
  3. * code for logging.
  4. *
  5. * We pass the AFAR in as-is, and we encode the status
  6. * information as described in asm-sparc64/sfafsr.h
  7. */
  8. .type __spitfire_access_error,#function
  9. __spitfire_access_error:
  10. /* Disable ESTATE error reporting so that we do not take
  11. * recursive traps and RED state the processor.
  12. */
  13. stxa %g0, [%g0] ASI_ESTATE_ERROR_EN
  14. membar #Sync
  15. mov UDBE_UE, %g1
  16. ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR
  17. /* __spitfire_cee_trap branches here with AFSR in %g4 and
  18. * UDBE_CE in %g1. It only clears ESTATE_ERR_CE in the ESTATE
  19. * Error Enable register.
  20. */
  21. __spitfire_cee_trap_continue:
  22. ldxa [%g0] ASI_AFAR, %g5 ! Get AFAR
  23. rdpr %tt, %g3
  24. and %g3, 0x1ff, %g3 ! Paranoia
  25. sllx %g3, SFSTAT_TRAP_TYPE_SHIFT, %g3
  26. or %g4, %g3, %g4
  27. rdpr %tl, %g3
  28. cmp %g3, 1
  29. mov 1, %g3
  30. bleu %xcc, 1f
  31. sllx %g3, SFSTAT_TL_GT_ONE_SHIFT, %g3
  32. or %g4, %g3, %g4
  33. /* Read in the UDB error register state, clearing the sticky
  34. * error bits as-needed. We only clear them if the UE bit is
  35. * set. Likewise, __spitfire_cee_trap below will only do so
  36. * if the CE bit is set.
  37. *
  38. * NOTE: UltraSparc-I/II have high and low UDB error
  39. * registers, corresponding to the two UDB units
  40. * present on those chips. UltraSparc-IIi only
  41. * has a single UDB, called "SDB" in the manual.
  42. * For IIi the upper UDB register always reads
  43. * as zero so for our purposes things will just
  44. * work with the checks below.
  45. */
  46. 1: ldxa [%g0] ASI_UDBH_ERROR_R, %g3
  47. and %g3, 0x3ff, %g7 ! Paranoia
  48. sllx %g7, SFSTAT_UDBH_SHIFT, %g7
  49. or %g4, %g7, %g4
  50. andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE
  51. be,pn %xcc, 1f
  52. nop
  53. stxa %g3, [%g0] ASI_UDB_ERROR_W
  54. membar #Sync
  55. 1: mov 0x18, %g3
  56. ldxa [%g3] ASI_UDBL_ERROR_R, %g3
  57. and %g3, 0x3ff, %g7 ! Paranoia
  58. sllx %g7, SFSTAT_UDBL_SHIFT, %g7
  59. or %g4, %g7, %g4
  60. andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE
  61. be,pn %xcc, 1f
  62. nop
  63. mov 0x18, %g7
  64. stxa %g3, [%g7] ASI_UDB_ERROR_W
  65. membar #Sync
  66. 1: /* Ok, now that we've latched the error state, clear the
  67. * sticky bits in the AFSR.
  68. */
  69. stxa %g4, [%g0] ASI_AFSR
  70. membar #Sync
  71. rdpr %tl, %g2
  72. cmp %g2, 1
  73. rdpr %pil, %g2
  74. bleu,pt %xcc, 1f
  75. wrpr %g0, PIL_NORMAL_MAX, %pil
  76. ba,pt %xcc, etraptl1
  77. rd %pc, %g7
  78. ba,a,pt %xcc, 2f
  79. 1: ba,pt %xcc, etrap_irq
  80. rd %pc, %g7
  81. 2:
  82. #ifdef CONFIG_TRACE_IRQFLAGS
  83. call trace_hardirqs_off
  84. nop
  85. #endif
  86. mov %l4, %o1
  87. mov %l5, %o2
  88. call spitfire_access_error
  89. add %sp, PTREGS_OFF, %o0
  90. ba,a,pt %xcc, rtrap
  91. .size __spitfire_access_error,.-__spitfire_access_error
  92. /* This is the trap handler entry point for ECC correctable
  93. * errors. They are corrected, but we listen for the trap so
  94. * that the event can be logged.
  95. *
  96. * Disrupting errors are either:
  97. * 1) single-bit ECC errors during UDB reads to system
  98. * memory
  99. * 2) data parity errors during write-back events
  100. *
  101. * As far as I can make out from the manual, the CEE trap is
  102. * only for correctable errors during memory read accesses by
  103. * the front-end of the processor.
  104. *
  105. * The code below is only for trap level 1 CEE events, as it
  106. * is the only situation where we can safely record and log.
  107. * For trap level >1 we just clear the CE bit in the AFSR and
  108. * return.
  109. *
  110. * This is just like __spiftire_access_error above, but it
  111. * specifically handles correctable errors. If an
  112. * uncorrectable error is indicated in the AFSR we will branch
  113. * directly above to __spitfire_access_error to handle it
  114. * instead. Uncorrectable therefore takes priority over
  115. * correctable, and the error logging C code will notice this
  116. * case by inspecting the trap type.
  117. */
  118. .type __spitfire_cee_trap,#function
  119. __spitfire_cee_trap:
  120. ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR
  121. mov 1, %g3
  122. sllx %g3, SFAFSR_UE_SHIFT, %g3
  123. andcc %g4, %g3, %g0 ! Check for UE
  124. bne,pn %xcc, __spitfire_access_error
  125. nop
  126. /* Ok, in this case we only have a correctable error.
  127. * Indicate we only wish to capture that state in register
  128. * %g1, and we only disable CE error reporting unlike UE
  129. * handling which disables all errors.
  130. */
  131. ldxa [%g0] ASI_ESTATE_ERROR_EN, %g3
  132. andn %g3, ESTATE_ERR_CE, %g3
  133. stxa %g3, [%g0] ASI_ESTATE_ERROR_EN
  134. membar #Sync
  135. /* Preserve AFSR in %g4, indicate UDB state to capture in %g1 */
  136. ba,pt %xcc, __spitfire_cee_trap_continue
  137. mov UDBE_CE, %g1
  138. .size __spitfire_cee_trap,.-__spitfire_cee_trap
  139. .type __spitfire_data_access_exception_tl1,#function
  140. __spitfire_data_access_exception_tl1:
  141. rdpr %pstate, %g4
  142. wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
  143. mov TLB_SFSR, %g3
  144. mov DMMU_SFAR, %g5
  145. ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR
  146. ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
  147. stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit
  148. membar #Sync
  149. rdpr %tt, %g3
  150. cmp %g3, 0x80 ! first win spill/fill trap
  151. blu,pn %xcc, 1f
  152. cmp %g3, 0xff ! last win spill/fill trap
  153. bgu,pn %xcc, 1f
  154. nop
  155. ba,pt %xcc, winfix_dax
  156. rdpr %tpc, %g3
  157. 1: sethi %hi(109f), %g7
  158. ba,pt %xcc, etraptl1
  159. 109: or %g7, %lo(109b), %g7
  160. mov %l4, %o1
  161. mov %l5, %o2
  162. call spitfire_data_access_exception_tl1
  163. add %sp, PTREGS_OFF, %o0
  164. ba,a,pt %xcc, rtrap
  165. .size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1
  166. .type __spitfire_data_access_exception,#function
  167. __spitfire_data_access_exception:
  168. rdpr %pstate, %g4
  169. wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
  170. mov TLB_SFSR, %g3
  171. mov DMMU_SFAR, %g5
  172. ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR
  173. ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
  174. stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit
  175. membar #Sync
  176. sethi %hi(109f), %g7
  177. ba,pt %xcc, etrap
  178. 109: or %g7, %lo(109b), %g7
  179. mov %l4, %o1
  180. mov %l5, %o2
  181. call spitfire_data_access_exception
  182. add %sp, PTREGS_OFF, %o0
  183. ba,a,pt %xcc, rtrap
  184. .size __spitfire_data_access_exception,.-__spitfire_data_access_exception
  185. .type __spitfire_insn_access_exception_tl1,#function
  186. __spitfire_insn_access_exception_tl1:
  187. rdpr %pstate, %g4
  188. wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
  189. mov TLB_SFSR, %g3
  190. ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR
  191. rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC
  192. stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit
  193. membar #Sync
  194. sethi %hi(109f), %g7
  195. ba,pt %xcc, etraptl1
  196. 109: or %g7, %lo(109b), %g7
  197. mov %l4, %o1
  198. mov %l5, %o2
  199. call spitfire_insn_access_exception_tl1
  200. add %sp, PTREGS_OFF, %o0
  201. ba,a,pt %xcc, rtrap
  202. .size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1
  203. .type __spitfire_insn_access_exception,#function
  204. __spitfire_insn_access_exception:
  205. rdpr %pstate, %g4
  206. wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
  207. mov TLB_SFSR, %g3
  208. ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR
  209. rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC
  210. stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit
  211. membar #Sync
  212. sethi %hi(109f), %g7
  213. ba,pt %xcc, etrap
  214. 109: or %g7, %lo(109b), %g7
  215. mov %l4, %o1
  216. mov %l5, %o2
  217. call spitfire_insn_access_exception
  218. add %sp, PTREGS_OFF, %o0
  219. ba,a,pt %xcc, rtrap
  220. .size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception