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

alignem.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

ULONGLONG KiEmulateLoadLong (IN PULONG UnalignedAddress)
ULONGLONG KiEmulateLoadQuad (IN PUQUAD UnalignedAddress)
ULONGLONG KiEmulateLoadFloatIEEESingle (IN PULONG UnalignedAddress)
ULONGLONG KiEmulateLoadFloatIEEEDouble (IN PUQUAD UnalignedAddress)
VOID KiEmulateStoreLong (IN PULONG UnalignedAddress, IN ULONGLONG Data)
VOID KiEmulateStoreQuad (IN PUQUAD UnalignedAddress, IN ULONGLONG Data)
VOID KiEmulateStoreFloatIEEESingle (IN PULONG UnalignedAddress, IN ULONGLONG Data)
VOID KiEmulateStoreFloatIEEEDouble (IN PUQUAD UnalignedAddress, IN ULONGLONG Data)
VOID KiEnablePALAlignmentFixups (VOID)
VOID KiDisablePALAlignmentFixups (VOID)
VOID KiProfileInterrupt (IN KPROFILE_SOURCE ProfileSource, IN PKTRAP_FRAME TrapFrame)
VOID KiEnableAlignmentExceptions (VOID)
VOID KiDisableAlignmentExceptions (VOID)
BOOLEAN KiEmulateReference (IN OUT PEXCEPTION_RECORD ExceptionRecord, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame, IN BOOLEAN QuadwordOnly)


Function Documentation

VOID KiDisableAlignmentExceptions VOID   ) 
 

Definition at line 125 of file alpha/alignem.c.

References KeProcessorLevel, KiEnableAlignmentFaultExceptions, and KiEnablePALAlignmentFixups().

00130 : 00131 00132 Disables alignment exceptions on the current processor by 00133 enabling automatic PAL code alignment fixups. PAL is 00134 called to turn on automatic fixups only if CPU is 00135 21164 or greater and KiEnableAlignmentFaultExceptions==0 00136 00137 If KiEnableAlignmentFaultExceptions is either 1 or 2, then 00138 the kernel always needs to see alignment faults, so PAL 00139 automatic alignment fixups should not be enabled 00140 00141 Arguments: 00142 00143 None 00144 00145 Return Value: 00146 00147 None 00148 00149 --*/ 00150 00151 { 00152 if ((KeProcessorLevel >= PROCESSOR_ALPHA_21164) && 00153 (KiEnableAlignmentFaultExceptions == 0)) { 00154 KiEnablePALAlignmentFixups(); 00155 } 00156 }

VOID KiDisablePALAlignmentFixups VOID   ) 
 

Referenced by KiEnableAlignmentExceptions().

ULONGLONG KiEmulateLoadFloatIEEEDouble IN PUQUAD  UnalignedAddress  ) 
 

Referenced by KiEmulateReference().

ULONGLONG KiEmulateLoadFloatIEEESingle IN PULONG  UnalignedAddress  ) 
 

Referenced by KiEmulateReference().

ULONGLONG KiEmulateLoadLong IN PULONG  UnalignedAddress  ) 
 

Referenced by KiEmulateReference().

ULONGLONG KiEmulateLoadQuad IN PUQUAD  UnalignedAddress  ) 
 

Referenced by KiEmulateReference().

BOOLEAN KiEmulateReference IN OUT PEXCEPTION_RECORD  ExceptionRecord,
IN OUT PKEXCEPTION_FRAME  ExceptionFrame,
IN OUT PKTRAP_FRAME  TrapFrame,
IN BOOLEAN  QuadwordOnly
 

Definition at line 160 of file alpha/alignem.c.

