gate.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * This file contains the code that gets mapped at the upper end of each task's text
  3.  * region.  For now, it contains the signal trampoline code only.
  4.  *
  5.  * Copyright (C) 1999-2001 Hewlett-Packard Co
  6.  *  David Mosberger-Tang <davidm@hpl.hp.com>
  7.  */
  8. #include <asm/asmmacro.h>
  9. #include <asm/offsets.h>
  10. #include <asm/sigcontext.h>
  11. #include <asm/system.h>
  12. #include <asm/unistd.h>
  13. #include <asm/page.h>
  14. .section .text.gate,"ax"
  15. # define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET)
  16. # define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET)
  17. # define ARG2_OFF (16 + IA64_SIGFRAME_ARG2_OFFSET)
  18. # define SIGHANDLER_OFF (16 + IA64_SIGFRAME_HANDLER_OFFSET)
  19. # define SIGCONTEXT_OFF (16 + IA64_SIGFRAME_SIGCONTEXT_OFFSET)
  20. # define FLAGS_OFF IA64_SIGCONTEXT_FLAGS_OFFSET
  21. # define CFM_OFF IA64_SIGCONTEXT_CFM_OFFSET
  22. # define FR6_OFF IA64_SIGCONTEXT_FR6_OFFSET
  23. # define BSP_OFF IA64_SIGCONTEXT_AR_BSP_OFFSET
  24. # define RNAT_OFF IA64_SIGCONTEXT_AR_RNAT_OFFSET
  25. # define UNAT_OFF IA64_SIGCONTEXT_AR_UNAT_OFFSET
  26. # define FPSR_OFF IA64_SIGCONTEXT_AR_FPSR_OFFSET
  27. # define PR_OFF IA64_SIGCONTEXT_PR_OFFSET
  28. # define RP_OFF IA64_SIGCONTEXT_B0_OFFSET
  29. # define SP_OFF IA64_SIGCONTEXT_R12_OFFSET
  30. # define RBS_BASE_OFF IA64_SIGCONTEXT_RBS_BASE_OFFSET
  31. # define LOADRS_OFF IA64_SIGCONTEXT_LOADRS_OFFSET
  32. # define base0 r2
  33. # define base1 r3
  34. /*
  35.  * When we get here, the memory stack looks like this:
  36.  *
  37.  *   +===============================+
  38.          *   |      |
  39.          *   //     struct sigframe          //
  40.          *   |      |
  41.  *   +-------------------------------+ <-- sp+16
  42.  *   |      16 byte of scratch       |
  43.  *   |            space              |
  44.  *   +-------------------------------+ <-- sp
  45.  *
  46.  * The register stack looks _exactly_ the way it looked at the time the signal
  47.  * occurred.  In other words, we're treading on a potential mine-field: each
  48.  * incoming general register may be a NaT value (including sp, in which case the
  49.  * process ends up dying with a SIGSEGV).
  50.  *
  51.  * The first thing need to do is a cover to get the registers onto the backing
  52.  * store.  Once that is done, we invoke the signal handler which may modify some
  53.  * of the machine state.  After returning from the signal handler, we return
  54.  * control to the previous context by executing a sigreturn system call.  A signal
  55.  * handler may call the rt_sigreturn() function to directly return to a given
  56.  * sigcontext.  However, the user-level sigreturn() needs to do much more than
  57.  * calling the rt_sigreturn() system call as it needs to unwind the stack to
  58.  * restore preserved registers that may have been saved on the signal handler's
  59.  * call stack.
  60.  */
  61. GLOBAL_ENTRY(ia64_sigtramp)
  62. // describe the state that is active when we get here:
  63. .prologue
  64. .unwabi @svr4, 's' // mark this as a sigtramp handler (saves scratch regs)
  65. .savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF
  66. .savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF
  67. .savesp pr, PR_OFF+SIGCONTEXT_OFF
  68. .savesp rp, RP_OFF+SIGCONTEXT_OFF
  69. .vframesp SP_OFF+SIGCONTEXT_OFF
  70. .body
  71. .label_state 1
  72. adds base0=SIGHANDLER_OFF,sp
  73. adds base1=RBS_BASE_OFF+SIGCONTEXT_OFF,sp
  74. br.call.sptk.many rp=1f
  75. 1:
  76. ld8 r17=[base0],(ARG0_OFF-SIGHANDLER_OFF) // get pointer to signal handler's plabel
  77. ld8 r15=[base1] // get address of new RBS base (or NULL)
  78. cover // push args in interrupted frame onto backing store
  79. ;;
  80. cmp.ne p8,p0=r15,r0 // do we need to switch the rbs?
  81. mov.m r9=ar.bsp // fetch ar.bsp
  82. .spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
  83. (p8) br.cond.spnt setup_rbs // yup -> (clobbers r14, r15, and r16)
  84. back_from_setup_rbs:
  85. .save ar.pfs, r8
  86. alloc r8=ar.pfs,0,0,3,0 // get CFM0, EC0, and CPL0 into r8
  87. ld8 out0=[base0],16 // load arg0 (signum)
  88. adds base1=(ARG1_OFF-(RBS_BASE_OFF+SIGCONTEXT_OFF)),base1
  89. ;;
  90. ld8 out1=[base1] // load arg1 (siginfop)
  91. ld8 r10=[r17],8 // get signal handler entry point
  92. ;;
  93. ld8 out2=[base0] // load arg2 (sigcontextp)
  94. ld8 gp=[r17] // get signal handler's global pointer
  95. adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
  96. ;;
  97. .spillsp ar.bsp, BSP_OFF+SIGCONTEXT_OFF
  98. st8 [base0]=r9,(CFM_OFF-BSP_OFF) // save sc_ar_bsp
  99. dep r8=0,r8,38,26 // clear EC0, CPL0 and reserved bits
  100. adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
  101. ;;
  102. .spillsp ar.pfs, CFM_OFF
  103. st8 [base0]=r8 // save CFM0
  104. adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
  105. ;;
  106. stf.spill [base0]=f6,32
  107. stf.spill [base1]=f7,32
  108. ;;
  109. stf.spill [base0]=f8,32
  110. stf.spill [base1]=f9,32
  111. mov b6=r10
  112. ;;
  113. stf.spill [base0]=f10,32
  114. stf.spill [base1]=f11,32
  115. ;;
  116. stf.spill [base0]=f12,32
  117. stf.spill [base1]=f13,32
  118. ;;
  119. stf.spill [base0]=f14,32
  120. stf.spill [base1]=f15,32
  121. br.call.sptk.many rp=b6 // call the signal handler
  122. .ret0: adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
  123. ;;
  124. ld8 r15=[base0],(CFM_OFF-BSP_OFF) // fetch sc_ar_bsp and advance to CFM_OFF
  125. mov r14=ar.bsp
  126. ;;
  127. ld8 r8=[base0] // restore (perhaps modified) CFM0, EC0, and CPL0
  128. cmp.ne p8,p0=r14,r15 // do we need to restore the rbs?
  129. (p8) br.cond.spnt restore_rbs // yup -> (clobbers r14 and r16)
  130. ;;
  131. back_from_restore_rbs:
  132. adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
  133. adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
  134. ;;
  135. ldf.fill f6=[base0],32
  136. ldf.fill f7=[base1],32
  137. ;;
  138. ldf.fill f8=[base0],32
  139. ldf.fill f9=[base1],32
  140. ;;
  141. ldf.fill f10=[base0],32
  142. ldf.fill f11=[base1],32
  143. ;;
  144. ldf.fill f12=[base0],32
  145. ldf.fill f13=[base1],32
  146. ;;
  147. ldf.fill f14=[base0],32
  148. ldf.fill f15=[base1],32
  149. mov r15=__NR_rt_sigreturn
  150. break __BREAK_SYSCALL
  151. .body
  152. .copy_state 1
  153. setup_rbs:
  154. mov ar.rsc=0 // put RSE into enforced lazy mode
  155. ;;
  156. .save ar.rnat, r16
  157. mov r16=ar.rnat // save RNaT before switching backing store area
  158. adds r14=(RNAT_OFF+SIGCONTEXT_OFF),sp
  159. mov ar.bspstore=r15 // switch over to new register backing store area
  160. ;;
  161. .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
  162. st8 [r14]=r16 // save sc_ar_rnat
  163. adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp
  164. mov.m r16=ar.bsp // sc_loadrs <- (new bsp - new bspstore) << 16
  165. ;;
  166. invala
  167. sub r15=r16,r15
  168. ;;
  169. shl r15=r15,16
  170. ;;
  171. st8 [r14]=r15 // save sc_loadrs
  172. mov ar.rsc=0xf // set RSE into eager mode, pl 3
  173. br.cond.sptk back_from_setup_rbs
  174. .prologue
  175. .copy_state 1
  176. .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
  177. .body
  178. restore_rbs:
  179. alloc r2=ar.pfs,0,0,0,0 // alloc null frame
  180. adds r16=(LOADRS_OFF+SIGCONTEXT_OFF),sp
  181. ;;
  182. ld8 r14=[r16]
  183. adds r16=(RNAT_OFF+SIGCONTEXT_OFF),sp
  184. ;;
  185. mov ar.rsc=r14 // put RSE into enforced lazy mode
  186. ld8 r14=[r16] // get new rnat
  187. ;;
  188. loadrs // restore dirty partition
  189. ;;
  190. mov ar.bspstore=r15 // switch back to old register backing store area
  191. ;;
  192. mov ar.rnat=r14 // restore RNaT
  193. mov ar.rsc=0xf // (will be restored later on from sc_ar_rsc)
  194. // invala not necessary as that will happen when returning to user-mode
  195. br.cond.sptk back_from_restore_rbs
  196. END(ia64_sigtramp)