entry-table.S 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /* entry-table.S: main trap vector tables and exception jump table
  2. *
  3. * Copyright (C) 2003 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/config.h>
  14. #include <linux/linkage.h>
  15. #include <asm/spr-regs.h>
  16. ###############################################################################
  17. #
  18. # Declare the main trap and vector tables
  19. #
  20. # There are six tables:
  21. #
  22. # (1) The trap table for debug mode
  23. # (2) The trap table for kernel mode
  24. # (3) The trap table for user mode
  25. #
  26. # The CPU jumps to an appropriate slot in the appropriate table to perform
  27. # exception processing. We have three different tables for the three
  28. # different CPU modes because there is no hardware differentiation between
  29. # stack pointers for these three modes, and so we have to invent one when
  30. # crossing mode boundaries.
  31. #
  32. # (4) The exception handler vector table
  33. #
  34. # The user and kernel trap tables use the same prologue for normal
  35. # exception processing. The prologue then jumps to the handler in this
  36. # table, as indexed by the exception ID from the TBR.
  37. #
  38. # (5) The fixup table for kernel-trap single-step
  39. # (6) The fixup table for user-trap single-step
  40. #
  41. # Due to the way single-stepping works on this CPU (single-step is not
  42. # disabled when crossing exception boundaries, only when in debug mode),
  43. # we have to catch the single-step event in break.S and jump to the fixup
  44. # routine pointed to by this table.
  45. #
  46. # The linker script places the user mode and kernel mode trap tables on to
  47. # the same 8Kb page, so that break.S can be more efficient when performing
  48. # single-step bypass management
  49. #
  50. ###############################################################################
  51. # trap table for entry from debug mode
  52. .section .trap.break,"ax"
  53. .balign 256*16
  54. .globl __entry_breaktrap_table
  55. __entry_breaktrap_table:
  56. # trap table for entry from user mode
  57. .section .trap.user,"ax"
  58. .balign 256*16
  59. .globl __entry_usertrap_table
  60. __entry_usertrap_table:
  61. # trap table for entry from kernel mode
  62. .section .trap.kernel,"ax"
  63. .balign 256*16
  64. .globl __entry_kerneltrap_table
  65. __entry_kerneltrap_table:
  66. # exception handler jump table
  67. .section .trap.vector,"ax"
  68. .balign 256*4
  69. .globl __entry_vector_table
  70. __entry_vector_table:
  71. # trap fixup table for single-stepping in user mode
  72. .section .trap.fixup.user,"a"
  73. .balign 256*4
  74. .globl __break_usertrap_fixup_table
  75. __break_usertrap_fixup_table:
  76. # trap fixup table for single-stepping in user mode
  77. .section .trap.fixup.kernel,"a"
  78. .balign 256*4
  79. .globl __break_kerneltrap_fixup_table
  80. __break_kerneltrap_fixup_table:
  81. # handler declaration for a sofware or program interrupt
  82. .macro VECTOR_SOFTPROG tbr_tt, vec
  83. .section .trap.user
  84. .org \tbr_tt
  85. bra __entry_uspace_softprog_interrupt
  86. .section .trap.fixup.user
  87. .org \tbr_tt >> 2
  88. .long __break_step_uspace_softprog_interrupt
  89. .section .trap.kernel
  90. .org \tbr_tt
  91. bra __entry_kernel_softprog_interrupt
  92. .section .trap.fixup.kernel
  93. .org \tbr_tt >> 2
  94. .long __break_step_kernel_softprog_interrupt
  95. .section .trap.vector
  96. .org \tbr_tt >> 2
  97. .long \vec
  98. .endm
  99. # handler declaration for a maskable external interrupt
  100. .macro VECTOR_IRQ tbr_tt, vec
  101. .section .trap.user
  102. .org \tbr_tt
  103. bra __entry_uspace_external_interrupt
  104. .section .trap.fixup.user
  105. .org \tbr_tt >> 2
  106. .long __break_step_uspace_external_interrupt
  107. .section .trap.kernel
  108. .org \tbr_tt
  109. # deal with virtual interrupt disablement
  110. beq icc2,#0,__entry_kernel_external_interrupt_virtually_disabled
  111. bra __entry_kernel_external_interrupt
  112. .section .trap.fixup.kernel
  113. .org \tbr_tt >> 2
  114. .long __break_step_kernel_external_interrupt
  115. .section .trap.vector
  116. .org \tbr_tt >> 2
  117. .long \vec
  118. .endm
  119. # handler declaration for an NMI external interrupt
  120. .macro VECTOR_NMI tbr_tt, vec
  121. .section .trap.user
  122. .org \tbr_tt
  123. break
  124. break
  125. break
  126. break
  127. .section .trap.kernel
  128. .org \tbr_tt
  129. break
  130. break
  131. break
  132. break
  133. .section .trap.vector
  134. .org \tbr_tt >> 2
  135. .long \vec
  136. .endm
  137. # handler declaration for an MMU only sofware or program interrupt
  138. .macro VECTOR_SP_MMU tbr_tt, vec
  139. #ifdef CONFIG_MMU
  140. VECTOR_SOFTPROG \tbr_tt, \vec
  141. #else
  142. VECTOR_NMI \tbr_tt, 0
  143. #endif
  144. .endm
  145. ###############################################################################
  146. #
  147. # specification of the vectors
  148. # - note: each macro inserts code into multiple sections
  149. #
  150. ###############################################################################
  151. VECTOR_SP_MMU TBR_TT_INSTR_MMU_MISS, __entry_insn_mmu_miss
  152. VECTOR_SOFTPROG TBR_TT_INSTR_ACC_ERROR, __entry_insn_access_error
  153. VECTOR_SOFTPROG TBR_TT_INSTR_ACC_EXCEP, __entry_insn_access_exception
  154. VECTOR_SOFTPROG TBR_TT_PRIV_INSTR, __entry_privileged_instruction
  155. VECTOR_SOFTPROG TBR_TT_ILLEGAL_INSTR, __entry_illegal_instruction
  156. VECTOR_SOFTPROG TBR_TT_FP_EXCEPTION, __entry_media_exception
  157. VECTOR_SOFTPROG TBR_TT_MP_EXCEPTION, __entry_media_exception
  158. VECTOR_SOFTPROG TBR_TT_DATA_ACC_ERROR, __entry_data_access_error
  159. VECTOR_SP_MMU TBR_TT_DATA_MMU_MISS, __entry_data_mmu_miss
  160. VECTOR_SOFTPROG TBR_TT_DATA_ACC_EXCEP, __entry_data_access_exception
  161. VECTOR_SOFTPROG TBR_TT_DATA_STR_ERROR, __entry_data_store_error
  162. VECTOR_SOFTPROG TBR_TT_DIVISION_EXCEP, __entry_division_exception
  163. #ifdef CONFIG_MMU
  164. .section .trap.user
  165. .org TBR_TT_INSTR_TLB_MISS
  166. .globl __trap_user_insn_tlb_miss
  167. __trap_user_insn_tlb_miss:
  168. movsg ear0,gr28 /* faulting address */
  169. movsg scr0,gr31 /* get mapped PTD coverage start address */
  170. xor.p gr28,gr31,gr31 /* compare addresses */
  171. bra __entry_user_insn_tlb_miss
  172. .org TBR_TT_DATA_TLB_MISS
  173. .globl __trap_user_data_tlb_miss
  174. __trap_user_data_tlb_miss:
  175. movsg ear0,gr28 /* faulting address */
  176. movsg scr1,gr31 /* get mapped PTD coverage start address */
  177. xor.p gr28,gr31,gr31 /* compare addresses */
  178. bra __entry_user_data_tlb_miss
  179. .section .trap.kernel
  180. .org TBR_TT_INSTR_TLB_MISS
  181. .globl __trap_kernel_insn_tlb_miss
  182. __trap_kernel_insn_tlb_miss:
  183. movsg ear0,gr29 /* faulting address */
  184. movsg scr0,gr31 /* get mapped PTD coverage start address */
  185. xor.p gr29,gr31,gr31 /* compare addresses */
  186. bra __entry_kernel_insn_tlb_miss
  187. .org TBR_TT_DATA_TLB_MISS
  188. .globl __trap_kernel_data_tlb_miss
  189. __trap_kernel_data_tlb_miss:
  190. movsg ear0,gr29 /* faulting address */
  191. movsg scr1,gr31 /* get mapped PTD coverage start address */
  192. xor.p gr29,gr31,gr31 /* compare addresses */
  193. bra __entry_kernel_data_tlb_miss
  194. .section .trap.fixup.user
  195. .org TBR_TT_INSTR_TLB_MISS >> 2
  196. .globl __trap_fixup_user_insn_tlb_miss
  197. __trap_fixup_user_insn_tlb_miss:
  198. .long __break_user_insn_tlb_miss
  199. .org TBR_TT_DATA_TLB_MISS >> 2
  200. .globl __trap_fixup_user_data_tlb_miss
  201. __trap_fixup_user_data_tlb_miss:
  202. .long __break_user_data_tlb_miss
  203. .section .trap.fixup.kernel
  204. .org TBR_TT_INSTR_TLB_MISS >> 2
  205. .globl __trap_fixup_kernel_insn_tlb_miss
  206. __trap_fixup_kernel_insn_tlb_miss:
  207. .long __break_kernel_insn_tlb_miss
  208. .org TBR_TT_DATA_TLB_MISS >> 2
  209. .globl __trap_fixup_kernel_data_tlb_miss
  210. __trap_fixup_kernel_data_tlb_miss:
  211. .long __break_kernel_data_tlb_miss
  212. .section .trap.vector
  213. .org TBR_TT_INSTR_TLB_MISS >> 2
  214. .long __entry_insn_mmu_fault
  215. .org TBR_TT_DATA_TLB_MISS >> 2
  216. .long __entry_data_mmu_fault
  217. #endif
  218. VECTOR_SP_MMU TBR_TT_DATA_DAT_EXCEP, __entry_data_dat_fault
  219. VECTOR_NMI TBR_TT_DECREMENT_TIMER, __entry_do_NMI
  220. VECTOR_SOFTPROG TBR_TT_COMPOUND_EXCEP, __entry_compound_exception
  221. VECTOR_IRQ TBR_TT_INTERRUPT_1, __entry_do_IRQ
  222. VECTOR_IRQ TBR_TT_INTERRUPT_2, __entry_do_IRQ
  223. VECTOR_IRQ TBR_TT_INTERRUPT_3, __entry_do_IRQ
  224. VECTOR_IRQ TBR_TT_INTERRUPT_4, __entry_do_IRQ
  225. VECTOR_IRQ TBR_TT_INTERRUPT_5, __entry_do_IRQ
  226. VECTOR_IRQ TBR_TT_INTERRUPT_6, __entry_do_IRQ
  227. VECTOR_IRQ TBR_TT_INTERRUPT_7, __entry_do_IRQ
  228. VECTOR_IRQ TBR_TT_INTERRUPT_8, __entry_do_IRQ
  229. VECTOR_IRQ TBR_TT_INTERRUPT_9, __entry_do_IRQ
  230. VECTOR_IRQ TBR_TT_INTERRUPT_10, __entry_do_IRQ
  231. VECTOR_IRQ TBR_TT_INTERRUPT_11, __entry_do_IRQ
  232. VECTOR_IRQ TBR_TT_INTERRUPT_12, __entry_do_IRQ
  233. VECTOR_IRQ TBR_TT_INTERRUPT_13, __entry_do_IRQ
  234. VECTOR_IRQ TBR_TT_INTERRUPT_14, __entry_do_IRQ
  235. VECTOR_NMI TBR_TT_INTERRUPT_15, __entry_do_NMI
  236. # miscellaneous user mode entry points
  237. .section .trap.user
  238. .org TBR_TT_TRAP0
  239. .rept 127
  240. bra __entry_uspace_softprog_interrupt
  241. .long 0,0,0
  242. .endr
  243. .org TBR_TT_BREAK
  244. bra __entry_break
  245. .long 0,0,0
  246. .section .trap.fixup.user
  247. .org TBR_TT_TRAP0 >> 2
  248. .rept 127
  249. .long __break_step_uspace_softprog_interrupt
  250. .endr
  251. .org TBR_TT_BREAK >> 2
  252. .long 0
  253. # miscellaneous kernel mode entry points
  254. .section .trap.kernel
  255. .org TBR_TT_TRAP0
  256. bra __entry_kernel_softprog_interrupt
  257. .org TBR_TT_TRAP1
  258. bra __entry_kernel_softprog_interrupt
  259. # trap #2 in kernel - reenable interrupts
  260. .org TBR_TT_TRAP2
  261. bra __entry_kernel_external_interrupt_virtual_reenable
  262. # miscellaneous kernel traps
  263. .org TBR_TT_TRAP3
  264. .rept 124
  265. bra __entry_kernel_softprog_interrupt
  266. .long 0,0,0
  267. .endr
  268. .org TBR_TT_BREAK
  269. bra __entry_break
  270. .long 0,0,0
  271. .section .trap.fixup.kernel
  272. .org TBR_TT_TRAP0 >> 2
  273. .long __break_step_kernel_softprog_interrupt
  274. .long __break_step_kernel_softprog_interrupt
  275. .long __break_step_kernel_external_interrupt_virtual_reenable
  276. .rept 124
  277. .long __break_step_kernel_softprog_interrupt
  278. .endr
  279. .org TBR_TT_BREAK >> 2
  280. .long 0
  281. # miscellaneous debug mode entry points
  282. .section .trap.break
  283. .org TBR_TT_BREAK
  284. movsg bpcsr,gr30
  285. jmpl @(gr30,gr0)
  286. # miscellaneous vectors
  287. .section .trap.vector
  288. .org TBR_TT_TRAP0 >> 2
  289. .long system_call
  290. .rept 126
  291. .long __entry_unsupported_trap
  292. .endr
  293. .org TBR_TT_BREAK >> 2
  294. .long __entry_debug_exception