Leaked source code of windows server 2003
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.

453 lines
11 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. getsetrg.c
  5. Abstract:
  6. This module implement the code necessary to get and set register values.
  7. These routines are used during the emulation of unaligned data references
  8. and floating point exceptions.
  9. Author:
  10. David N. Cutler (davec) 17-Jun-1991
  11. Environment:
  12. Kernel mode only.
  13. Revision History:
  14. --*/
  15. #include "ki.h"
  16. #include "ntfpia64.h"
  17. ULONGLONG
  18. KiGetRegisterValue (
  19. IN ULONG Register,
  20. IN PKEXCEPTION_FRAME ExceptionFrame,
  21. IN PKTRAP_FRAME TrapFrame
  22. )
  23. /*++
  24. Routine Description:
  25. This function is called to get the value of a register from the specified
  26. exception or trap frame.
  27. Arguments:
  28. Register - Supplies the number of the register whose value is to be
  29. returned. Integer registers are specified as 0 - 31 and floating
  30. registers are specified as 32 - 63.
  31. ExceptionFrame - Supplies a pointer to an exception frame.
  32. TrapFrame - Supplies a pointer to a trap frame.
  33. Return Value:
  34. The value of the specified register is returned as the function value.
  35. --*/
  36. {
  37. //
  38. // Dispatch on the register number.
  39. //
  40. if (Register == 0) {
  41. return 0;
  42. } else if (Register <= 3) {
  43. Register -= 1;
  44. return ( *(&TrapFrame->IntGp + Register) );
  45. } else if (Register <= 7) {
  46. Register -= 4;
  47. return ( *(&ExceptionFrame->IntS0 + Register) );
  48. } else if (Register <= 31) {
  49. Register -= 8;
  50. return ( *(&TrapFrame->IntV0 + Register) );
  51. }
  52. //
  53. // Register is the stacked register
  54. //
  55. // (R32 - R127)
  56. //
  57. {
  58. PULONGLONG UserBStore, KernelBStore;
  59. ULONG SizeOfCurrentFrame;
  60. SizeOfCurrentFrame = (ULONG)(TrapFrame->StIFS & 0x7F);
  61. Register = Register - 32;
  62. if (TrapFrame->PreviousMode == UserMode) {
  63. //
  64. // PreviousMode is user
  65. //
  66. UserBStore = (PULONGLONG) TrapFrame->RsBSP;
  67. do {
  68. UserBStore = UserBStore - 1;
  69. SizeOfCurrentFrame = SizeOfCurrentFrame - 1;
  70. if (((ULONG_PTR) UserBStore & 0x1F8) == 0x1F8) {
  71. //
  72. // Adjust Bsp, by skipping RNAT
  73. //
  74. UserBStore = UserBStore - 1;
  75. }
  76. } while (Register < SizeOfCurrentFrame);
  77. ProbeForRead(UserBStore, sizeof(ULONGLONG), sizeof(ULONGLONG));
  78. return (*UserBStore);
  79. } else {
  80. //
  81. // PreviousMode is kernel
  82. //
  83. KernelBStore = (ULONGLONG *) TrapFrame->RsBSP;
  84. do {
  85. KernelBStore = KernelBStore - 1;
  86. SizeOfCurrentFrame = SizeOfCurrentFrame - 1;
  87. if (((ULONG_PTR) KernelBStore & 0x1F8) == 0x1F8) {
  88. //
  89. // Adjust UserBsp, by skipping RNAT
  90. //
  91. KernelBStore = KernelBStore -1;
  92. }
  93. } while (Register < SizeOfCurrentFrame);
  94. return (*KernelBStore);
  95. }
  96. }
  97. }
  98. #define GET_NAT_OFFSET(addr) (USHORT)(((ULONG_PTR) (addr) >> 3) & 0x3F)
  99. #define CLEAR_NAT_BIT(Nats, Offset) Nats &= ~((ULONGLONG)1i64 << Offset)
  100. #define GET_NAT(Nats, addr) (UCHAR)((Nats >> GET_NAT_OFFSET(addr)) & 1)
  101. VOID
  102. KiSetRegisterValue (
  103. IN ULONG Register,
  104. IN ULONGLONG Value,
  105. OUT PKEXCEPTION_FRAME ExceptionFrame,
  106. OUT PKTRAP_FRAME TrapFrame
  107. )
  108. /*++
  109. Routine Description:
  110. This function is called to set the value of a register in the specified
  111. exception or trap frame.
  112. Arguments:
  113. Register - Supplies the number of the register whose value is to be
  114. stored. Integer registers are specified as 0 - 31 and floating
  115. registers are specified as 32 - 63.
  116. Value - Supplies the value to be stored in the specified register.
  117. ExceptionFrame - Supplies a pointer to an exception frame.
  118. TrapFrame - Supplies a pointer to a trap frame.
  119. Return Value:
  120. None.
  121. --*/
  122. {
  123. USHORT NatBitOffset;
  124. PULONGLONG UserBStore, KernelBStore, RnatAddress;
  125. ULONG SizeOfCurrentFrame;
  126. //
  127. // Dispatch on the register number.
  128. //
  129. if (Register == 0) {
  130. return;
  131. } else if (Register < 32) {
  132. if ((Register <= 3) || (Register >= 8)) {
  133. Register -= 1;
  134. *(&TrapFrame->IntGp + Register) = Value;
  135. NatBitOffset = GET_NAT_OFFSET(&TrapFrame->IntGp + Register);
  136. CLEAR_NAT_BIT(TrapFrame->IntNats, NatBitOffset);
  137. } else if ((Register >= 4) && (Register <= 7)) {
  138. Register -= 4;
  139. *(&ExceptionFrame->IntS0 + Register) = Value;
  140. NatBitOffset = GET_NAT_OFFSET(&ExceptionFrame->IntS0 + Register);
  141. CLEAR_NAT_BIT(ExceptionFrame->IntNats, NatBitOffset);
  142. }
  143. return;
  144. }
  145. //
  146. // Register is the stacked register
  147. //
  148. // (R32 - R127)
  149. //
  150. RnatAddress = NULL;
  151. SizeOfCurrentFrame = (ULONG)(TrapFrame->StIFS & 0x7F);
  152. Register = Register - 32;
  153. if (TrapFrame->PreviousMode == UserMode) {
  154. //
  155. // PreviousMode is user
  156. //
  157. UserBStore = (PULONGLONG) TrapFrame->RsBSP;
  158. do {
  159. UserBStore = UserBStore - 1;
  160. SizeOfCurrentFrame = SizeOfCurrentFrame - 1;
  161. if (((ULONG_PTR) UserBStore & 0x1F8) == 0x1F8) {
  162. //
  163. // Adjust Bsp, by skipping RNAT
  164. //
  165. RnatAddress = UserBStore;
  166. UserBStore = UserBStore - 1;
  167. }
  168. } while (Register < SizeOfCurrentFrame);
  169. ProbeForWrite(UserBStore, sizeof(ULONGLONG), sizeof(ULONGLONG));
  170. *UserBStore = Value;
  171. NatBitOffset = GET_NAT_OFFSET(UserBStore);
  172. if (RnatAddress == NULL) {
  173. CLEAR_NAT_BIT(TrapFrame->RsRNAT, NatBitOffset);
  174. } else {
  175. ProbeForWrite(RnatAddress, sizeof(ULONGLONG), sizeof(ULONGLONG));
  176. CLEAR_NAT_BIT(*RnatAddress, NatBitOffset);
  177. }
  178. } else {
  179. //
  180. // PreviousMode is kernel
  181. //
  182. ULONGLONG OriginalRsc, BspStore, Rnat;
  183. //
  184. // put RSE in lazy mode
  185. //
  186. OriginalRsc = __getReg(CV_IA64_RsRSC);
  187. __setReg(CV_IA64_RsRSC, RSC_KERNEL_DISABLED);
  188. KernelBStore = (ULONGLONG *) TrapFrame->RsBSP;
  189. do {
  190. KernelBStore = KernelBStore - 1;
  191. SizeOfCurrentFrame = SizeOfCurrentFrame - 1;
  192. if (((ULONG_PTR) KernelBStore & 0x1F8) == 0x1F8) {
  193. //
  194. // Adjust UserBsp, by skipping RNAT
  195. //
  196. KernelBStore = KernelBStore -1;
  197. }
  198. } while (Register < SizeOfCurrentFrame);
  199. *KernelBStore = Value;
  200. NatBitOffset = GET_NAT_OFFSET(KernelBStore);
  201. RnatAddress = (PULONGLONG)((ULONGLONG)KernelBStore | RNAT_ALIGNMENT);
  202. //
  203. // disable interrupt and read bspstore & rnat
  204. //
  205. _disable();
  206. BspStore = __getReg(CV_IA64_RsBSPSTORE);
  207. Rnat = __getReg(CV_IA64_RsRNAT);
  208. if ((ULONGLONG)RnatAddress == ((ULONGLONG)BspStore | RNAT_ALIGNMENT)) {
  209. CLEAR_NAT_BIT(Rnat, NatBitOffset);
  210. __setReg(CV_IA64_RsRNAT, Rnat);
  211. } else {
  212. CLEAR_NAT_BIT(*RnatAddress, NatBitOffset);
  213. }
  214. //
  215. // enable interrupt and restore RSC setting
  216. //
  217. _enable();
  218. __setReg(CV_IA64_RsRSC, OriginalRsc);
  219. }
  220. }
  221. FLOAT128
  222. KiGetFloatRegisterValue (
  223. IN ULONG Register,
  224. IN struct _KEXCEPTION_FRAME *ExceptionFrame,
  225. IN struct _KTRAP_FRAME *TrapFrame
  226. )
  227. {
  228. if (Register == 0) {
  229. FLOAT128 t = {0ULL,0ULL};
  230. return t;
  231. } else if (Register == 1) {
  232. FLOAT128 t = {0x8000000000000000ULL,0x000000000000FFFFULL}; // low,high
  233. return t;
  234. } else if (Register <= 5) {
  235. Register -= 2;
  236. return ( *(&ExceptionFrame->FltS0 + Register) );
  237. } else if (Register <= 15) {
  238. Register -= 6;
  239. return ( *(&TrapFrame->FltT0 + Register) );
  240. } else if (Register <= 31) {
  241. Register -= 16;
  242. return ( *(&ExceptionFrame->FltS4 + Register) );
  243. } else {
  244. PKHIGHER_FP_VOLATILE HigherVolatile;
  245. HigherVolatile = GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(KeGetCurrentThread()->StackBase);
  246. Register -= 32;
  247. return ( *(&HigherVolatile->FltF32 + Register) );
  248. }
  249. }
  250. VOID
  251. KiSetFloatRegisterValue (
  252. IN ULONG Register,
  253. IN FLOAT128 Value,
  254. OUT struct _KEXCEPTION_FRAME *ExceptionFrame,
  255. OUT struct _KTRAP_FRAME *TrapFrame
  256. )
  257. {
  258. if (Register <= 1) {
  259. return;
  260. } else if (Register <= 5) {
  261. Register -= 2;
  262. *(&ExceptionFrame->FltS0 + Register) = Value;
  263. return;
  264. } else if (Register <= 15) {
  265. Register -= 6;
  266. *(&TrapFrame->FltT0 + Register) = Value;
  267. return;
  268. } else if (Register <= 31) {
  269. Register -= 16;
  270. *(&ExceptionFrame->FltS4 + Register) = Value;
  271. return;
  272. } else {
  273. PKHIGHER_FP_VOLATILE HigherVolatile;
  274. HigherVolatile = GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(KeGetCurrentThread()->StackBase);
  275. Register -= 32;
  276. *(&HigherVolatile->FltF32 + Register) = Value;
  277. TrapFrame->StIPSR &= ~(1i64 << PSR_MFH);
  278. TrapFrame->StIPSR |= (1i64 << PSR_DFH);
  279. return;
  280. }
  281. }
  282. VOID
  283. __cdecl
  284. KeSaveStateForHibernate(
  285. IN PKPROCESSOR_STATE ProcessorState
  286. )
  287. /*++
  288. Routine Description:
  289. Saves all processor-specific state that must be preserved
  290. across an S4 state (hibernation).
  291. Arguments:
  292. ProcessorState - Supplies the KPROCESSOR_STATE where the
  293. current CPU's state is to be saved.
  294. Return Value:
  295. None.
  296. --*/
  297. {
  298. //
  299. // BUGBUG John Vert (jvert) 4/30/1998
  300. // someone needs to implement this and probably put it in a more
  301. // appropriate file.
  302. UNREFERENCED_PARAMETER (ProcessorState);
  303. }
  304. FLOAT128
  305. get_fp_register (
  306. IN ULONG Register,
  307. IN PVOID FpState
  308. )
  309. {
  310. return(KiGetFloatRegisterValue (
  311. Register,
  312. ((PFLOATING_POINT_STATE)FpState)->ExceptionFrame,
  313. ((PFLOATING_POINT_STATE)FpState)->TrapFrame
  314. ));
  315. }
  316. VOID
  317. set_fp_register (
  318. IN ULONG Register,
  319. IN FLOAT128 Value,
  320. IN PVOID FpState
  321. )
  322. {
  323. KiSetFloatRegisterValue (
  324. Register,
  325. Value,
  326. ((PFLOATING_POINT_STATE)FpState)->ExceptionFrame,
  327. ((PFLOATING_POINT_STATE)FpState)->TrapFrame
  328. );
  329. }