Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

380 lines
9.2 KiB

  1. //++
  2. //
  3. // Module name:
  4. //
  5. // i64fwasm.s
  6. //
  7. // Author:
  8. //
  9. // Arad Rostampour ([email protected]) Mar-21-99
  10. //
  11. // Description:
  12. //
  13. // Assembly routines for calling into SAL, PAL, and setting up translation registers
  14. //
  15. //--
  16. #include "ksia64.h"
  17. .sdata
  18. //
  19. // HalpSalSpinLock:
  20. //
  21. // HAL private spinlock protecting generic SAL calls.
  22. //
  23. .align 128
  24. HalpSalSpinLock::
  25. data8 0
  26. //
  27. // HalpSalStateInfoSpinLock:
  28. //
  29. // HAL private spinlock protecting specific SAL STATE_INFO calls.
  30. //
  31. .align 128
  32. HalpSalStateInfoSpinLock::
  33. data8 0
  34. //
  35. // HalpMcaSpinLock
  36. //
  37. // HAL private spinlock protecting HAL internal MCA data structures and operations.
  38. // Including operations at IRQL DISPATCH_LEVEL and higher.
  39. //
  40. .align 128
  41. HalpMcaSpinLock::
  42. data8 0
  43. //
  44. // HalpInitSpinLock
  45. //
  46. // HAL private spinlock protecting HAL internal INIT data structures and operations.
  47. // Including operations at IRQL DISPATCH_LEVEL and higher.
  48. //
  49. .align 128
  50. HalpInitSpinLock::
  51. data8 0
  52. //
  53. // HalpCmcSpinLock
  54. //
  55. // HAL private spinlock protecting HAL internal CMC data structures and operations.
  56. // Including operations at IRQL DISPATCH_LEVEL and higher.
  57. //
  58. .align 128
  59. HalpCmcSpinLock::
  60. data8 0
  61. //
  62. // HalpCpeSpinLock
  63. //
  64. // HAL private spinlock protecting HAL internal CPE data structures and operations.
  65. // Including operations at IRQL DISPATCH_LEVEL and higher.
  66. //
  67. .align 128
  68. HalpCpeSpinLock::
  69. data8 0
  70. //
  71. // Definitions used in this file
  72. //
  73. // Bits to set for the Mode argument in the HalpSetupTranslationRegisters call
  74. #define SET_DTR_BIT 1
  75. #define SET_ITR_BIT 0
  76. // TR for PAL is:
  77. // ed=1, PPN=0 (to be ORed in), RWX privledge only for ring 0, dirty/accessed bit set,
  78. // cacheable memory, present bit set.
  79. #define HAL_SAL_PAL_TR_ATTRIB TR_VALUE(1,0,3,0,1,1,0,1)
  80. #define HAL_TR_ATTRIBUTE_PPN_MASK 0x0000FFFFFFFFF000
  81. .file "i64fwasm.s"
  82. // These globals are defined in i64fw.c
  83. .global HalpSalProcPointer
  84. .global HalpSalProcGlobalPointer
  85. .global HalpPalProcPointer
  86. //++
  87. //
  88. // VOID
  89. // HalpSalProc(
  90. // LONGLONG a0, /* SAL function ID */
  91. // LONGLONG a1, /* SAL argument */
  92. // LONGLONG a2, /* SAL argument */
  93. // LONGLONG a3, /* SAL argument */
  94. // LONGLONG a4, /* SAL argument */
  95. // LONGLONG a5, /* SAL argument */
  96. // LONGLONG a6, /* SAL argument */
  97. // LONGLONG a7 /* SAL argument */
  98. // );
  99. //
  100. // Routine Description:
  101. // This is a simple assembly wrapper that jumps directly to the SAL code. The ONLY
  102. // caller should be HalpSalCall. Other users must use the HalpSalCall API for
  103. // calling into the SAL.
  104. //
  105. // Return Values:
  106. // r8->r11 contain the 4 64-bit return values for SAL, r8 is the status
  107. //--
  108. NESTED_ENTRY(HalpSalProc)
  109. NESTED_SETUP(8,3,8,0)
  110. // copy args to outs
  111. mov out0 = a0
  112. mov out1 = a1
  113. mov out2 = a2
  114. mov out3 = a3
  115. mov out4 = a4
  116. mov out5 = a5
  117. mov out6 = a6
  118. mov out7 = a7
  119. ;;
  120. // Simply load the address and branch to it
  121. addl t1 = @gprel(HalpSalProcPointer), gp
  122. addl t2 = @gprel(HalpSalProcGlobalPointer), gp
  123. ;;
  124. mov loc2 = gp
  125. ld8 t0 = [t1]
  126. ;;
  127. ld8 gp = [t2]
  128. mov bt0 = t0
  129. rsm 1 << PSR_I // disable interrupts
  130. ;;
  131. // br.sptk.many bt0
  132. br.call.sptk brp = bt0
  133. ;;
  134. mov gp = loc2
  135. ssm 1 << PSR_I // enable interrupts
  136. ;;
  137. NESTED_RETURN
  138. NESTED_EXIT(HalpSalProc)
  139. //++
  140. //
  141. // VOID
  142. // HalpPalProc(
  143. // LONGLONG a0, /* PAL function ID */
  144. // LONGLONG a1, /* PAL argument */
  145. // LONGLONG a2, /* PAL argument */
  146. // LONGLONG a3 /* PAL argument */
  147. // );
  148. //
  149. // Routine Description
  150. // This routine sets up the correct registers for input into PAL depending on
  151. // if the call uses static or stacked registers, turns off interrupts, ensures
  152. // the correct bank registers are being used and calls into the PAL. The ONLY
  153. // caller should be HalpPalCall. Other users must use the HalpPalCall API for
  154. // calling into the PAL.
  155. //
  156. // Return Values:
  157. // r8->r11 contain the 4 64-bit return values for PAL, r8 is the status
  158. //--
  159. NESTED_ENTRY(HalpPalProc)
  160. NESTED_SETUP(4,3,4,0)
  161. PROLOGUE_END
  162. // For both the static and stacked register conventions, load r28 with FunctionID
  163. mov r28 = a0
  164. // If static register calling convention (1-255, 512-767), copy arguments to r29->r31
  165. // Otherwise, copy to out0->out3 so they are in r32->r35 in PAL_PROC
  166. mov t0 = a0
  167. ;;
  168. shr t0 = t0, 8
  169. ;;
  170. tbit.z pt0, pt1 = t0, 0
  171. ;;
  172. //
  173. // Static proc: do br not call
  174. //
  175. (pt0) mov r29 = a1
  176. (pt0) mov r30 = a2
  177. (pt0) mov r31 = a3
  178. //
  179. // Stacked call
  180. //
  181. (pt1) mov out0 = a0
  182. (pt1) mov out1 = a1
  183. (pt1) mov out2 = a2
  184. (pt1) mov out3 = a3
  185. // Load up the address of PAL_PROC and call it
  186. addl t1 = @gprel(HalpPalProcPointer), gp
  187. ;;
  188. ld8 t0 = [t1]
  189. ;;
  190. mov bt0 = t0
  191. // Call into PAL_PROC
  192. (pt0) addl t1 = @ltoff(PalReturn), gp
  193. ;;
  194. (pt0) ld8 t0 = [t1]
  195. ;;
  196. (pt0) mov brp = t0
  197. ;;
  198. // Disable interrupts
  199. DISABLE_INTERRUPTS(loc2)
  200. ;;
  201. srlz.d
  202. ;;
  203. (pt0) br.sptk.many bt0
  204. ;;
  205. (pt1) br.call.sptk brp = bt0
  206. ;;
  207. PalReturn:
  208. // Restore the interrupt state
  209. RESTORE_INTERRUPTS(loc2)
  210. ;;
  211. NESTED_RETURN
  212. NESTED_EXIT(HalpPalProc)
  213. //++
  214. //
  215. // VOID
  216. // HalpPalProcPhysicalStatic(
  217. // LONGLONG a0, /* PAL function ID */
  218. // LONGLONG a1, /* PAL argument */
  219. // LONGLONG a2, /* PAL argument */
  220. // LONGLONG a3 /* PAL argument */
  221. // );
  222. //
  223. // Routine Description
  224. // This routine sets up the correct registers for input into PAL turns off interrupts,
  225. // ensures the correct bank registers are being used and calls into the PAL in PHYSICAL
  226. // mode since some of the calls require it. The ONLY caller should be HalpPalCall.
  227. // Other users must use the HalpPalCall API for calling into the PAL.
  228. //
  229. // Return Values:
  230. // r8->r11 contain the 4 64-bit return values for PAL, r8 is the status
  231. //--
  232. NESTED_ENTRY(HalpPalProcPhysicalStatic)
  233. NESTED_SETUP(4,3,4,0)
  234. PROLOGUE_END
  235. mov r28 = a0
  236. mov r29 = a1
  237. mov r30 = a2
  238. mov r31 = a3
  239. // Disable interrupts
  240. DISABLE_INTERRUPTS(loc2)
  241. ;;
  242. srlz.d
  243. ;;
  244. // For now, return unimplemented
  245. //
  246. // Need to switch into physical mode before calling into PAL, so could:
  247. //
  248. // a) Map everything through Region 4, simply turn off translation, and
  249. // be identity mapped in an uncacheable area (any issues?)
  250. //
  251. // b) Setup IIP and IPSR to jump to a physical address in physical mode
  252. // by doing an RFI.
  253. movl r8 = -1
  254. movl r9 = 0
  255. movl r10 = 0
  256. movl r11 = 0
  257. // Restore the interrupt state
  258. RESTORE_INTERRUPTS(loc2)
  259. ;;
  260. srlz.d
  261. ;;
  262. NESTED_RETURN
  263. NESTED_EXIT(HalpPalProcPhysicalStatic)
  264. //++
  265. //
  266. // VOID
  267. // HalpPalProcPhysicalStacked(
  268. // LONGLONG a0, /* PAL function ID */
  269. // LONGLONG a1, /* PAL argument */
  270. // LONGLONG a2, /* PAL argument */
  271. // LONGLONG a3 /* PAL argument */
  272. // );
  273. //
  274. // Routine Description
  275. // This routine calls PAL in physical mode for the stacked calling
  276. // convention. The ONLY caller should be HalpPalCall. Other users must
  277. // use the HalpPalCall API for calling into the PAL.
  278. //
  279. // Return Values:
  280. // r8->r11 contain the 4 64-bit return values for PAL, r8 is the status
  281. //--
  282. NESTED_ENTRY(HalpPalProcPhysicalStacked)
  283. NESTED_SETUP(4,3,4,0)
  284. PROLOGUE_END
  285. // Setup the input parameters for PAL (note r28 must specify the function ID as well)
  286. mov r28 = a0
  287. mov out0 = a0
  288. mov out1 = a1
  289. mov out2 = a2
  290. mov out3 = a3
  291. // Disable interrupts
  292. DISABLE_INTERRUPTS(loc2)
  293. ;;
  294. srlz.d
  295. ;;
  296. // For now, return unimplemented as we can not transition to physical
  297. // mode using RFI with the stacked convention. There are RSE issues
  298. // as well as needing psr.ic bit set to set IIP and other registers,
  299. // but memory arguments aren't mapped with a TR, so they could cause
  300. // a fault.
  301. movl r8 = -1
  302. movl r9 = 0
  303. movl r10 = 0
  304. movl r11 = 0
  305. // Restore the interrupt state
  306. RESTORE_INTERRUPTS(loc2)
  307. ;;
  308. srlz.d
  309. ;;
  310. NESTED_RETURN
  311. NESTED_EXIT(HalpPalProcPhysicalStacked)