entry-table.S 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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. bra __entry_kernel_external_interrupt
  110. .section .trap.fixup.kernel
  111. .org \tbr_tt >> 2
  112. .long __break_step_kernel_external_interrupt
  113. .section .trap.vector
  114. .org \tbr_tt >> 2
  115. .long \vec
  116. .endm
  117. # handler declaration for an NMI external interrupt
  118. .macro VECTOR_NMI tbr_tt, vec
  119. .section .trap.user
  120. .org \tbr_tt
  121. break
  122. break
  123. break
  124. break
  125. .section .trap.kernel
  126. .org \tbr_tt
  127. break
  128. break
  129. break
  130. break
  131. .section .trap.vector
  132. .org \tbr_tt >> 2
  133. .long \vec
  134. .endm
  135. # handler declaration for an MMU only sofware or program interrupt
  136. .macro VECTOR_SP_MMU tbr_tt, vec
  137. #ifdef CONFIG_MMU
  138. VECTOR_SOFTPROG \tbr_tt, \vec
  139. #else
  140. VECTOR_NMI \tbr_tt, 0
  141. #endif
  142. .endm
  143. ###############################################################################
  144. #
  145. # specification of the vectors
  146. # - note: each macro inserts code into multiple sections
  147. #
  148. ###############################################################################
  149. VECTOR_SP_MMU TBR_TT_INSTR_MMU_MISS, __entry_insn_mmu_miss
  150. VECTOR_SOFTPROG TBR_TT_INSTR_ACC_ERROR, __entry_insn_access_error
  151. VECTOR_SOFTPROG TBR_TT_INSTR_ACC_EXCEP, __entry_insn_access_exception
  152. VECTOR_SOFTPROG TBR_TT_PRIV_INSTR, __entry_privileged_instruction
  153. VECTOR_SOFTPROG TBR_TT_ILLEGAL_INSTR, __entry_illegal_instruction
  154. VECTOR_SOFTPROG TBR_TT_FP_EXCEPTION, __entry_media_exception
  155. VECTOR_SOFTPROG TBR_TT_MP_EXCEPTION, __entry_media_exception
  156. VECTOR_SOFTPROG TBR_TT_DATA_ACC_ERROR, __entry_data_access_error
  157. VECTOR_SP_MMU TBR_TT_DATA_MMU_MISS, __entry_data_mmu_miss
  158. VECTOR_SOFTPROG TBR_TT_DATA_ACC_EXCEP, __entry_data_access_exception
  159. VECTOR_SOFTPROG TBR_TT_DATA_STR_ERROR, __entry_data_store_error
  160. VECTOR_SOFTPROG TBR_TT_DIVISION_EXCEP, __entry_division_exception
  161. #ifdef CONFIG_MMU
  162. .section .trap.user
  163. .org TBR_TT_INSTR_TLB_MISS
  164. .globl __trap_user_insn_tlb_miss
  165. __trap_user_insn_tlb_miss:
  166. movsg ear0,gr28 /* faulting address */
  167. movsg scr0,gr31 /* get mapped PTD coverage start address */
  168. xor.p gr28,gr31,gr31 /* compare addresses */
  169. bra __entry_user_insn_tlb_miss
  170. .org TBR_TT_DATA_TLB_MISS
  171. .globl __trap_user_data_tlb_miss
  172. __trap_user_data_tlb_miss:
  173. movsg ear0,gr28 /* faulting address */
  174. movsg scr1,gr31 /* get mapped PTD coverage start address */
  175. xor.p gr28,gr31,gr31 /* compare addresses */
  176. bra __entry_user_data_tlb_miss
  177. .section .trap.kernel
  178. .org TBR_TT_INSTR_TLB_MISS
  179. .globl __trap_kernel_insn_tlb_miss
  180. __trap_kernel_insn_tlb_miss:
  181. movsg ear0,gr29 /* faulting address */
  182. movsg scr0,gr31 /* get mapped PTD coverage start address */
  183. xor.p gr29,gr31,gr31 /* compare addresses */
  184. bra __entry_kernel_insn_tlb_miss
  185. .org TBR_TT_DATA_TLB_MISS
  186. .globl __trap_kernel_data_tlb_miss
  187. __trap_kernel_data_tlb_miss:
  188. movsg ear0,gr29 /* faulting address */
  189. movsg scr1,gr31 /* get mapped PTD coverage start address */
  190. xor.p gr29,gr31,gr31 /* compare addresses */
  191. bra __entry_kernel_data_tlb_miss
  192. .section .trap.fixup.user
  193. .org TBR_TT_INSTR_TLB_MISS >> 2
  194. .globl __trap_fixup_user_insn_tlb_miss
  195. __trap_fixup_user_insn_tlb_miss:
  196. .long __break_user_insn_tlb_miss
  197. .org TBR_TT_DATA_TLB_MISS >> 2
  198. .globl __trap_fixup_user_data_tlb_miss
  199. __trap_fixup_user_data_tlb_miss:
  200. .long __break_user_data_tlb_miss
  201. .section .trap.fixup.kernel
  202. .org TBR_TT_INSTR_TLB_MISS >> 2
  203. .globl __trap_fixup_kernel_insn_tlb_miss
  204. __trap_fixup_kernel_insn_tlb_miss:
  205. .long __break_kernel_insn_tlb_miss
  206. .org TBR_TT_DATA_TLB_MISS >> 2
  207. .globl __trap_fixup_kernel_data_tlb_miss
  208. __trap_fixup_kernel_data_tlb_miss:
  209. .long __break_kernel_data_tlb_miss
  210. .section .trap.vector
  211. .org TBR_TT_INSTR_TLB_MISS >> 2
  212. .long __entry_insn_mmu_fault
  213. .org TBR_TT_DATA_TLB_MISS >> 2
  214. .long __entry_data_mmu_fault
  215. #endif
  216. VECTOR_SP_MMU TBR_TT_DATA_DAT_EXCEP, __entry_data_dat_fault
  217. VECTOR_NMI TBR_TT_DECREMENT_TIMER, __entry_do_NMI
  218. VECTOR_SOFTPROG TBR_TT_COMPOUND_EXCEP, __entry_compound_exception
  219. VECTOR_IRQ TBR_TT_INTERRUPT_1, __entry_do_IRQ
  220. VECTOR_IRQ TBR_TT_INTERRUPT_2, __entry_do_IRQ
  221. VECTOR_IRQ TBR_TT_INTERRUPT_3, __entry_do_IRQ
  222. VECTOR_IRQ TBR_TT_INTERRUPT_4, __entry_do_IRQ
  223. VECTOR_IRQ TBR_TT_INTERRUPT_5, __entry_do_IRQ
  224. VECTOR_IRQ TBR_TT_INTERRUPT_6, __entry_do_IRQ
  225. VECTOR_IRQ TBR_TT_INTERRUPT_7, __entry_do_IRQ
  226. VECTOR_IRQ TBR_TT_INTERRUPT_8, __entry_do_IRQ
  227. VECTOR_IRQ TBR_TT_INTERRUPT_9, __entry_do_IRQ
  228. VECTOR_IRQ TBR_TT_INTERRUPT_10, __entry_do_IRQ
  229. VECTOR_IRQ TBR_TT_INTERRUPT_11, __entry_do_IRQ
  230. VECTOR_IRQ TBR_TT_INTERRUPT_12, __entry_do_IRQ
  231. VECTOR_IRQ TBR_TT_INTERRUPT_13, __entry_do_IRQ
  232. VECTOR_IRQ TBR_TT_INTERRUPT_14, __entry_do_IRQ
  233. VECTOR_NMI TBR_TT_INTERRUPT_15, __entry_do_NMI
  234. # miscellaneous user mode entry points
  235. .section .trap.user
  236. .org TBR_TT_TRAP0
  237. .rept 127
  238. bra __entry_uspace_softprog_interrupt
  239. bra __break_step_uspace_softprog_interrupt
  240. .long 0,0
  241. .endr
  242. .org TBR_TT_BREAK
  243. bra __entry_break
  244. .long 0,0,0
  245. # miscellaneous kernel mode entry points
  246. .section .trap.kernel
  247. .org TBR_TT_TRAP0
  248. .rept 127
  249. bra __entry_kernel_softprog_interrupt
  250. bra __break_step_kernel_softprog_interrupt
  251. .long 0,0
  252. .endr
  253. .org TBR_TT_BREAK
  254. bra __entry_break
  255. .long 0,0,0
  256. # miscellaneous debug mode entry points
  257. .section .trap.break
  258. .org TBR_TT_BREAK
  259. movsg bpcsr,gr30
  260. jmpl @(gr30,gr0)
  261. # miscellaneous vectors
  262. .section .trap.vector
  263. .org TBR_TT_TRAP0 >> 2
  264. .long system_call
  265. .rept 126
  266. .long __entry_unsupported_trap
  267. .endr
  268. .org TBR_TT_BREAK >> 2
  269. .long __entry_debug_exception