trap.S 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. trap.S
  5. Abstract:
  6. This module implements interrupt and exception trap management, such as
  7. saving and restoring registers.
  8. Author:
  9. Evan Green 11-Aug-2012
  10. Environment:
  11. Kernel mode
  12. --*/
  13. ##
  14. ## ------------------------------------------------------------------- Includes
  15. ##
  16. #include <minoca/kernel/arm.inc>
  17. ##
  18. ## ---------------------------------------------------------------- Definitions
  19. ##
  20. ##
  21. ## ---------------------------------------------------------------------- Code
  22. ##
  23. ASSEMBLY_FILE_HEADER
  24. ##
  25. ## VOID
  26. ## ArpInitializeExceptionStacks (
  27. ## PVOID ExceptionStacksBase,
  28. ## ULONG ExceptionStackSize
  29. ## )
  30. ##
  31. /*++
  32. Routine Description:
  33. This routine initializes the stack pointer for all privileged ARM modes. It
  34. switches into each mode and initializes the banked r13. This function
  35. should be called with interrupts disabled and returns with interrupts
  36. disabled.
  37. Arguments:
  38. ExceptionStacksBase - Supplies a pointer to the lowest address that should
  39. be used for exception stacks. Each stack takes up 16 bytes and there are
  40. 4 modes, so at least 64 bytes are needed.
  41. ExceptionStackSize - Supplies the size of each exception stack.
  42. Return Value:
  43. None.
  44. --*/
  45. FUNCTION ArpInitializeExceptionStacks
  46. ##
  47. ## Load R1 with an individual stack size.
  48. ##
  49. add %r0, %r0, %r1
  50. ##
  51. ## Disable interrupts and switch into IRQ mode. Note that this also
  52. ## clobbers the flags register.
  53. ##
  54. mov %r2, #(PSR_FLAG_IRQ | ARM_MODE_IRQ)
  55. msr CPSR_cxsf, %r2
  56. mov %sp, %r0
  57. add %r0, %r0, %r1
  58. ##
  59. ## Initialize the FIQ stack.
  60. ##
  61. mov %r2, #(PSR_FLAG_IRQ | ARM_MODE_FIQ)
  62. msr CPSR_cxsf, %r2
  63. mov %sp, %r0
  64. add %r0, %r0, %r1
  65. ##
  66. ## Initialize the undefined instruction stack.
  67. ##
  68. mov %r2, #(PSR_FLAG_IRQ | ARM_MODE_UNDEF)
  69. msr CPSR_cxsf, %r2
  70. mov %sp, %r0
  71. add %r0, %r0, %r1
  72. ##
  73. ## Initialize the data fetch abort stack.
  74. ##
  75. mov %r2, #(PSR_FLAG_IRQ | ARM_MODE_ABORT)
  76. msr CPSR_cxsf, %r2
  77. mov %sp, %r0
  78. ##
  79. ## Switch back to SVC mode and return.
  80. ##
  81. mov %r2, #(PSR_FLAG_IRQ | ARM_MODE_SVC)
  82. msr CPSR_cxsf, %r2
  83. bx %lr
  84. END_FUNCTION ArpInitializeExceptionStacks
  85. ##
  86. ## VOID
  87. ## ArpUndefinedInstructionEntry (
  88. ## VOID
  89. ## )
  90. ##
  91. /*++
  92. Routine Description:
  93. This routine directly handles an exception generated by an undefined
  94. instruction. It uses a largely separate code path from normal exceptions
  95. to avoid recursively breaking into the debugger.
  96. Arguments:
  97. None.
  98. Return Value:
  99. None.
  100. --*/
  101. FUNCTION ArpUndefinedInstructionEntry
  102. ##
  103. ## Save state and create a trap frame.
  104. ##
  105. ARM_ENTER_INTERRUPT
  106. ##
  107. ## Call the main dispatch routine routine with a pointer to the trap frame
  108. ## as the only parameter. Align the stack down even though it shouldn't be
  109. ## strictly necessary in case something bad happened.
  110. ##
  111. mov %r0, %sp
  112. mov %r4, %sp
  113. and %r1, %r4, #0xFFFFFFF0 @ Align stack down for fear of badness.
  114. mov %sp, %r1
  115. bl KeDispatchUndefinedInstructionException
  116. mov %sp, %r4
  117. ##
  118. ## Restore state and return.
  119. ##
  120. ARM_EXIT_INTERRUPT
  121. END_FUNCTION ArpUndefinedInstructionEntry
  122. ##
  123. ## VOID
  124. ## ArpSoftwareInterruptEntry (
  125. ## VOID
  126. ## )
  127. ##
  128. /*++
  129. Routine Description:
  130. This routine directly handles an exception generated by a software
  131. interrupt (a system call).
  132. Arguments:
  133. None.
  134. Return Value:
  135. None.
  136. --*/
  137. FUNCTION ArpSoftwareInterruptEntry
  138. srsdb %sp!, #ARM_MODE_SVC @ Push lr and spsr.
  139. mov %lr, #0 @ Zero SVC link register.
  140. stmdb %sp!, {%r1-%r12, %lr} @ Push general registers.
  141. mrs %r2, cpsr @ Get the "exception" CPSR.
  142. stmdb %sp!, {%r0, %r2} @ Push exception CPSR and R0.
  143. mov %r4, %sp @ Get stack.
  144. sub %sp, #8 @ Account for pushes.
  145. cps #ARM_MODE_SYSTEM @ Switch to system mode.
  146. str %lr, [%r4, #-4] @ Save usermode SP.
  147. str %sp, [%r4, #-8] @ Save usermode LR.
  148. cpsie i, #ARM_MODE_SVC @ Enable interrupts, svc mode.
  149. sub %sp, #4 @ Allocate room for sp.
  150. str %sp, [%sp] @ Save SP.
  151. ##
  152. ## The system call routine takes three parameters: the system call number,
  153. ## system call parameter, and a pointer to the trap frame. User-mode already
  154. ## set up the first two parameters in R0 and R1, and they were preserved
  155. ## throughout the context save process here. So all that's left is to put a
  156. ## pointer to the trap frame in R2.
  157. ##
  158. mov %r2, %sp
  159. bl KeSystemCallHandler
  160. ##
  161. ## Restore state and return.
  162. ##
  163. ARM_EXIT_INTERRUPT
  164. END_FUNCTION ArpSoftwareInterruptEntry
  165. ##
  166. ## VOID
  167. ## ArpPrefetchAbortEntry (
  168. ## VOID
  169. ## )
  170. ##
  171. /*++
  172. Routine Description:
  173. This routine directly handles an exception generated by a prefetch abort
  174. (page fault).
  175. Arguments:
  176. None.
  177. Return Value:
  178. None.
  179. --*/
  180. FUNCTION ArpPrefetchAbortEntry
  181. ##
  182. ## In ARM mode, prefect aborts save the PC-4 in LR. For Thumb mode, data
  183. ## aborts save the PC in LR. Thus, the PC is always 4 bytes head of the
  184. ## faulting address.
  185. ##
  186. sub %lr, %lr, #4 @ Prefetches go too far by 4.
  187. ##
  188. ## Save state and create a trap frame.
  189. ##
  190. ARM_ENTER_INTERRUPT
  191. ##
  192. ## Call the main dispatch routine routine with a pointer to the trap frame
  193. ## and 1 to indicate a prefetch abort.
  194. ##
  195. mov %r0, %sp
  196. mov %r1, #1
  197. blx KeDispatchException
  198. ##
  199. ## Restore state and return.
  200. ##
  201. ARM_EXIT_INTERRUPT
  202. END_FUNCTION ArpPrefetchAbortEntry
  203. ##
  204. ## VOID
  205. ## ArpDataAbortEntry (
  206. ## VOID
  207. ## )
  208. ##
  209. /*++
  210. Routine Description:
  211. This routine directly handles an exception generated by a data abort (page
  212. fault).
  213. Arguments:
  214. None.
  215. Return Value:
  216. None.
  217. --*/
  218. FUNCTION ArpDataAbortEntry
  219. ##
  220. ## In ARM mode, data aborts save the PC in LR. For Thumb mode, data aborts
  221. ## save the PC+4 in LR. Thus, the PC is always 8 bytes head of the faulting
  222. ## address.
  223. ##
  224. sub %lr, %lr, #8
  225. ##
  226. ## Save state and create a trap frame.
  227. ##
  228. ARM_ENTER_INTERRUPT
  229. ##
  230. ## Call the main dispatch routine routine with a pointer to the trap frame
  231. ## and 0 to indicate a prefetch abort.
  232. ##
  233. mov %r0, %sp
  234. mov %r1, #0
  235. blx KeDispatchException
  236. ##
  237. ## Restore state and return.
  238. ##
  239. ARM_EXIT_INTERRUPT
  240. END_FUNCTION ArpDataAbortEntry
  241. ##
  242. ## VOID
  243. ## ArpIrqEntry (
  244. ## VOID
  245. ## )
  246. ##
  247. /*++
  248. Routine Description:
  249. This routine directly handles an exception generated by an external
  250. interrupt on the IRQ pin.
  251. Arguments:
  252. None.
  253. Return Value:
  254. None.
  255. --*/
  256. FUNCTION ArpIrqEntry
  257. b ArpCommonInterruptEntry
  258. END_FUNCTION ArpIrqEntry
  259. ##
  260. ## VOID
  261. ## ArpFiqEntry (
  262. ## VOID
  263. ## )
  264. ##
  265. /*++
  266. Routine Description:
  267. This routine directly handles an exception generated by an external
  268. interrupt on the FIQ pin.
  269. Arguments:
  270. None.
  271. Return Value:
  272. None.
  273. --*/
  274. FUNCTION ArpFiqEntry
  275. b ArpCommonInterruptEntry
  276. END_FUNCTION ArpFiqEntry
  277. ##
  278. ## --------------------------------------------------------- Internal Functions
  279. ##
  280. ##
  281. ## This code is entered as the result of any interrupt or exception. Its job is
  282. ## to transition back to the SVC stack and then call the real interrupt
  283. ## dispatch routine.
  284. ##
  285. ArpCommonInterruptEntry:
  286. ##
  287. ## Save state and create a trap frame.
  288. ##
  289. ARM_ENTER_INTERRUPT
  290. ##
  291. ## Call the main dispatch routine routine with a pointer to the trap frame
  292. ## as the only parameter. Align the stack down in case the exception
  293. ## interrupted something unaligned.
  294. ##
  295. mov %r0, %sp
  296. mov %r4, %sp
  297. and %r5, %r4, #0xFFFFFFF0
  298. mov %sp, %r5
  299. bl KeDispatchException
  300. mov %sp, %r4
  301. ##
  302. ## Restore state and return.
  303. ##
  304. ARM_EXIT_INTERRUPT