contexta.S 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*++
  2. Copyright (c) 2016 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. contexta.S
  9. Abstract:
  10. This module implements functionality for manipulating ucontext structures.
  11. Author:
  12. Evan Green 9-Sep-2016
  13. Environment:
  14. User Mode C Library
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <minoca/kernel/arm.inc>
  20. //
  21. // ---------------------------------------------------------------- Definitions
  22. //
  23. //
  24. // ----------------------------------------------------------------------- Code
  25. //
  26. ASSEMBLY_FILE_HEADER
  27. .fpu vfpv3
  28. //
  29. // LIBC_API
  30. // int
  31. // getcontext (
  32. // ucontext_t *Context
  33. // )
  34. //
  35. /*++
  36. Routine Description:
  37. This routine saves the current user context into the given structure,
  38. including the machine registers, signal mask, and execution stack pointer.
  39. If restored, the returned context will appear to execute at the return from
  40. this function.
  41. Arguments:
  42. Context - Supplies a pointer where the current context is saved.
  43. Return Value:
  44. 0 on success.
  45. -1 on failure, and errno will be set to contain more information.
  46. --*/
  47. EXPORTED_FUNCTION getcontext
  48. str %r1, [%r0, #(SIGNAL_CONTEXT_SIZE + TRAP_R1)] @ Save R1.
  49. str %r2, [%r0, #(SIGNAL_CONTEXT_SIZE + TRAP_R2)] @ Save R2.
  50. str %r3, [%r0, #(SIGNAL_CONTEXT_SIZE + TRAP_R3)] @ Save R3.
  51. mov %r2, %r0 @ Copy R0 into R2.
  52. add %r0, %r0, #SIGNAL_CONTEXT_SIZE @ Get to the TRAP_FRAME part.
  53. eor %r1, %r1, %r1 @ Clear R1.
  54. mov %r3, %sp @ Get SP in a regular register.
  55. stmia %r0!, {%r1, %r3, %lr} @ Save SVC Sp, User SP, and User LR.
  56. stmia %r0!, {%r1} @ Save a zeroed R0.
  57. stmia %r0!, {%r1} @ Save a zeroed exception CPSR.
  58. add %r0, %r0, #12 @ Skip R1-R3.
  59. stmia %r0!, {%r4-%r12} @ Save R4-R12.
  60. stmia %r0!, {%r1, %lr} @ Save zeroed SVC link, and PC.
  61. mrs %r1, CPSR @ Get the flags.
  62. stmia %r0!, {%r1} @ Save the CPSR.
  63. mov %r0, %r2 @ Get the context back.
  64. mov %r1, %sp @ Stack pointer as second argument.
  65. b ClpGetContext @ Tail call to clpgetcontext.
  66. END_FUNCTION getcontext
  67. //
  68. // LIBC_API
  69. // int
  70. // setcontext (
  71. // const ucontext_t *Context
  72. // )
  73. //
  74. /*++
  75. Routine Description:
  76. This routine restores a previous execution context into the current
  77. processor.
  78. Arguments:
  79. Context - Supplies a pointer to the previously saved context to restore.
  80. Return Value:
  81. Does not return on success, as execution continues from the new context.
  82. -1 on failure, and errno will be set to contain more information.
  83. --*/
  84. EXPORTED_FUNCTION setcontext
  85. stmdb %sp!, {%r0} @ Save R0.
  86. bl ClpSetContext @ Call the C helper.
  87. ldmia %sp!, {%r0} @ Restore R0.
  88. add %r2, %r0, #(SIGNAL_CONTEXT_SIZE + TRAP_USERSP) @ Get to user SP.
  89. ldmia %r2!, {%r3-%r7} @ Get User SP, lr, R0, exception CPSR, and R1.
  90. mov %sp, %r3 @ Restore SP.
  91. mov %lr, %r4 @ Restore LR.
  92. mov %r0, %r5 @ Restore R0.
  93. mov %r1, %r7 @ Restore R1.
  94. add %r2, %r2, #8 @ Skip R2 and R3.
  95. ldmia %r2!, {%r4-%r12} @ Restore R4-R12.
  96. add %r2, %r2, #4 @ Skip Svc link.
  97. ldmia %r2!, {%r3} @ Restore PC into R3. Ignore CPSR.
  98. bx %r3 @ Jump to PC.
  99. END_FUNCTION setcontext
  100. //
  101. // __NO_RETURN
  102. // void
  103. // ClpContextStart (
  104. // void (*StartFunction)(),
  105. // ...
  106. // )
  107. //
  108. /*++
  109. Routine Description:
  110. This routine is a small trampoline that calls the function specified in
  111. makecontext.
  112. Arguments:
  113. StartFunction - Supplies a pointer to the function to call.
  114. ... - Supplies the arguments the start function takes.
  115. Return Value:
  116. This routine does not return.
  117. --*/
  118. FUNCTION ClpContextStart
  119. ldmia %sp!, {%r12} @ Get the function to call.
  120. ldmia %sp!, {%r0-%r3} @ Pop the register arguments.
  121. blx %r12 @ Jump to the function to call.
  122. mov %sp, %r4 @ Pop the function and arguments.
  123. ldmia %sp!, {%r0} @ Pop the context pointer.
  124. bl ClpContextEnd @ Call the C helper to switch contexts.
  125. DEBUGGER_BREAK @ Execution should never reach here.
  126. END_FUNCTION ClpContextStart
  127. //
  128. // VOID
  129. // ClpSaveVfp (
  130. // PFPU_CONTEXT Context,
  131. // BOOL SimdSupport
  132. // )
  133. //
  134. /*++
  135. Routine Description:
  136. This routine saves the Vector Floating Point unit state.
  137. Arguments:
  138. Context - Supplies a pointer where the context will be saved.
  139. SimdSupport - Supplies a boolean indicating whether the VFP unit contains
  140. 32 64-bit registers (TRUE) or 16 64-bit registers (FALSE).
  141. Return Value:
  142. None.
  143. --*/
  144. FUNCTION ClpSaveVfp
  145. stc p11, c0, [%r0], #16*8 @ Save D0-D15 (stmia).
  146. cmp %r1, #0 @ Test for no SIMD support.
  147. ITE(ne) @ If equal then else.
  148. stclne p11, c0, [%r0], #16*8 @ Save D16-D31 if SIMD support.
  149. addeq %r0, %r0, #16*8 @ Skip those registers if not.
  150. vmrs %r2, FPSCR @ Get FPSCR.
  151. str %r2, [%r0] @ Store it.
  152. bx %lr @ Return.
  153. END_FUNCTION ClpSaveVfp
  154. //
  155. // VOID
  156. // ClpRestoreVfp (
  157. // PFPU_CONTEXT Context,
  158. // BOOL SimdSupport
  159. // )
  160. //
  161. /*++
  162. Routine Description:
  163. This routine restores the Vector Floating Point unit state into the
  164. hardware.
  165. Arguments:
  166. Context - Supplies a pointer to the context to restore.
  167. SimdSupport - Supplies a boolean indicating whether the VFP unit contains
  168. 32 64-bit registers (TRUE) or 16 64-bit registers (FALSE).
  169. Return Value:
  170. None.
  171. --*/
  172. FUNCTION ClpRestoreVfp
  173. ldc p11, c0, [%r0], #16*8 @ Restore D0-D15 (ldmia).
  174. cmp %r1, #0 @ Test for no SIMD support.
  175. ITE(ne) @ If equal then else.
  176. ldclne p11, c0, [%r0], #16*8 @ Restore D16-D31 if SIMD support.
  177. addeq %r0, %r0, #16*8 @ Skip those registers if not.
  178. ldr %r2, [%r0] @ Get FPSCR.
  179. vmsr FPSCR, %r2 @ Restore FPSCR.
  180. bx %lr @ Return.
  181. END_FUNCTION ClpRestoreVfp