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.

230 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. vdmnpx.c
  5. Abstract:
  6. This module contains the support for Vdm use of the npx.
  7. Author:
  8. Dave Hastings (daveh) 02-Feb-1992
  9. Revision History:
  10. 18-Dec-1992 sudeepb Tuned all the routines for performance
  11. --*/
  12. #include "vdmp.h"
  13. #include <ntos.h>
  14. #include <vdmntos.h>
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGE, VdmDispatchIRQ13)
  17. #pragma alloc_text(PAGE, VdmSkipNpxInstruction)
  18. #endif
  19. #ifdef ALLOC_DATA_PRAGMA
  20. #pragma const_seg("PAGECONST")
  21. #endif
  22. static const UCHAR MOD16[] = { 0, 1, 2, 0 };
  23. static const UCHAR MOD32[] = { 0, 1, 4, 0 };
  24. const UCHAR VdmUserCr0MapIn[] = {
  25. /* !EM !MP */ 0,
  26. /* !EM MP */ CR0_PE, // Don't set MP, but shadow users MP setting
  27. /* EM !MP */ CR0_EM,
  28. /* EM MP */ CR0_EM | CR0_MP
  29. };
  30. const UCHAR VdmUserCr0MapOut[] = {
  31. /* !EM !MP !PE */ 0,
  32. /* !EM !MP PE */ CR0_MP,
  33. /* !EM MP !PE */ CR0_MP, // setting not valid
  34. /* !EM MP PE */ CR0_MP, // setting not valid
  35. /* EM !MP !PE */ CR0_EM,
  36. /* EM !MP PE */ CR0_EM | CR0_MP, // setting not valid
  37. /* EM MP !PE */ CR0_EM | CR0_MP,
  38. /* EM MP PE */ CR0_EM | CR0_MP // setting not valid
  39. };
  40. BOOLEAN
  41. VdmDispatchIRQ13(
  42. PKTRAP_FRAME TrapFrame
  43. )
  44. /*++
  45. aRoutine Description:
  46. This routine reflects an IRQ 13 event to the usermode monitor for this
  47. vdm. The IRQ 13 must be reflected to usermode, so that it can properly
  48. be raised as an interrupt through the virtual PIC.
  49. Arguments:
  50. none
  51. Return Value:
  52. TRUE if the event was reflected
  53. FALSE if not
  54. --*/
  55. {
  56. EXCEPTION_RECORD ExceptionRecord;
  57. PVDM_TIB VdmTib;
  58. BOOLEAN Success;
  59. NTSTATUS Status;
  60. PAGED_CODE();
  61. Status = VdmpGetVdmTib(&VdmTib);
  62. if (!NT_SUCCESS(Status)) {
  63. return FALSE;
  64. }
  65. Success = TRUE;
  66. try {
  67. VdmTib->EventInfo.Event = VdmIrq13;
  68. VdmTib->EventInfo.InstructionSize = 0L;
  69. } except(EXCEPTION_EXECUTE_HANDLER) {
  70. ExceptionRecord.ExceptionCode = GetExceptionCode();
  71. ExceptionRecord.ExceptionFlags = 0;
  72. ExceptionRecord.NumberParameters = 0;
  73. ExRaiseException(&ExceptionRecord);
  74. Success = FALSE;
  75. }
  76. if (Success) { // insure that we do not redispatch an exception
  77. try {
  78. VdmEndExecution(TrapFrame,VdmTib);
  79. } except (EXCEPTION_EXECUTE_HANDLER) {
  80. NOTHING;
  81. }
  82. }
  83. return TRUE;
  84. }
  85. BOOLEAN
  86. VdmSkipNpxInstruction(
  87. PKTRAP_FRAME TrapFrame,
  88. ULONG Address32Bits,
  89. PUCHAR istream,
  90. ULONG InstructionSize
  91. )
  92. /*++
  93. Routine Description:
  94. This functions gains control when the system has no installed
  95. NPX support, but the thread has cleared its EM bit in CR0.
  96. The purpose of this function is to move the instruction
  97. pointer forward over the current NPX instruction.
  98. Enviroment:
  99. V86 MODE ONLY, first opcode byte already verified to be 0xD8 - 0xDF.
  100. Arguments:
  101. Return Value:
  102. TRUE if trap frame was modified to skip the NPX instruction
  103. --*/
  104. {
  105. UCHAR ibyte, Mod, rm;
  106. if (KeI386NpxPresent) {
  107. //
  108. // We should only get here if the thread is executing garbage so
  109. // just return and dispatch the error to the app.
  110. //
  111. return FALSE;
  112. }
  113. //
  114. // This NPX instruction should be skipped
  115. //
  116. //
  117. // Get ModR/M byte for NPX opcode
  118. //
  119. istream += 1;
  120. try {
  121. ibyte = *istream;
  122. } except (EXCEPTION_EXECUTE_HANDLER) {
  123. return FALSE;
  124. }
  125. InstructionSize += 1;
  126. if (ibyte <= 0xbf) {
  127. //
  128. // Within ModR/M range for addressing, process it.
  129. //
  130. Mod = ibyte >> 6;
  131. rm = ibyte & 0x7;
  132. if (Address32Bits) {
  133. InstructionSize += MOD32 [Mod];
  134. if (Mod == 0 && rm == 5) {
  135. // disp 32
  136. InstructionSize += 4;
  137. }
  138. //
  139. // If SIB byte, read it
  140. //
  141. if (rm == 4) {
  142. istream += 1;
  143. try {
  144. ibyte = *istream;
  145. } except (EXCEPTION_EXECUTE_HANDLER) {
  146. return FALSE;
  147. }
  148. InstructionSize += 1;
  149. if (Mod == 0 && (ibyte & 7) == 5) {
  150. // disp 32
  151. InstructionSize += 4;
  152. }
  153. }
  154. } else {
  155. InstructionSize += MOD16 [Mod];
  156. if (Mod == 0 && rm == 6) {
  157. // disp 16
  158. InstructionSize += 2;
  159. }
  160. }
  161. }
  162. //
  163. // Adjust Eip to skip NPX instruction
  164. //
  165. TrapFrame->Eip += InstructionSize;
  166. TrapFrame->Eip &= 0xffff;
  167. return TRUE;
  168. }