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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  * This file is subject to the terms and conditions of the GNU General Public
  4.  * License.  See the file "COPYING" in the main directory of this archive
  5.  * for more details.
  6.  *
  7.  * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com)
  8.  *
  9.  */
  10. #define __ASSEMBLY__
  11. #include <asm/assembly.h>
  12. #include <asm/psw.h>
  13. .section .bss
  14. .export real_stack
  15. .align 64
  16. real_stack:
  17. .block 8192
  18. #ifdef __LP64__
  19. #  define REG_SZ 8
  20. #else
  21. #  define REG_SZ 4
  22. #endif
  23. #define N_SAVED_REGS 9
  24. save_cr_space:
  25. .block REG_SZ * N_SAVED_REGS
  26. /************************ 32-bit real-mode calls ***********************/
  27. /* This can be called in both narrow and wide kernels */
  28. .text
  29. .export real32_call_asm
  30. /* unsigned long real32_call_asm(unsigned int *sp,
  31.  * unsigned int *arg0p,
  32.  * unsigned int iodc_fn)
  33.  * sp is value of stack pointer to adopt before calling PDC (virt)
  34.  * arg0p points to where saved arg values may be found
  35.  * iodc_fn is the IODC function to call
  36.  */
  37. real32_call_asm:
  38. STREG %rp, -RP_OFFSET(%sp) /* save RP */
  39. #ifdef __LP64__
  40. callee_save
  41. ldo 2*REG_SZ(%sp), %sp /* room for a couple more saves */
  42. STREG %r27, -1*REG_SZ(%sp)
  43. STREG %r29, -2*REG_SZ(%sp)
  44. #endif
  45. STREG %sp, -REG_SZ(%arg0) /* save SP on real-mode stack */
  46. copy %arg0, %sp /* adopt the real-mode SP */
  47. /* save iodc_fn */
  48. copy %arg2, %r31
  49. /* load up the arg registers from the saved arg area */
  50. /* 32-bit calling convention passes first 4 args in registers */
  51. ldw 0(%arg1), %arg0 /* note overwriting arg0 */
  52. ldw -8(%arg1), %arg2
  53. ldw -12(%arg1), %arg3
  54. ldw -4(%arg1), %arg1 /* obviously must do this one last! */
  55. tophys %sp
  56. b,l rfi_virt2real,%r2
  57. nop
  58. b,l save_control_regs,%r2 /* modifies r1, r2, r28 */
  59. nop
  60. #ifdef __LP64__
  61. rsm PSW_SM_W, %r0 /* go narrow */
  62. #endif
  63. ldil L%PA(ric_ret), %r2
  64. ldo R%PA(ric_ret)(%r2), %r2
  65. bv 0(%r31)
  66. nop
  67. ric_ret:
  68. #ifdef __LP64__
  69. ssm PSW_SM_W, %r0 /* go wide */
  70. #endif
  71. /* restore CRs before going virtual in case we page fault */
  72. b,l restore_control_regs, %r2 /* modifies r1, r2, r26 */
  73. nop
  74. b,l rfi_real2virt,%r2
  75. nop
  76. tovirt %sp
  77. LDREG -REG_SZ(%sp), %sp /* restore SP */
  78. #ifdef __LP64__
  79. LDREG -1*REG_SZ(%sp), %r27
  80. LDREG -2*REG_SZ(%sp), %r29
  81. ldo -2*REG_SZ(%sp), %sp
  82. callee_rest
  83. #endif
  84. LDREG -RP_OFFSET(%sp), %rp /* restore RP */
  85. bv 0(%rp)
  86. nop
  87. #  define PUSH_CR(r, where) mfctl r, %r1 ! STREG,ma %r1, REG_SZ(where)
  88. #  define POP_CR(r, where) LDREG,mb -REG_SZ(where), %r1 ! mtctl %r1, r
  89. .text
  90. save_control_regs:
  91. load32 PA(save_cr_space), %r28
  92. PUSH_CR(%cr24, %r28)
  93. PUSH_CR(%cr25, %r28)
  94. PUSH_CR(%cr26, %r28)
  95. PUSH_CR(%cr27, %r28)
  96. PUSH_CR(%cr28, %r28)
  97. PUSH_CR(%cr29, %r28)
  98. PUSH_CR(%cr30, %r28)
  99. PUSH_CR(%cr31, %r28)
  100. PUSH_CR(%cr15, %r28)
  101. bv 0(%r2)
  102. nop
  103. restore_control_regs:
  104. load32 PA(save_cr_space + (N_SAVED_REGS * REG_SZ)), %r26
  105. POP_CR(%cr15, %r26)
  106. POP_CR(%cr31, %r26)
  107. POP_CR(%cr30, %r26)
  108. POP_CR(%cr29, %r26)
  109. POP_CR(%cr28, %r26)
  110. POP_CR(%cr27, %r26)
  111. POP_CR(%cr26, %r26)
  112. POP_CR(%cr25, %r26)
  113. POP_CR(%cr24, %r26)
  114. bv 0(%r2)
  115. nop
  116. /* rfi_virt2real() and rfi_real2virt() could perhaps be adapted for
  117.  * more general-purpose use by the several places which need RFIs
  118.  */
  119. .align 128
  120. .text
  121. rfi_virt2real:
  122. /* switch to real mode... */
  123. ssm 0,0 /* See "relied upon translation" */
  124. nop /* comment in interruption.S */
  125. nop
  126. nop
  127. nop
  128. nop
  129. nop
  130. nop
  131. nop
  132. mtsm 0 /* disable interruptions */
  133. mtctl 0, %cr17 /* space 0 */
  134. mtctl 0, %cr17
  135. load32 PA(rfi_v2r_1), %r1
  136. mtctl %r1, %cr18
  137. ldo 4(%r1), %r1
  138. mtctl %r1, %cr18
  139. load32 PDC_PSW, %r1
  140. mtctl %r1, %cr22
  141. rfi
  142. nop
  143. nop
  144. nop
  145. nop
  146. nop
  147. nop
  148. nop
  149. nop
  150. rfi_v2r_1:
  151. tophys %r2
  152. bv 0(%r2)
  153. nop
  154. .text
  155. .align 128
  156. rfi_real2virt:
  157. ssm 0,0 /* See "relied upon translation" */
  158. nop /* comment in interruption.S */
  159. nop
  160. nop
  161. nop
  162. nop
  163. nop
  164. nop
  165. nop
  166. mtsm 0 /* disable interruptions */
  167. mtctl 0, %cr17 /* space 0 */
  168. mtctl 0, %cr17
  169. load32 (rfi_r2v_1), %r1
  170. mtctl %r1, %cr18
  171. ldo 4(%r1), %r1
  172. mtctl %r1, %cr18
  173. load32 KERNEL_PSW, %r1
  174. mtctl %r1, %cr22
  175. rfi
  176. nop
  177. nop
  178. nop
  179. nop
  180. nop
  181. nop
  182. nop
  183. nop
  184. rfi_r2v_1:
  185. tovirt %r2
  186. bv 0(%r2)
  187. nop
  188. #ifdef __LP64__
  189. /************************ 64-bit real-mode calls ***********************/
  190. /* This is only usable in wide kernels right now and will probably stay so */
  191. .text
  192. .export real64_call_asm
  193. /* unsigned long real64_call_asm(unsigned long *sp,
  194.  * unsigned long *arg0p,
  195.  * unsigned long fn)
  196.  * sp is value of stack pointer to adopt before calling PDC (virt)
  197.  * arg0p points to where saved arg values may be found
  198.  * iodc_fn is the IODC function to call
  199.  */
  200. real64_call_asm:
  201. std %rp, -0x10(%sp) /* save RP */
  202. std %sp, -8(%arg0) /* save SP on real-mode stack */
  203. copy %arg0, %sp /* adopt the real-mode SP */
  204. /* save fn */
  205. copy %arg2, %r31
  206. /* set up the new ap */
  207. ldo 64(%arg1), %r29
  208. /* load up the arg registers from the saved arg area */
  209. /* 32-bit calling convention passes first 4 args in registers */
  210. ldd 0*REG_SZ(%arg1), %arg0 /* note overwriting arg0 */
  211. ldd 2*REG_SZ(%arg1), %arg2
  212. ldd 3*REG_SZ(%arg1), %arg3
  213. ldd 4*REG_SZ(%arg1), %r22
  214. ldd 5*REG_SZ(%arg1), %r21
  215. ldd 6*REG_SZ(%arg1), %r20
  216. ldd 7*REG_SZ(%arg1), %r19
  217. ldd 1*REG_SZ(%arg1), %arg1 /* do this one last! */
  218. tophys %sp
  219. b,l rfi_virt2real,%r2
  220. nop
  221. b,l save_control_regs,%r2 /* modifies r1, r2, r28 */
  222. nop
  223. load32 PA(r64_ret), %r2
  224. bv 0(%r31)
  225. nop
  226. r64_ret:
  227. /* restore CRs before going virtual in case we page fault */
  228. b,l restore_control_regs, %r2 /* modifies r1, r2, r26 */
  229. nop
  230. b,l rfi_real2virt,%r2
  231. nop
  232. tovirt %sp
  233. ldd -8(%sp), %sp /* restore SP */
  234. ldd -0x10(%sp), %rp /* restore RP */
  235. bv 0(%rp)
  236. nop
  237. #endif