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

byteem.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1995 Digital Equipment Corporation 00004 00005 Module Name: 00006 00007 byteem.c 00008 00009 Abstract: 00010 00011 This module implements the code necessary to emulate the new set of Alpha 00012 byte and word instructions defined by ECO 81. 00013 00014 N.B. This file must be compiled without the use of byte/word instructions 00015 to avoid fatal recursive exceptions. 00016 00017 Author: 00018 00019 Wim Colgate (colgate) 18-May-1995 00020 Thomas Van Baak (tvb) 18-May-1995 00021 00022 Environment: 00023 00024 Kernel mode only. 00025 00026 Revision History: 00027 00028 --*/ 00029 00030 #include "ki.h" 00031 00032 // 00033 // Define function prototypes for emulation routines written in assembler. 00034 // 00035 00036 VOID 00037 KiInterlockedStoreByte ( 00038 IN PUCHAR Address, 00039 IN UCHAR Data 00040 ); 00041 00042 VOID 00043 KiInterlockedStoreWord ( 00044 IN PUSHORT Address, 00045 IN USHORT Data 00046 ); 00047 00048 BOOLEAN 00049 KiEmulateByteWord ( 00050 IN OUT PEXCEPTION_RECORD ExceptionRecord, 00051 IN OUT PKEXCEPTION_FRAME ExceptionFrame, 00052 IN OUT PKTRAP_FRAME TrapFrame 00053 ) 00054 00055 /*++ 00056 00057 Routine Description: 00058 00059 This routine emulates Alpha instructions defined by ECO 81. This includes 00060 the load byte unsigned, store byte, load word unsigned, store word, sign 00061 extend byte, and sign extend word instructions. 00062 00063 If a misaligned word access is detected the illegal instruction exception 00064 record is converted into data misalignment exception record, no emulation 00065 is performed, and a value of FALSE is returned. It is expected that the 00066 call to this function is followed by a check for a data misalignment 00067 exception and a call to the data misalignment emulation function if 00068 appropriate. 00069 00070 Arguments: 00071 00072 ExceptionRecord - Supplies a pointer to the exception record. 00073 00074 ExceptionFrame - Supplies a pointer to an exception frame. 00075 00076 TrapFrame - Supplies a pointer to a trap frame. 00077 00078 Return Value: 00079 00080 A value of TRUE is returned if the instruction is successfully emulated, 00081 otherwise a value of FALSE is returned. 00082 00083 --*/ 00084 00085 { 00086 ULONGLONG Data; 00087 ULONGLONG EffectiveAddress; 00088 PVOID ExceptionAddress; 00089 ALPHA_INSTRUCTION Instruction; 00090 KIRQL OldIrql; 00091 KPROCESSOR_MODE PreviousMode; 00092 00093 // 00094 // Save original exception address in case another exception occurs. 00095 // 00096 00097 ExceptionAddress = ExceptionRecord->ExceptionAddress; 00098 00099 // 00100 // Any exception that occurs during the attempted emulation will cause 00101 // the emulation to be aborted. The new exception code and information 00102 // will be copied to the original exception record and FALSE will be 00103 // returned. If the memory access was not from kernel mode then probe 00104 // the effective address before performing the emulation. 00105 // 00106 00107 // 00108 // Capture previous mode from trap frame not current thread. 00109 // 00110 00111 PreviousMode = (KPROCESSOR_MODE)(((PSR *)(&TrapFrame->Psr))->MODE); 00112 00113 try { 00114 00115 // 00116 // Get faulting instruction and case on instruction type. 00117 // 00118 00119 if (PreviousMode != KernelMode) { 00120 ProbeForRead(ExceptionAddress, 00121 sizeof(ALPHA_INSTRUCTION), 00122 sizeof(ALPHA_INSTRUCTION)); 00123 } 00124 Instruction = *((PALPHA_INSTRUCTION)ExceptionAddress); 00125 switch (Instruction.Memory.Opcode) { 00126 00127 // 00128 // Load/store operations. 00129 // 00130 00131 case LDBU_OP : 00132 case LDWU_OP : 00133 case STB_OP : 00134 case STW_OP : 00135 00136 00137 // 00138 // Compute effective address and if the address is non-canonical 00139 // then change the exception code to STATUS_ACCESS_VIOLATION and 00140 // return FALSE. 00141 // 00142 00143 EffectiveAddress = (ULONGLONG)Instruction.Memory.MemDisp + 00144 KiGetRegisterValue(Instruction.Memory.Rb, 00145 ExceptionFrame, 00146 TrapFrame); 00147 00148 if (EffectiveAddress != (ULONGLONG)(PVOID)EffectiveAddress) { 00149 ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION; 00150 ExceptionRecord->NumberParameters = 0; 00151 return FALSE; 00152 } 00153 00154 // 00155 // Case on individual load/store instruction type. 00156 // 00157 00158 switch (Instruction.Memory.Opcode) { 00159 00160 // 00161 // Load byte unsigned. 00162 // 00163 00164 case LDBU_OP : 00165 if (PreviousMode != KernelMode) { 00166 ProbeForRead(EffectiveAddress, 00167 sizeof(UCHAR), 00168 sizeof(UCHAR)); 00169 } 00170 Data = (ULONGLONG)*(PUCHAR)EffectiveAddress; 00171 KiSetRegisterValue(Instruction.Memory.Ra, 00172 Data, 00173 ExceptionFrame, 00174 TrapFrame); 00175 break; 00176 00177 // 00178 // Load word unsigned. 00179 // 00180 00181 case LDWU_OP : 00182 if (EffectiveAddress & 0x1) { 00183 goto AlignmentFault; 00184 } 00185 if (PreviousMode != KernelMode) { 00186 ProbeForRead((PUSHORT)EffectiveAddress, 00187 sizeof(USHORT), 00188 sizeof(UCHAR)); 00189 } 00190 Data = (ULONGLONG)*(PUSHORT)EffectiveAddress; 00191 KiSetRegisterValue(Instruction.Memory.Ra, 00192 Data, 00193 ExceptionFrame, 00194 TrapFrame); 00195 break; 00196 00197 // 00198 // Store byte. 00199 // 00200 00201 case STB_OP : 00202 if (PreviousMode != KernelMode) { 00203 ProbeForWrite((PUCHAR)EffectiveAddress, 00204 sizeof(UCHAR), 00205 sizeof(UCHAR)); 00206 } 00207 Data = KiGetRegisterValue(Instruction.Memory.Ra, 00208 ExceptionFrame, 00209 TrapFrame); 00210 KiInterlockedStoreByte((PUCHAR)EffectiveAddress, 00211 (UCHAR)Data); 00212 break; 00213 00214 // 00215 // Store word. 00216 // 00217 00218 case STW_OP : 00219 if (EffectiveAddress & 0x1) { 00220 goto AlignmentFault; 00221 } 00222 if (PreviousMode != KernelMode) { 00223 ProbeForWrite((PUSHORT)EffectiveAddress, 00224 sizeof(USHORT), 00225 sizeof(UCHAR)); 00226 } 00227 Data = KiGetRegisterValue(Instruction.Memory.Ra, 00228 ExceptionFrame, 00229 TrapFrame); 00230 KiInterlockedStoreWord((PUSHORT)EffectiveAddress, 00231 (USHORT)Data); 00232 break; 00233 } 00234 00235 break; 00236 00237 // 00238 // Sign extend operations. 00239 // 00240 00241 case SEXT_OP : 00242 switch (Instruction.OpReg.Function) { 00243 00244 // 00245 // Sign extend byte. 00246 // 00247 00248 case SEXTB_FUNC : 00249 Data = KiGetRegisterValue(Instruction.OpReg.Rb, 00250 ExceptionFrame, 00251 TrapFrame); 00252 KiSetRegisterValue(Instruction.OpReg.Rc, 00253 (ULONGLONG)(CHAR)Data, 00254 ExceptionFrame, 00255 TrapFrame); 00256 break; 00257 00258 // 00259 // Sign extend word. 00260 // 00261 00262 case SEXTW_FUNC : 00263 Data = KiGetRegisterValue(Instruction.OpReg.Rb, 00264 ExceptionFrame, 00265 TrapFrame); 00266 KiSetRegisterValue(Instruction.OpReg.Rc, 00267 (ULONGLONG)(SHORT)Data, 00268 ExceptionFrame, 00269 TrapFrame); 00270 break; 00271 00272 // 00273 // All other functions are not emulated. 00274 // 00275 00276 default : 00277 return FALSE; 00278 } 00279 00280 break; 00281 00282 // 00283 // All other instructions are not emulated. 00284 // 00285 00286 default : 00287 return FALSE; 00288 } 00289 00290 #if 0 00291 // 00292 // Call out to profile interrupt if byte/word emulation profiling is 00293 // active. 00294 // 00295 00296 if (KiProfileByteWordEmulation != FALSE) { 00297 if (++KiProfileByteWordEmulationCount >= 00298 KiProfileByteWordEmulationInterval) { 00299 00300 KeRaiseIrql(PROFILE_LEVEL, &OldIrql); 00301 KiProfileByteWordEmulationCount = 0; 00302 KeProfileInterruptWithSource(TrapFrame, 00303 ProfileByteWordEmulation); 00304 KeLowerIrql(OldIrql); 00305 } 00306 } 00307 #endif 00308 00309 TrapFrame->Fir += 4; 00310 00311 return TRUE; 00312 00313 } except (KiCopyInformation(ExceptionRecord, 00314 (GetExceptionInformation())->ExceptionRecord)) { 00315 00316 // 00317 // Preserve the original exception address. 00318 // 00319 00320 ExceptionRecord->ExceptionAddress = ExceptionAddress; 00321 00322 return FALSE; 00323 } 00324 00325 AlignmentFault : 00326 00327 // 00328 // A misaligned word access has been encountered. Change the illegal 00329 // instruction exception record into data misalignment exception record 00330 // (the format is defined by PALcode) and return FALSE. 00331 // 00332 00333 ExceptionRecord->ExceptionCode = STATUS_DATATYPE_MISALIGNMENT; 00334 ExceptionRecord->NumberParameters = 3; 00335 ExceptionRecord->ExceptionInformation[0] = Instruction.Memory.Opcode; 00336 ExceptionRecord->ExceptionInformation[1] = Instruction.Memory.Ra; 00337 ExceptionRecord->ExceptionInformation[2] = (ULONG)EffectiveAddress; 00338 00339 return FALSE; 00340 }

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