Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

vdmnpx.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 vdmnpx.c 00008 00009 Abstract: 00010 00011 This module contains the support for Vdm use of the npx. 00012 00013 Author: 00014 00015 Dave Hastings (daveh) 02-Feb-1992 00016 00017 00018 Revision History: 00019 18-Dec-1992 sudeepb Tuned all the routines for performance 00020 00021 --*/ 00022 00023 #include <ntos.h> 00024 #include <vdmntos.h> 00025 #include "vdmp.h" 00026 00027 #ifdef ALLOC_PRAGMA 00028 #pragma alloc_text(PAGE, VdmDispatchIRQ13) 00029 #pragma alloc_text(PAGE, VdmSkipNpxInstruction) 00030 #endif 00031 00032 static UCHAR MOD16[] = { 0, 1, 2, 0 }; 00033 static UCHAR MOD32[] = { 0, 1, 4, 0 }; 00034 UCHAR VdmUserCr0MapIn[] = { 00035 /* !EM !MP */ 0, 00036 /* !EM MP */ CR0_PE, // Don't set MP, but shadow users MP setting 00037 /* EM !MP */ CR0_EM, 00038 /* EM MP */ CR0_EM | CR0_MP 00039 }; 00040 00041 UCHAR VdmUserCr0MapOut[] = { 00042 /* !EM !MP !PE */ 0, 00043 /* !EM !MP PE */ CR0_MP, 00044 /* !EM MP !PE */ CR0_MP, // setting not valid 00045 /* !EM MP PE */ CR0_MP, // setting not valid 00046 /* EM !MP !PE */ CR0_EM, 00047 /* EM !MP PE */ CR0_EM | CR0_MP, // setting not valid 00048 /* EM MP !PE */ CR0_EM | CR0_MP, 00049 /* EM MP PE */ CR0_EM | CR0_MP // setting not valid 00050 }; 00051 00052 00053 BOOLEAN 00054 VdmDispatchIRQ13( 00055 PKTRAP_FRAME TrapFrame 00056 ) 00057 /*++ 00058 00059 aRoutine Description: 00060 00061 This routine reflects an IRQ 13 event to the usermode monitor for this 00062 vdm. The IRQ 13 must be reflected to usermode, so that it can properly 00063 be raised as an interrupt through the virtual PIC. 00064 00065 Arguments: 00066 00067 none 00068 00069 Return Value: 00070 00071 TRUE if the event was reflected 00072 FALSE if not 00073 00074 --*/ 00075 { 00076 EXCEPTION_RECORD ExceptionRecord; 00077 PVDM_TIB VdmTib; 00078 BOOLEAN Success; 00079 NTSTATUS Status; 00080 00081 PAGED_CODE(); 00082 00083 Success = TRUE; 00084 00085 Status = VdmpGetVdmTib(&VdmTib, VDMTIB_KPROBE); 00086 if (!NT_SUCCESS(Status)) { 00087 return(FALSE); 00088 } 00089 00090 try { 00091 VdmTib->EventInfo.Event = VdmIrq13; 00092 VdmTib->EventInfo.InstructionSize = 0L; 00093 } except(EXCEPTION_EXECUTE_HANDLER) { 00094 ExceptionRecord.ExceptionCode = GetExceptionCode(); 00095 ExceptionRecord.ExceptionFlags = 0; 00096 ExceptionRecord.NumberParameters = 0; 00097 ExRaiseException(&ExceptionRecord); 00098 Success = FALSE; 00099 } 00100 00101 if (Success) { // insure that we do not redispatch an exception 00102 VdmEndExecution(TrapFrame,VdmTib); 00103 } 00104 00105 00106 return TRUE; 00107 } 00108 00109 BOOLEAN 00110 VdmSkipNpxInstruction( 00111 PKTRAP_FRAME TrapFrame, 00112 ULONG Address32Bits, 00113 PUCHAR istream, 00114 ULONG InstructionSize 00115 ) 00116 /*++ 00117 00118 Routine Description: 00119 00120 This functions gains control when the system has no installed 00121 NPX support, but the thread has cleared it's EM bit in CR0. 00122 00123 The purpose of this function is to move the instruction 00124 pointer forward over the current NPX instruction. 00125 00126 Enviroment: 00127 00128 V86 MODE ONLY, first opcode byte already verified to be 0xD8 - 0xDF. 00129 00130 Arguments: 00131 00132 Return Value: 00133 00134 TRUE if trap frame was modified to skip the NPX instruction 00135 00136 --*/ 00137 { 00138 UCHAR ibyte, Mod, rm; 00139 00140 ASSERT (!KeI386NpxPresent); 00141 00142 // 00143 // This NPX instruction should be skipped 00144 // 00145 00146 try { 00147 // 00148 // Get ModR/M byte for NPX opcode 00149 // 00150 00151 istream += 1; 00152 ibyte = *istream; 00153 InstructionSize += 1; 00154 00155 if (ibyte > 0xbf) { 00156 // 00157 // Outside of ModR/M range for addressing, all done 00158 // 00159 00160 goto try_exit; 00161 } 00162 00163 Mod = ibyte >> 6; 00164 rm = ibyte & 0x7; 00165 if (Address32Bits) { 00166 InstructionSize += MOD32 [Mod]; 00167 if (Mod == 0 && rm == 5) { 00168 // disp 32 00169 InstructionSize += 4; 00170 } 00171 00172 // 00173 // If SIB byte, read it 00174 // 00175 00176 if (rm == 4) { 00177 istream += 1; 00178 ibyte = *istream; 00179 InstructionSize += 1; 00180 00181 if (Mod == 0 && (ibyte & 7) == 5) { 00182 // disp 32 00183 InstructionSize += 4; 00184 } 00185 } 00186 00187 } else { 00188 InstructionSize += MOD16 [Mod]; 00189 if (Mod == 0 && rm == 6) { 00190 // disp 16 00191 InstructionSize += 2; 00192 } 00193 } 00194 00195 try_exit: ; 00196 } except (EXCEPTION_EXECUTE_HANDLER) { 00197 00198 // 00199 // Some sort of fault !? 00200 // 00201 00202 #if DBG 00203 DbgPrint ("P5_FPU_PATCH: V86: Fault occured\n"); 00204 #endif 00205 return FALSE; 00206 } 00207 00208 // 00209 // Adjust Eip to skip NPX instruction 00210 // 00211 00212 TrapFrame->Eip += InstructionSize; 00213 TrapFrame->Eip &= 0xffff; 00214 00215 return TRUE; 00216 }

Generated on Sat May 15 19:42:22 2004 for test by doxygen 1.3.7