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

嵌入式Linux

开发平台:

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