mca_asm.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:9k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * File: mca_asm.h
  3.  *
  4.  * Copyright (C) 1999 Silicon Graphics, Inc.
  5.  * Copyright (C) Vijay Chander (vijay@engr.sgi.com)
  6.  * Copyright (C) Srinivasa Thirumalachar <sprasad@engr.sgi.com>
  7.  * Copyright (C) 2000 Hewlett-Packard Co.
  8.  * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
  9.  * Copyright (C) 2002 Intel Corp.
  10.  * Copyright (C) 2002 Jenna Hall <jenna.s.hall@intel.com>
  11.  */
  12. #ifndef _ASM_IA64_MCA_ASM_H
  13. #define _ASM_IA64_MCA_ASM_H
  14. #define PSR_IC 13
  15. #define PSR_I 14
  16. #define PSR_DT 17
  17. #define PSR_RT 27
  18. #define PSR_IT 36
  19. #define PSR_BN 44
  20. /*
  21.  * This macro converts a instruction virtual address to a physical address
  22.  * Right now for simulation purposes the virtual addresses are
  23.  * direct mapped to physical addresses.
  24.  * 1. Lop off bits 61 thru 63 in the virtual address
  25.  */
  26. #define INST_VA_TO_PA(addr)
  27. dep addr = 0, addr, 61, 3
  28. /*
  29.  * This macro converts a data virtual address to a physical address
  30.  * Right now for simulation purposes the virtual addresses are
  31.  * direct mapped to physical addresses.
  32.  * 1. Lop off bits 61 thru 63 in the virtual address
  33.  */
  34. #define DATA_VA_TO_PA(addr)
  35. dep addr = 0, addr, 61, 3
  36. /*
  37.  * This macro converts a data physical address to a virtual address
  38.  * Right now for simulation purposes the virtual addresses are
  39.  * direct mapped to physical addresses.
  40.  * 1. Put 0x7 in bits 61 thru 63.
  41.  */
  42. #define DATA_PA_TO_VA(addr,temp)
  43. mov temp = 0x7 ;;
  44. dep addr = temp, addr, 61, 3
  45. /*
  46.  * This macro jumps to the instruction at the given virtual address
  47.  * and starts execution in physical mode with all the address
  48.  * translations turned off.
  49.  * 1. Save the current psr
  50.  * 2. Make sure that all the upper 32 bits are off
  51.  *
  52.  * 3. Clear the interrupt enable and interrupt state collection bits
  53.  * in the psr before updating the ipsr and iip.
  54.  *
  55.  * 4. Turn off the instruction, data and rse translation bits of the psr
  56.  * and store the new value into ipsr
  57.  * Also make sure that the interrupts are disabled.
  58.  * Ensure that we are in little endian mode.
  59.  * [psr.{rt, it, dt, i, be} = 0]
  60.  *
  61.  * 5. Get the physical address corresponding to the virtual address
  62.  * of the next instruction bundle and put it in iip.
  63.  * (Using magic numbers 24 and 40 in the deposint instruction since
  64.  *  the IA64_SDK code directly maps to lower 24bits as physical address
  65.  *  from a virtual address).
  66.  *
  67.  * 6. Do an rfi to move the values from ipsr to psr and iip to ip.
  68.  */
  69. #define  PHYSICAL_MODE_ENTER(temp1, temp2, start_addr, old_psr)
  70. mov old_psr = psr;
  71. ;;
  72. dep old_psr = 0, old_psr, 32, 32;
  73. mov ar.rsc = 0 ;
  74. ;;
  75. srlz.d;
  76. mov temp2 = ar.bspstore;
  77. ;;
  78. DATA_VA_TO_PA(temp2);
  79. ;;
  80. mov temp1 = ar.rnat;
  81. ;;
  82. mov ar.bspstore = temp2;
  83. ;;
  84. mov ar.rnat = temp1;
  85. mov temp1 = psr;
  86. mov temp2 = psr;
  87. ;;
  88. dep temp2 = 0, temp2, PSR_IC, 2;
  89. ;;
  90. mov psr.l = temp2;
  91. ;;
  92. srlz.d;
  93. dep temp1 = 0, temp1, 32, 32;
  94. ;;
  95. dep temp1 = 0, temp1, PSR_IT, 1;
  96. ;;
  97. dep temp1 = 0, temp1, PSR_DT, 1;
  98. ;;
  99. dep temp1 = 0, temp1, PSR_RT, 1;
  100. ;;
  101. dep temp1 = 0, temp1, PSR_I, 1;
  102. ;;
  103. dep temp1 = 0, temp1, PSR_IC, 1;
  104. ;;
  105. movl temp2 = start_addr;
  106. mov cr.ipsr = temp1;
  107. ;;
  108. INST_VA_TO_PA(temp2);
  109. ;;
  110. mov cr.iip = temp2;
  111. mov cr.ifs = r0;
  112. DATA_VA_TO_PA(sp);
  113. DATA_VA_TO_PA(gp);
  114. ;;
  115. srlz.i;
  116. ;;
  117. nop 1;
  118. nop 2;
  119. nop 1;
  120. nop 2;
  121. rfi;
  122. ;;
  123. /*
  124.  * This macro jumps to the instruction at the given virtual address
  125.  * and starts execution in virtual mode with all the address
  126.  * translations turned on.
  127.  * 1. Get the old saved psr
  128.  *
  129.  * 2. Clear the interrupt state collection bit in the current psr.
  130.  *
  131.  * 3. Set the instruction translation bit back in the old psr
  132.  * Note we have to do this since we are right now saving only the
  133.  * lower 32-bits of old psr.(Also the old psr has the data and
  134.  * rse translation bits on)
  135.  *
  136.  * 4. Set ipsr to this old_psr with "it" bit set and "bn" = 1.
  137.  *
  138.  * 5. Reset the current thread pointer (r13).
  139.  *
  140.  * 6. Set iip to the virtual address of the next instruction bundle.
  141.  *
  142.  * 7. Do an rfi to move ipsr to psr and iip to ip.
  143.  */
  144. #define VIRTUAL_MODE_ENTER(temp1, temp2, start_addr, old_psr)
  145. mov temp2 = psr;
  146. ;;
  147. mov old_psr = temp2;
  148. ;;
  149. dep temp2 = 0, temp2, PSR_IC, 2;
  150. ;;
  151. mov psr.l = temp2;
  152. mov ar.rsc = 0;
  153. ;;
  154. srlz.d;
  155. mov r13 = ar.k6;
  156. ;;
  157. DATA_PA_TO_VA(r13,temp1);
  158. ;;
  159. mov temp2 = ar.bspstore;
  160. ;;
  161. DATA_PA_TO_VA(temp2,temp1);
  162. ;;
  163. mov temp1 = ar.rnat;
  164. ;;
  165. mov ar.bspstore = temp2;
  166. ;;
  167. mov ar.rnat = temp1;
  168. ;;
  169. mov temp1 = old_psr;
  170. ;;
  171. mov temp2 = 1;
  172. ;;
  173. dep temp1 = temp2, temp1, PSR_IC, 1;
  174. ;;
  175. dep temp1 = temp2, temp1, PSR_IT, 1;
  176. ;;
  177. dep temp1 = temp2, temp1, PSR_DT, 1;
  178. ;;
  179. dep temp1 = temp2, temp1, PSR_RT, 1;
  180. ;;
  181. dep temp1 = temp2, temp1, PSR_BN, 1;
  182. ;;
  183. mov     cr.ipsr = temp1;
  184. movl temp2 = start_addr;
  185. ;;
  186. mov cr.iip = temp2;
  187. ;;
  188. DATA_PA_TO_VA(sp, temp1);
  189. DATA_PA_TO_VA(gp, temp2);
  190. srlz.i;
  191. ;;
  192. nop 1;
  193. nop 2;
  194. nop 1;
  195. rfi
  196. ;;
  197. /*
  198.  * The following offsets capture the order in which the
  199.  * RSE related registers from the old context are
  200.  * saved onto the new stack frame.
  201.  *
  202.  * +-----------------------+
  203.  * |NDIRTY [BSP - BSPSTORE]|
  204.  * +-----------------------+
  205.  * | RNAT |
  206.  * +-----------------------+
  207.  * | BSPSTORE |
  208.  * +-----------------------+
  209.  * | IFS |
  210.  * +-----------------------+
  211.  * | PFS |
  212.  * +-----------------------+
  213.  * | RSC |
  214.  * +-----------------------+ <-------- Bottom of new stack frame
  215.  */
  216. #define  rse_rsc_offset 0
  217. #define  rse_pfs_offset (rse_rsc_offset+0x08)
  218. #define  rse_ifs_offset (rse_pfs_offset+0x08)
  219. #define  rse_bspstore_offset (rse_ifs_offset+0x08)
  220. #define  rse_rnat_offset (rse_bspstore_offset+0x08)
  221. #define  rse_ndirty_offset (rse_rnat_offset+0x08)
  222. /*
  223.  * rse_switch_context
  224.  *
  225.  * 1. Save old RSC onto the new stack frame
  226.  * 2. Save PFS onto new stack frame
  227.  * 3. Cover the old frame and start a new frame.
  228.  * 4. Save IFS onto new stack frame
  229.  * 5. Save the old BSPSTORE on the new stack frame
  230.  * 6. Save the old RNAT on the new stack frame
  231.  * 7. Write BSPSTORE with the new backing store pointer
  232.  * 8. Read and save the new BSP to calculate the #dirty registers
  233.  * NOTE: Look at pages 11-10, 11-11 in PRM Vol 2
  234.  */
  235. #define rse_switch_context(temp,p_stackframe,p_bspstore)
  236. ;;
  237. mov     temp=ar.rsc;;
  238. st8     [p_stackframe]=temp,8;;
  239. mov     temp=ar.pfs;;
  240. st8     [p_stackframe]=temp,8;
  241. cover ;;
  242. mov     temp=cr.ifs;;
  243. st8     [p_stackframe]=temp,8;;
  244. mov     temp=ar.bspstore;;
  245. st8     [p_stackframe]=temp,8;;
  246. mov     temp=ar.rnat;;
  247. st8     [p_stackframe]=temp,8;
  248. mov     ar.bspstore=p_bspstore;;
  249. mov     temp=ar.bsp;;
  250. sub     temp=temp,p_bspstore;;
  251. st8     [p_stackframe]=temp,8;;
  252. /*
  253.  * rse_return_context
  254.  * 1. Allocate a zero-sized frame
  255.  * 2. Store the number of dirty registers RSC.loadrs field
  256.  * 3. Issue a loadrs to insure that any registers from the interrupted
  257.  *    context which were saved on the new stack frame have been loaded
  258.  *    back into the stacked registers
  259.  * 4. Restore BSPSTORE
  260.  * 5. Restore RNAT
  261.  * 6. Restore PFS
  262.  * 7. Restore IFS
  263.  * 8. Restore RSC
  264.  * 9. Issue an RFI
  265.  */
  266. #define rse_return_context(psr_mask_reg,temp,p_stackframe)
  267. ;;
  268. alloc   temp=ar.pfs,0,0,0,0;
  269. add     p_stackframe=rse_ndirty_offset,p_stackframe;;
  270. ld8     temp=[p_stackframe];;
  271. shl     temp=temp,16;;
  272. mov     ar.rsc=temp;;
  273. loadrs;;
  274. add     p_stackframe=-rse_ndirty_offset+rse_bspstore_offset,p_stackframe;;
  275. ld8     temp=[p_stackframe];;
  276. mov     ar.bspstore=temp;;
  277. add     p_stackframe=-rse_bspstore_offset+rse_rnat_offset,p_stackframe;;
  278. ld8     temp=[p_stackframe];;
  279. mov     ar.rnat=temp;;
  280. add     p_stackframe=-rse_rnat_offset+rse_pfs_offset,p_stackframe;;
  281. ld8     temp=[p_stackframe];;
  282. mov     ar.pfs=temp;;
  283. add     p_stackframe=-rse_pfs_offset+rse_ifs_offset,p_stackframe;;
  284. ld8     temp=[p_stackframe];;
  285. mov     cr.ifs=temp;;
  286. add     p_stackframe=-rse_ifs_offset+rse_rsc_offset,p_stackframe;;
  287. ld8     temp=[p_stackframe];;
  288. mov     ar.rsc=temp ;
  289. mov     temp=psr;;
  290. or      temp=temp,psr_mask_reg;;
  291. mov     cr.ipsr=temp;;
  292. mov     temp=ip;;
  293. add     temp=0x30,temp;;
  294. mov     cr.iip=temp;;
  295. srlz.i;;
  296. rfi;;
  297. #endif /* _ASM_IA64_MCA_ASM_H */