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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * PAL Firmware support
  3.  * IA-64 Processor Programmers Reference Vol 2
  4.  *
  5.  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  6.  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  7.  * Copyright (C) 1999-2001 Hewlett-Packard Co
  8.  * David Mosberger <davidm@hpl.hp.com>
  9.  * Stephane Eranian <eranian@hpl.hp.com>
  10.  *
  11.  * 05/22/2000 eranian Added support for stacked register calls
  12.  * 05/24/2000 eranian Added support for physical mode static calls
  13.  */
  14. #include <asm/asmmacro.h>
  15. #include <asm/processor.h>
  16. .data
  17. pal_entry_point:
  18. data8 ia64_pal_default_handler
  19. .text
  20. /*
  21.  * Set the PAL entry point address.  This could be written in C code, but we do it here
  22.  * to keep it all in one module (besides, it's so trivial that it's
  23.  * not a big deal).
  24.  *
  25.  * in0 Address of the PAL entry point (text address, NOT a function descriptor).
  26.  */
  27. GLOBAL_ENTRY(ia64_pal_handler_init)
  28. alloc r3=ar.pfs,1,0,0,0
  29. movl r2=pal_entry_point
  30. ;;
  31. st8 [r2]=in0
  32. br.ret.sptk.many rp
  33. END(ia64_pal_handler_init)
  34. /*
  35.  * Default PAL call handler.  This needs to be coded in assembly because it uses
  36.  * the static calling convention, i.e., the RSE may not be used and calls are
  37.  * done via "br.cond" (not "br.call").
  38.  */
  39. GLOBAL_ENTRY(ia64_pal_default_handler)
  40. mov r8=-1
  41. br.cond.sptk.many rp
  42. END(ia64_pal_default_handler)
  43. /*
  44.  * Make a PAL call using the static calling convention.
  45.  *
  46.  * in0         Index of PAL service
  47.  * in1 - in3   Remaining PAL arguments
  48.  * in4        1 ==> clear psr.ic,  0 ==> don't clear psr.ic
  49.  *
  50.  */
  51. GLOBAL_ENTRY(ia64_pal_call_static)
  52. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6)
  53. alloc loc1 = ar.pfs,6,90,0,0
  54. movl loc2 = pal_entry_point
  55. 1: {
  56.   mov r28 = in0
  57.   mov r29 = in1
  58.   mov r8 = ip
  59. }
  60. ;;
  61. ld8 loc2 = [loc2] // loc2 <- entry point
  62. tbit.nz p6,p7 = in4, 0
  63. adds r8 = 1f-1b,r8
  64. ;;
  65. mov loc3 = psr
  66. mov loc0 = rp
  67. .body
  68. mov r30 = in2
  69. (p6) rsm psr.i | psr.ic
  70. mov r31 = in3
  71. mov b7 = loc2
  72. (p7) rsm psr.i
  73. ;;
  74. (p6) srlz.i
  75. mov rp = r8
  76. br.cond.sptk.many b7
  77. 1: mov psr.l = loc3
  78. mov ar.pfs = loc1
  79. mov rp = loc0
  80. ;;
  81. srlz.d // seralize restoration of psr.l
  82. br.ret.sptk.many b0
  83. END(ia64_pal_call_static)
  84. /*
  85.  * Make a PAL call using the stacked registers calling convention.
  86.  *
  87.  * Inputs:
  88.  *  in0         Index of PAL service
  89.  *  in2 - in3   Remaning PAL arguments
  90.  */
  91. GLOBAL_ENTRY(ia64_pal_call_stacked)
  92. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
  93. alloc loc1 = ar.pfs,5,4,87,0
  94. movl loc2 = pal_entry_point
  95. mov r28  = in0 // Index MUST be copied to r28
  96. mov out0 = in0 // AND in0 of PAL function
  97. mov loc0 = rp
  98. .body
  99. ;;
  100. ld8 loc2 = [loc2] // loc2 <- entry point
  101. mov out1 = in1
  102. mov out2 = in2
  103. mov out3 = in3
  104. mov loc3 = psr
  105. ;;
  106. rsm psr.i
  107. mov b7 = loc2
  108. ;; 
  109. br.call.sptk.many rp=b7 // now make the call
  110. .ret0: mov psr.l  = loc3
  111. mov ar.pfs = loc1
  112. mov rp = loc0
  113. ;;
  114. srlz.d // serialize restoration of psr.l
  115. br.ret.sptk.many b0
  116. END(ia64_pal_call_stacked)
  117. /*
  118.  * Make a physical mode PAL call using the static registers calling convention.
  119.  *
  120.  * Inputs:
  121.  *  in0         Index of PAL service
  122.  *  in2 - in3   Remaning PAL arguments
  123.  *
  124.  * PSR_DB, PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
  125.  * So we don't need to clear them.
  126.  */
  127. #define PAL_PSR_BITS_TO_CLEAR
  128. (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT |
  129.  IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |
  130.  IA64_PSR_DFL | IA64_PSR_DFH)
  131. #define PAL_PSR_BITS_TO_SET
  132. (IA64_PSR_BN)
  133. GLOBAL_ENTRY(ia64_pal_call_phys_static)
  134. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6)
  135. alloc loc1 = ar.pfs,6,90,0,0
  136. movl loc2 = pal_entry_point
  137. 1: {
  138.   mov r28  = in0 // copy procedure index
  139.   mov r8   = ip // save ip to compute branch
  140.   mov loc0 = rp // save rp
  141. }
  142. .body
  143. ;;
  144. ld8 loc2 = [loc2] // loc2 <- entry point
  145. mov r29  = in1 // first argument
  146. mov r30  = in2 // copy arg2
  147. mov r31  = in3 // copy arg3
  148. ;;
  149. mov loc3 = psr // save psr
  150. adds r8  = 1f-1b,r8 // calculate return address for call
  151. ;; 
  152. mov loc4=ar.rsc // save RSE configuration
  153. dep.z loc2=loc2,0,61 // convert pal entry point to physical
  154. dep.z r8=r8,0,61 // convert rp to physical
  155. ;;
  156. mov b7 = loc2 // install target to branch reg
  157. mov ar.rsc=0 // put RSE in enforced lazy, LE mode
  158. movl r16=PAL_PSR_BITS_TO_CLEAR
  159. movl r17=PAL_PSR_BITS_TO_SET
  160. ;;
  161. or loc3=loc3,r17 // add in psr the bits to set
  162. ;;
  163. andcm r16=loc3,r16 // removes bits to clear from psr
  164. br.call.sptk.many rp=ia64_switch_mode
  165. .ret1: mov rp = r8 // install return address (physical)
  166. br.cond.sptk.many b7
  167. 1:
  168. mov ar.rsc=0 // put RSE in enforced lazy, LE mode
  169. mov r16=loc3 // r16= original psr
  170. br.call.sptk.many rp=ia64_switch_mode // return to virtual mode
  171. .ret2:
  172. mov psr.l = loc3 // restore init PSR
  173. mov ar.pfs = loc1
  174. mov rp = loc0
  175. ;;
  176. mov ar.rsc=loc4 // restore RSE configuration
  177. srlz.d // seralize restoration of psr.l
  178. br.ret.sptk.many b0
  179. END(ia64_pal_call_phys_static)
  180. /*
  181.  * Make a PAL call using the stacked registers in physical mode.
  182.  *
  183.  * Inputs:
  184.  *  in0         Index of PAL service
  185.  *  in2 - in3   Remaning PAL arguments
  186.  */
  187. GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
  188. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
  189. alloc loc1 = ar.pfs,5,5,86,0
  190. movl loc2 = pal_entry_point
  191. 1: {
  192.   mov r28  = in0 // copy procedure index
  193.   mov loc0 = rp // save rp
  194. }
  195. .body
  196. ;;
  197. ld8 loc2 = [loc2] // loc2 <- entry point
  198. mov out0 = in0 // first argument
  199. mov out1 = in1 // copy arg2
  200. mov out2 = in2 // copy arg3
  201. mov out3 = in3 // copy arg3
  202. ;;
  203. mov loc3 = psr // save psr
  204. ;; 
  205. mov loc4=ar.rsc // save RSE configuration
  206. dep.z loc2=loc2,0,61 // convert pal entry point to physical
  207. ;;
  208. mov ar.rsc=0 // put RSE in enforced lazy, LE mode
  209. movl r16=PAL_PSR_BITS_TO_CLEAR
  210. movl r17=PAL_PSR_BITS_TO_SET
  211. ;;
  212. or loc3=loc3,r17 // add in psr the bits to set
  213. mov b7 = loc2 // install target to branch reg
  214. ;;
  215. andcm r16=loc3,r16 // removes bits to clear from psr
  216. br.call.sptk.many rp=ia64_switch_mode
  217. .ret6:
  218. br.call.sptk.many rp=b7 // now make the call
  219. .ret7:
  220. mov ar.rsc=0 // put RSE in enforced lazy, LE mode
  221. mov r16=loc3 // r16= original psr
  222. br.call.sptk.many rp=ia64_switch_mode // return to virtual mode
  223. .ret8: mov psr.l  = loc3 // restore init PSR
  224. mov ar.pfs = loc1
  225. mov rp = loc0
  226. ;;
  227. mov ar.rsc=loc4 // restore RSE configuration
  228. srlz.d // seralize restoration of psr.l
  229. br.ret.sptk.many b0
  230. END(ia64_pal_call_phys_stacked)