References FALSE, KeLowerIrql(), KeRaiseIrql(), KernelMode, KiCopyInformation(), KiEmulateLoadFloatIEEEDouble(), KiEmulateLoadFloatIEEESingle(), KiEmulateLoadLong(), KiEmulateLoadQuad(), KiEmulateStoreFloatIEEEDouble(), KiEmulateStoreFloatIEEESingle(), KiEmulateStoreLong(), KiEmulateStoreQuad(), KiGetRegisterValue(), KiProfileAlignmentFixup, KiProfileAlignmentFixupCount, KiProfileAlignmentFixupInterval, KiProfileInterrupt(), KiSetRegisterValue(), KPROCESSOR_MODE, LDS_OP, ProbeForRead, ProbeForWrite(), PROFILE_LEVEL, PSR, SHORT, TRUE, and USHORT.

00169 : 00170 00171 Routine emulates an unaligned data reference from user part 00172 of the address space. 00173 00174 Arguments: 00175 00176 ExceptionRecord - Supplies a pointer to the exception record. 00177 00178 ExceptionFrame - Supplies a pointer to an exception frame. 00179 00180 TrapFrame - Supplies a pointer to a trap frame 00181 00182 QuadwordOnly - Supplies a boolean which controls whether both longword 00183 and quadword references are to be emulated or quadword references 00184 only. 00185 00186 Return Value: 00187 00188 True is returned if reference is successfully emulated, 00189 otherwise False is returned. 00190 00191 --*/ 00192 00193 { 00194 00195 ULONGLONG Data; 00196 PVOID EffectiveAddress; 00197 PVOID ExceptionAddress; 00198 ULONG Fa; 00199 ULONG Opcode; 00200 KPROCESSOR_MODE PreviousMode; 00201 ULONG Ra; 00202 KIRQL OldIrql; 00203 00204 // 00205 // Call out to profile interrupt if alignment profiling is active 00206 // 00207 if (KiProfileAlignmentFixup) { 00208 00209 if (++KiProfileAlignmentFixupCount >= KiProfileAlignmentFixupInterval) { 00210 00211 KeRaiseIrql(PROFILE_LEVEL, &OldIrql); 00212 KiProfileAlignmentFixupCount = 0; 00213 KiProfileInterrupt(ProfileAlignmentFixup, TrapFrame); 00214 KeLowerIrql(OldIrql); 00215 00216 } 00217 } 00218 00219 // 00220 // Save original exception address in case another exception occurs 00221 // 00222 00223 ExceptionAddress = ExceptionRecord->ExceptionAddress; 00224 00225 // 00226 // The ExceptionInformation in the ExceptionRecord has already 00227 // recorded information we need to emulate the access. 00228 // 00229 // ExceptionInformation: 00230 // [0] = opcode 00231 // [1] = destination register 00232 // [2] = effective address of access 00233 00234 Opcode = (ULONG)ExceptionRecord->ExceptionInformation[0]; 00235 Ra = (ULONG)ExceptionRecord->ExceptionInformation[1]; 00236 Fa = Ra + 32; // convert to floating register name for floating opcodes 00237 EffectiveAddress = (PVOID)ExceptionRecord->ExceptionInformation[2]; 00238 00239 // 00240 // Capture previous mode from trap frame not current thread. 00241 // 00242 00243 PreviousMode = (KPROCESSOR_MODE)(((PSR *)(&TrapFrame->Psr))->MODE); 00244 00245 // 00246 // Any exception that occurs during the attempted emulation will cause 00247 // the emulation to be aborted. The new exception code and information 00248 // will be copied to the original exception record and FALSE will be 00249 // returned. If the unaligned access was not from kernel mode then 00250 // probe the effective address before performing the emulation. 00251 // 00252 00253 try { 00254 00255 switch (Opcode) { 00256 00257 // 00258 // load longword 00259 // 00260 00261 case LDL_OP: 00262 if (QuadwordOnly != FALSE) { 00263 return FALSE; 00264 } 00265 if( PreviousMode != KernelMode ){ 00266 ProbeForRead( EffectiveAddress, 00267 sizeof(LONG), 00268 sizeof(UCHAR) ); 00269 } 00270 Data = KiEmulateLoadLong( EffectiveAddress ); 00271 KiSetRegisterValue( Ra, 00272 Data, 00273 ExceptionFrame, 00274 TrapFrame ); 00275 00276 break; 00277 00278 // 00279 // load quadword 00280 // 00281 00282 case LDQ_OP: 00283 if( PreviousMode != KernelMode ){ 00284 ProbeForRead( EffectiveAddress, 00285 sizeof(LONGLONG), 00286 sizeof(UCHAR) ); 00287 } 00288 Data = KiEmulateLoadQuad( EffectiveAddress ); 00289 KiSetRegisterValue( Ra, 00290 Data, 00291 ExceptionFrame, 00292 TrapFrame ); 00293 00294 break; 00295 00296 // 00297 // load IEEE single float 00298 // 00299 00300 case LDS_OP: 00301 if (QuadwordOnly != FALSE) { 00302 return FALSE; 00303 } 00304 if( PreviousMode != KernelMode ){ 00305 ProbeForRead( EffectiveAddress, 00306 sizeof(float), 00307 sizeof(UCHAR) ); 00308 } 00309 Data = KiEmulateLoadFloatIEEESingle( EffectiveAddress ); 00310 KiSetRegisterValue( Fa, 00311 Data, 00312 ExceptionFrame, 00313 TrapFrame ); 00314 00315 break; 00316 00317 // 00318 // load IEEE double float 00319 // 00320 00321 case LDT_OP: 00322 if( PreviousMode != KernelMode ){ 00323 ProbeForRead( EffectiveAddress, 00324 sizeof(DOUBLE), 00325 sizeof(UCHAR) ); 00326 } 00327 Data = KiEmulateLoadFloatIEEEDouble( EffectiveAddress ); 00328 KiSetRegisterValue( Fa, 00329 Data, 00330 ExceptionFrame, 00331 TrapFrame ); 00332 00333 break; 00334 00335 // 00336 // Load word unsigned. 00337 // 00338 00339 case LDWU_OP : 00340 if (QuadwordOnly != FALSE) { 00341 return FALSE; 00342 } 00343 if (PreviousMode != KernelMode) { 00344 ProbeForRead(EffectiveAddress, 00345 sizeof(SHORT), 00346 sizeof(UCHAR)); 00347 } 00348 Data = (ULONGLONG)*(UNALIGNED USHORT *)EffectiveAddress; 00349 KiSetRegisterValue(Ra, 00350 Data, 00351 ExceptionFrame, 00352 TrapFrame); 00353 00354 break; 00355 00356 // 00357 // store longword 00358 // 00359 00360 case STL_OP: 00361 if (QuadwordOnly != FALSE) { 00362 return FALSE; 00363 } 00364 if( PreviousMode != KernelMode ){ 00365 ProbeForWrite( EffectiveAddress, 00366 sizeof(LONG), 00367 sizeof(UCHAR) ); 00368 } 00369 Data = KiGetRegisterValue( Ra, 00370 ExceptionFrame, 00371 TrapFrame ); 00372 KiEmulateStoreLong( EffectiveAddress, (ULONG)Data ); 00373 00374 break; 00375 00376 // 00377 // store quadword 00378 // 00379 00380 case STQ_OP: 00381 if( PreviousMode != KernelMode ){ 00382 ProbeForWrite( EffectiveAddress, 00383 sizeof(LONGLONG), 00384 sizeof(UCHAR) ); 00385 } 00386 Data = KiGetRegisterValue( Ra, 00387 ExceptionFrame, 00388 TrapFrame ); 00389 KiEmulateStoreQuad( EffectiveAddress, Data ); 00390 00391 break; 00392 00393 // 00394 // store IEEE float single 00395 // 00396 00397 case STS_OP: 00398 if (QuadwordOnly != FALSE) { 00399 return FALSE; 00400 } 00401 if( PreviousMode != KernelMode ){ 00402 ProbeForWrite( EffectiveAddress, 00403 sizeof(float), 00404 sizeof(UCHAR) ); 00405 } 00406 Data = KiGetRegisterValue( Fa, 00407 ExceptionFrame, 00408 TrapFrame ); 00409 KiEmulateStoreFloatIEEESingle( EffectiveAddress, Data ); 00410 00411 break; 00412 00413 // 00414 // store IEEE float double 00415 // 00416 00417 case STT_OP: 00418 if( PreviousMode != KernelMode ){ 00419 ProbeForWrite( EffectiveAddress, 00420 sizeof(DOUBLE), 00421 sizeof(UCHAR) ); 00422 } 00423 Data = KiGetRegisterValue( Fa, 00424 ExceptionFrame, 00425 TrapFrame ); 00426 KiEmulateStoreFloatIEEEDouble( EffectiveAddress, Data ); 00427 00428 break; 00429 00430 // 00431 // Store word. 00432 // 00433 00434 case STW_OP : 00435 if (QuadwordOnly != FALSE) { 00436 return FALSE; 00437 } 00438 if (PreviousMode != KernelMode) { 00439 ProbeForWrite(EffectiveAddress, 00440 sizeof(SHORT), 00441 sizeof(UCHAR)); 00442 } 00443 Data = KiGetRegisterValue(Ra, 00444 ExceptionFrame, 00445 TrapFrame); 00446 *(UNALIGNED USHORT *)EffectiveAddress = (USHORT)Data; 00447 00448 break; 00449 00450 // 00451 // all other instructions are not emulated 00452 // 00453 00454 default: 00455 return FALSE; 00456 } 00457 00458 TrapFrame->Fir += 4; 00459 return TRUE; 00460 00461 } except (KiCopyInformation(ExceptionRecord, 00462 (GetExceptionInformation())->ExceptionRecord)) { 00463 00464 // 00465 // Preserve the original exception address 00466 // 00467 00468 ExceptionRecord->ExceptionAddress = ExceptionAddress; 00469 00470 return FALSE; 00471 } 00472 } }

VOID KiEmulateStoreFloatIEEEDouble IN PUQUAD  UnalignedAddress,
IN ULONGLONG  Data
 

Referenced by KiEmulateReference().

VOID KiEmulateStoreFloatIEEESingle IN PULONG  UnalignedAddress,
IN ULONGLONG  Data
 

Referenced by KiEmulateReference().

VOID KiEmulateStoreLong IN PULONG  UnalignedAddress,
IN ULONGLONG  Data
 

Referenced by KiEmulateReference().

VOID KiEmulateStoreQuad IN PUQUAD  UnalignedAddress,
IN ULONGLONG  Data
 

Referenced by KiEmulateReference().

VOID KiEnableAlignmentExceptions VOID   ) 
 

Definition at line 95 of file alpha/alignem.c.

References KeProcessorLevel, and KiDisablePALAlignmentFixups().

00100 : 00101 00102 Enables alignment exceptions on the current processor by 00103 disabling automatic PAL code alignment fixups. PAL is 00104 called to turn off automatic fixups only if CPU is 00105 21164 or greater. 00106 00107 Arguments: 00108 00109 None 00110 00111 Return Value: 00112 00113 None 00114 00115 --*/ 00116 00117 { 00118 if (KeProcessorLevel >= PROCESSOR_ALPHA_21164) { 00119 KiDisablePALAlignmentFixups(); 00120 } 00121 }

VOID KiEnablePALAlignmentFixups VOID   ) 
 

Referenced by KiDisableAlignmentExceptions().

VOID KiProfileInterrupt IN KPROFILE_SOURCE  ProfileSource,
IN PKTRAP_FRAME  TrapFrame
 

Referenced by KiEmulateReference().


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