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.

Classes

struct  _INST_FORMAT

Defines

#define OPCODE_MASK   0x1EF00000000
#define LD_OP   0x08000000000
#define LDS_OP   0x08100000000
#define LDA_OP   0x08200000000
#define LDSA_OP   0x08300000000
#define LDBIAS_OP   0x08400000000
#define LDACQ_OP   0x08500000000
#define LDCCLR_OP   0x08800000000
#define LDCNC_OP   0x08900000000
#define LDCCLRACQ_OP   0x08A00000000
#define ST_OP   0x08C00000000
#define STREL_OP   0x08D00000000
#define LD_IMM_OP   0x0A000000000
#define LDS_IMM_OP   0x0A100000000
#define LDA_IMM_OP   0x0A200000000
#define LDSA_IMM_OP   0x0A300000000
#define LDBIAS_IMM_OP   0x0A400000000
#define LDACQ_IMM_OP   0x0A500000000
#define LDCCLR_IMM_OP   0x0A800000000
#define LDCNC_IMM_OP   0x0A900000000
#define LDCCLRACQ_IMM_OP   0x0AA00000000
#define ST_IMM_OP   0x0AC00000000
#define STREL_IMM_OP   0x0AD00000000
#define LDF_OP   0x0C000000000
#define LDFS_OP   0x0C100000000
#define LDFA_OP   0x0C200000000
#define LDFSA_OP   0x0C300000000
#define LDFCCLR_OP   0x0C800000000
#define LDFCNC_OP   0x0C900000000
#define STF_OP   0x0CC00000000
#define LDF_IMM_OP   0x0E000000000
#define LDFS_IMM_OP   0x0E100000000
#define LDFA_IMM_OP   0x0E200000000
#define LDFSA_IMM_OP   0x0E300000000
#define LDFCCLR_IMM_OP   0x0E800000000
#define LDFCNC_IMM_OP   0x0E900000000
#define STF_IMM_OP   0x0EC00000000

Typedefs

typedef _INST_FORMAT INST_FORMAT

Functions

VOID KiEmulateLoad (IN PVOID UnalignedAddress, IN ULONG OperandSize, IN PVOID Data)
VOID KiEmulateStore (IN PVOID UnalignedAddress, IN ULONG OperandSize, IN PVOID Data)
VOID KiEmulateLoadFloat (IN PVOID UnalignedAddress, IN ULONG OperandSize, IN PVOID Data)
VOID KiEmulateStoreFloat (IN PVOID UnalignedAddress, IN ULONG OperandSize, IN PVOID Data)
VOID KiEmulateLoadFloat80 (IN PVOID UnalignedAddress, OUT PVOID FloatData)
VOID KiEmulateLoadFloatInt (IN PVOID UnalignedAddress, OUT PVOID FloatData)
VOID KiEmulateLoadFloat32 (IN PVOID UnalignedAddress, OUT PVOID FloatData)
VOID KiEmulateLoadFloat64 (IN PVOID UnalignedAddress, OUT PVOID FloatData)
VOID KiEmulateStoreFloat80 (IN PVOID UnalignedAddress, OUT PVOID FloatData)
VOID KiEmulateStoreFloatInt (IN PVOID UnalignedAddress, OUT PVOID FloatData)
VOID KiEmulateStoreFloat32 (IN PVOID UnalignedAddress, OUT PVOID FloatData)
VOID KiEmulateStoreFloat64 (IN PVOID UnalignedAddress, OUT PVOID FloatData)
BOOLEAN KiEmulateReference (IN OUT PEXCEPTION_RECORD ExceptionRecord, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame)
VOID KiEmulateLoadFloat (IN PVOID UnalignedAddress, IN ULONG OperandSize, IN OUT PVOID Data)


Define Documentation

#define LD_IMM_OP   0x0A000000000
 

Definition at line 42 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LD_OP   0x08000000000
 

Definition at line 30 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDA_IMM_OP   0x0A200000000
 

Definition at line 44 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDA_OP   0x08200000000
 

Definition at line 32 of file ia64/alignem.c.

Referenced by KiEmulateReference(), and RtlVirtualUnwind().

#define LDACQ_IMM_OP   0x0A500000000
 

Definition at line 47 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDACQ_OP   0x08500000000
 

Definition at line 35 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDBIAS_IMM_OP   0x0A400000000
 

Definition at line 46 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDBIAS_OP   0x08400000000
 

Definition at line 34 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDCCLR_IMM_OP   0x0A800000000
 

Definition at line 48 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDCCLR_OP   0x08800000000
 

Definition at line 36 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDCCLRACQ_IMM_OP   0x0AA00000000
 

Definition at line 50 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDCCLRACQ_OP   0x08A00000000
 

Definition at line 38 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDCNC_IMM_OP   0x0A900000000
 

Definition at line 49 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDCNC_OP   0x08900000000
 

Definition at line 37 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDF_IMM_OP   0x0E000000000
 

Definition at line 62 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDF_OP   0x0C000000000
 

Definition at line 54 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDFA_IMM_OP   0x0E200000000
 

Definition at line 64 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDFA_OP   0x0C200000000
 

Definition at line 56 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDFCCLR_IMM_OP   0x0E800000000
 

Definition at line 66 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDFCCLR_OP   0x0C800000000
 

Definition at line 58 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDFCNC_IMM_OP   0x0E900000000
 

Definition at line 67 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDFCNC_OP   0x0C900000000
 

Definition at line 59 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDFS_IMM_OP   0x0E100000000
 

Definition at line 63 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDFS_OP   0x0C100000000
 

Definition at line 55 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDFSA_IMM_OP   0x0E300000000
 

Definition at line 65 of file ia64/alignem.c.

#define LDFSA_OP   0x0C300000000
 

Definition at line 57 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDS_IMM_OP   0x0A100000000
 

Definition at line 43 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDS_OP   0x08100000000
 

Definition at line 31 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDSA_IMM_OP   0x0A300000000
 

Definition at line 45 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define LDSA_OP   0x08300000000
 

Definition at line 33 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define OPCODE_MASK   0x1EF00000000
 

Definition at line 28 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define ST_IMM_OP   0x0AC00000000
 

Definition at line 51 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define ST_OP   0x08C00000000
 

Definition at line 39 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define STF_IMM_OP   0x0EC00000000
 

Definition at line 68 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define STF_OP   0x0CC00000000
 

Definition at line 60 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define STREL_IMM_OP   0x0AD00000000
 

Definition at line 52 of file ia64/alignem.c.

Referenced by KiEmulateReference().

#define STREL_OP   0x08D00000000
 

Definition at line 40 of file ia64/alignem.c.

Referenced by KiEmulateReference().


Typedef Documentation

typedef struct _INST_FORMAT INST_FORMAT
 


Function Documentation

VOID KiEmulateLoad IN PVOID  UnalignedAddress,
IN ULONG  OperandSize,
IN PVOID  Data
 

Definition at line 915 of file ia64/alignem.c.

Referenced by KiEmulateReference().

00923 : 00924 00925 This routine returns the integer value stored at the unaligned 00926 address passed in UnalignedAddress. 00927 00928 Arguments: 00929 00930 UnalignedAddress - Supplies a pointer to data value. 00931 00932 OperandSize - Supplies the size of data to be loaded 00933 00934 Data - Supplies a pointer to be filled for data 00935 00936 Return Value: 00937 00938 The value at the address pointed to by UnalignedAddress. 00939 00940 --*/ 00941 00942 { 00943 PUCHAR Source; 00944 PUCHAR Destination; 00945 ULONG i; 00946 00947 Source = (PUCHAR) UnalignedAddress; 00948 Destination = (PUCHAR) Data; 00949 OperandSize = 1 << OperandSize; 00950 00951 for (i = 0; i < OperandSize; i++) { 00952 00953 *Destination++ = *Source++; 00954 00955 } 00956 00957 return; 00958 }

VOID KiEmulateLoadFloat IN PVOID  UnalignedAddress,
IN ULONG  OperandSize,
IN OUT PVOID  Data
 

Definition at line 1007 of file ia64/alignem.c.

References KiEmulateLoadFloat32(), KiEmulateLoadFloat64(), KiEmulateLoadFloat80(), and KiEmulateLoadFloatInt().

Referenced by KiEmulateReference().

01015 : 01016 01017 This routine returns the floating point value stored at the unaligned 01018 address passed in UnalignedAddress. 01019 01020 Arguments: 01021 01022 UnalignedAddress - Supplies a pointer to floating point data value. 01023 01024 OperandSize - Supplies the size of data to be loaded 01025 01026 Data - Supplies a pointer to be filled for data 01027 01028 Return Value: 01029 01030 The value at the address pointed to by UnalignedAddress. 01031 01032 --*/ 01033 01034 { 01035 FLOAT128 FloatData; 01036 01037 RtlMoveMemory(&FloatData, UnalignedAddress, sizeof(FLOAT128)); 01038 01039 switch (OperandSize) { 01040 01041 case 0: 01042 KiEmulateLoadFloat80(&FloatData, Data); 01043 return; 01044 01045 case 1: 01046 KiEmulateLoadFloatInt(&FloatData, Data); 01047 return; 01048 01049 case 2: 01050 KiEmulateLoadFloat32(&FloatData, Data); 01051 return; 01052 01053 case 3: 01054 KiEmulateLoadFloat64(&FloatData, Data); 01055 return; 01056 01057 default: 01058 return; 01059 } 01060 }

VOID KiEmulateLoadFloat IN PVOID  UnalignedAddress,
IN ULONG  OperandSize,
IN PVOID  Data
 

VOID KiEmulateLoadFloat32 IN PVOID  UnalignedAddress,
OUT PVOID  FloatData
 

Referenced by KiEmulateLoadFloat().

VOID KiEmulateLoadFloat64 IN PVOID  UnalignedAddress,
OUT PVOID  FloatData
 

Referenced by KiEmulateLoadFloat().

VOID KiEmulateLoadFloat80 IN PVOID  UnalignedAddress,
OUT PVOID  FloatData
 

Referenced by KiEmulateLoadFloat().

VOID KiEmulateLoadFloatInt IN PVOID  UnalignedAddress,
OUT PVOID  FloatData
 

Referenced by KiEmulateLoadFloat().

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

Definition at line 166 of file ia64/alignem.c.

References FALSE, KeLowerIrql(), KeProfileInterruptWithSource(), KeRaiseIrql(), KernelMode, KiAdvanceInstPointer(), KiCopyInformation(), KiEmulateLoad(), KiEmulateLoadFloat(), KiEmulateStore(), KiEmulateStoreFloat(), KiGetFloatRegisterValue(), KiGetRegisterValue(), KiProfileAlignmentFixup, KiProfileAlignmentFixupCount, KiProfileAlignmentFixupInterval, KiSetFloatRegisterValue(), KiSetRegisterValue(), KPROCESSOR_MODE, LD_IMM_OP, LD_OP, LDA_IMM_OP, LDA_OP, LDACQ_IMM_OP, LDACQ_OP, LDBIAS_IMM_OP, LDBIAS_OP, LDCCLR_IMM_OP, LDCCLR_OP, LDCCLRACQ_IMM_OP, LDCCLRACQ_OP, LDCNC_IMM_OP, LDCNC_OP, LDF_IMM_OP, LDF_OP, LDFA_IMM_OP, LDFA_OP, LDFCCLR_IMM_OP, LDFCCLR_OP, LDFCNC_IMM_OP, LDFCNC_OP, LDFS_IMM_OP, LDFS_OP, LDFSA_OP, LDS_IMM_OP, LDS_OP, LDSA_IMM_OP, LDSA_OP, OPCODE_MASK, ProbeForRead, ProbeForWrite(), PROFILE_LEVEL, ST_IMM_OP, ST_OP, STF_IMM_OP, STF_OP, STREL_IMM_OP, STREL_OP, TRUE, and _INST_FORMAT::u.

00174 : 00175 00176 This function is called to emulate an unaligned data reference to an 00177 address in the user part of the address space. 00178 00179 Arguments: 00180 00181 ExceptionRecord - Supplies a pointer to an exception record. 00182 00183 ExceptionFrame - Supplies a pointer to an exception frame. 00184 00185 TrapFrame - Supplies a pointer to a trap frame. 00186 00187 Return Value: 00188 00189 A value of TRUE is returned if the data reference is successfully 00190 emulated. Otherwise, a value of FALSE is returned. 00191 00192 --*/ 00193 00194 { 00195 00196 PVOID EffectiveAddress; 00197 PVOID ExceptionAddress; 00198 KIRQL OldIrql; 00199 00200 KPROCESSOR_MODE PreviousMode; 00201 INST_FORMAT FaultInstruction; 00202 ULONGLONG Opcode; 00203 ULONGLONG Reg2Value; 00204 ULONGLONG Reg3Value; 00205 ULONGLONG BundleLow; 00206 ULONGLONG BundleHigh; 00207 ULONGLONG Syllable; 00208 ULONGLONG Data = 0; 00209 FLOAT128 FloatData = {0, 0}; 00210 ULONG OpSize; 00211 ULONG ImmValue; 00212 ULONG Length; 00213 00214 00215 // 00216 // Must flush the RSE to synchronize the RSE and backing store contents 00217 // 00218 00219 KiFlushRse(); 00220 00221 // 00222 // Call out to profile interrupt if alignment profiling is active 00223 // 00224 00225 if (KiProfileAlignmentFixup) { 00226 00227 if (++KiProfileAlignmentFixupCount >= KiProfileAlignmentFixupInterval) { 00228 00229 KeRaiseIrql(PROFILE_LEVEL, &OldIrql); 00230 KiProfileAlignmentFixupCount = 0; 00231 KeProfileInterruptWithSource(TrapFrame, ProfileAlignmentFixup); 00232 KeLowerIrql(OldIrql); 00233 00234 } 00235 } 00236 00237 // 00238 // Save the original exception address in case another exception 00239 // occurs. 00240 // 00241 00242 EffectiveAddress = (PVOID) ExceptionRecord->ExceptionInformation[1]; 00243 ExceptionAddress = (PVOID) TrapFrame->StIIP; 00244 00245 // 00246 // Capture previous mode from trap frame not current thread. 00247 // 00248 00249 PreviousMode = (KPROCESSOR_MODE) TrapFrame->PreviousMode; 00250 00251 // 00252 // Any exception that occurs during the attempted emulation of the 00253 // unaligned reference causes the emulation to be aborted. The new 00254 // exception code and information is copied to the original exception 00255 // record and a value of FALSE is returned. 00256 // 00257 00258 try { 00259 00260 00261 BundleLow = *((ULONGLONG *)ExceptionAddress); 00262 BundleHigh = *(((ULONGLONG *)ExceptionAddress) + 1); 00263 00264 Syllable = (TrapFrame->StIPSR >> PSR_RI) & 0x3; 00265 00266 switch (Syllable) { 00267 case 0: 00268 FaultInstruction.u.Ulong64 = (BundleLow >> 5); 00269 break; 00270 case 1: 00271 FaultInstruction.u.Ulong64 = (BundleLow >> 46) | (BundleHigh << 18); 00272 break; 00273 case 2: 00274 FaultInstruction.u.Ulong64 = (BundleHigh >> 23); 00275 case 3: 00276 default: 00277 return FALSE; 00278 } 00279 00280 Opcode = FaultInstruction.u.Ulong64 & OPCODE_MASK; 00281 OpSize = (ULONG)FaultInstruction.u.i_field.x6 & 0x3; 00282 00283 switch (Opcode) { 00284 00285 // 00286 // speculative and speculative advanced load 00287 // 00288 00289 case LDS_OP: 00290 case LDSA_OP: 00291 case LDS_IMM_OP: 00292 case LDSA_IMM_OP: 00293 case LDFS_OP: 00294 case LDFSA_OP: 00295 case LDFS_IMM_OP: 00296 00297 // 00298 // return NaT value to the target register 00299 // 00300 00301 TrapFrame->StIPSR |= (1i64 << PSR_ED); 00302 00303 return TRUE; 00304 00305 // 00306 // normal, advance, and check load 00307 // 00308 00309 case LD_OP: 00310 case LDA_OP: 00311 case LDBIAS_OP: 00312 case LDCCLR_OP: 00313 case LDCNC_OP: 00314 case LDACQ_OP: 00315 case LDCCLRACQ_OP: 00316 00317 if (FaultInstruction.u.i_field.x == 1) { 00318 00319 // 00320 // xField must be 0 00321 // 00322 00323 return FALSE; 00324 } 00325 00326 if( PreviousMode != KernelMode ){ 00327 ProbeForRead( EffectiveAddress, 00328 1 << OpSize, 00329 sizeof(UCHAR) ); 00330 } 00331 KiEmulateLoad(EffectiveAddress, OpSize, &Data); 00332 KiSetRegisterValue( (ULONG) FaultInstruction.u.i_field.r1, 00333 Data, 00334 ExceptionFrame, 00335 TrapFrame ); 00336 00337 if (FaultInstruction.u.i_field.m == 1) { 00338 00339 // 00340 // Update the address register (R3) 00341 // 00342 00343 00344 Reg2Value = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r2, 00345 ExceptionFrame, 00346 TrapFrame ); 00347 00348 Reg3Value = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00349 ExceptionFrame, 00350 TrapFrame ); 00351 00352 // 00353 // register update form 00354 // 00355 00356 Reg3Value = Reg2Value + Reg3Value; 00357 00358 KiSetRegisterValue ((ULONG) FaultInstruction.u.i_field.r3, 00359 Reg3Value, 00360 ExceptionFrame, 00361 TrapFrame); 00362 } 00363 00364 if ((Opcode == LDACQ_OP) || (Opcode == LDCCLRACQ_OP)) { 00365 00366 // 00367 // all future access should occur after unaligned memory accesses 00368 // 00369 00370 __mf(); 00371 } 00372 00373 break; 00374 00375 // 00376 // normal, advance, and check load 00377 // immidiate updated form 00378 // 00379 00380 case LD_IMM_OP: 00381 case LDA_IMM_OP: 00382 case LDBIAS_IMM_OP: 00383 case LDCCLR_IMM_OP: 00384 case LDCNC_IMM_OP: 00385 case LDACQ_IMM_OP: 00386 case LDCCLRACQ_IMM_OP: 00387 00388 if( PreviousMode != KernelMode ){ 00389 ProbeForRead( EffectiveAddress, 00390 1 << OpSize, 00391 sizeof(UCHAR) ); 00392 } 00393 KiEmulateLoad(EffectiveAddress, OpSize, &Data); 00394 KiSetRegisterValue( (ULONG) FaultInstruction.u.i_field.r1, 00395 Data, 00396 ExceptionFrame, 00397 TrapFrame ); 00398 00399 // 00400 // Update the address register R3 00401 // 00402 00403 Reg3Value = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00404 ExceptionFrame, 00405 TrapFrame ); 00406 00407 // 00408 // immediate update form 00409 // 00410 00411 ImmValue = (ULONG)(FaultInstruction.u.i_field.r2 00412 + (FaultInstruction.u.i_field.x << 7)); 00413 00414 if (FaultInstruction.u.i_field.m == 1) { 00415 00416 ImmValue = 0xFFFFFFFFFFFFFF00 | ImmValue; 00417 00418 } 00419 00420 Reg3Value = Reg3Value + ImmValue; 00421 00422 KiSetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00423 Reg3Value, 00424 ExceptionFrame, 00425 TrapFrame ); 00426 00427 if ((Opcode == LDACQ_IMM_OP) || (Opcode == LDCCLRACQ_IMM_OP)) { 00428 00429 // 00430 // all future access should occur after unaligned memory accesses 00431 // 00432 00433 __mf(); 00434 } 00435 00436 break; 00437 00438 case LDF_OP: 00439 case LDFA_OP: 00440 case LDFCCLR_OP: 00441 case LDFCNC_OP: 00442 00443 if (FaultInstruction.u.i_field.x == 1) { 00444 00445 // 00446 // floating point load pair 00447 // 00448 00449 if (FaultInstruction.u.i_field.m == 1) { 00450 00451 // 00452 // m field must be zero 00453 // 00454 00455 return FALSE; 00456 00457 } 00458 00459 if( PreviousMode != KernelMode ){ 00460 00461 switch (OpSize) { 00462 case 0: return FALSE; 00463 case 1: Length = 8; break; 00464 case 2: Length = 4; break; 00465 case 3: Length = 8; break; 00466 default: 00467 return FALSE; 00468 } 00469 00470 ProbeForRead( EffectiveAddress, 00471 Length << 1, 00472 sizeof(UCHAR) ); 00473 } 00474 00475 // 00476 // emulate the 1st half of the pair 00477 // 00478 00479 KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData); 00480 KiSetFloatRegisterValue( (ULONG) FaultInstruction.u.i_field.r1, 00481 FloatData, 00482 ExceptionFrame, 00483 TrapFrame ); 00484 00485 // 00486 // emulate the 2nd half of the pair 00487 // 00488 00489 EffectiveAddress = (PVOID)((ULONG_PTR)EffectiveAddress + Length); 00490 00491 KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData); 00492 KiSetFloatRegisterValue( (ULONG) FaultInstruction.u.i_field.r2, 00493 FloatData, 00494 ExceptionFrame, 00495 TrapFrame ); 00496 00497 } else { 00498 00499 // 00500 // floating point single load 00501 // 00502 00503 if( PreviousMode != KernelMode ){ 00504 00505 switch (OpSize) { 00506 case 0: Length = 16; break; 00507 case 1: Length = 8; break; 00508 case 2: Length = 4; break; 00509 case 3: Length = 8; break; 00510 default: 00511 return FALSE; 00512 } 00513 00514 ProbeForRead( EffectiveAddress, 00515 Length, 00516 sizeof(UCHAR) ); 00517 } 00518 00519 KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData); 00520 KiSetFloatRegisterValue( (ULONG) FaultInstruction.u.i_field.r1, 00521 FloatData, 00522 ExceptionFrame, 00523 TrapFrame ); 00524 00525 if (FaultInstruction.u.i_field.m == 1) { 00526 00527 // 00528 // update the address register (R3) 00529 // 00530 00531 Reg2Value = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r2, 00532 ExceptionFrame, 00533 TrapFrame ); 00534 00535 Reg3Value = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00536 ExceptionFrame, 00537 TrapFrame ); 00538 // 00539 // register update form 00540 // 00541 00542 Reg3Value = Reg2Value + Reg3Value; 00543 00544 KiSetRegisterValue ((ULONG) FaultInstruction.u.i_field.r3, 00545 Reg3Value, 00546 ExceptionFrame, 00547 TrapFrame); 00548 } 00549 } 00550 00551 break; 00552 00553 // 00554 // normal, advanced and checked floating point load 00555 // immediate updated form 00556 // 00557 00558 case LDF_IMM_OP: 00559 case LDFA_IMM_OP: 00560 case LDFCCLR_IMM_OP: 00561 case LDFCNC_IMM_OP: 00562 00563 if (FaultInstruction.u.i_field.x == 1) { 00564 00565 // 00566 // floating point load pair 00567 // 00568 00569 if (FaultInstruction.u.i_field.m == 0) { 00570 00571 // 00572 // m field must be one 00573 // 00574 00575 return FALSE; 00576 00577 } 00578 00579 if( PreviousMode != KernelMode ){ 00580 00581 switch (OpSize) { 00582 case 0: return FALSE; 00583 case 1: Length = 8; break; 00584 case 2: Length = 8; break; 00585 case 3: Length = 4; break; 00586 default: 00587 return FALSE; 00588 } 00589 00590 ProbeForRead( EffectiveAddress, 00591 Length << 1, 00592 sizeof(UCHAR) ); 00593 } 00594 00595 // 00596 // emulate the 1st half of the pair 00597 // 00598 00599 KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData); 00600 KiSetFloatRegisterValue( (ULONG) FaultInstruction.u.i_field.r1, 00601 FloatData, 00602 ExceptionFrame, 00603 TrapFrame ); 00604 00605 EffectiveAddress = (PVOID)((ULONG_PTR)EffectiveAddress + Length); 00606 00607 // 00608 // emulate the 2nd half of the pair 00609 // 00610 00611 KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData); 00612 KiSetFloatRegisterValue( (ULONG) FaultInstruction.u.i_field.r2, 00613 FloatData, 00614 ExceptionFrame, 00615 TrapFrame ); 00616 00617 // 00618 // Update the address register (R3) 00619 // 00620 00621 Reg3Value = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00622 ExceptionFrame, 00623 TrapFrame ); 00624 00625 // 00626 // immediate update form 00627 // 00628 00629 ImmValue = Length << 1; 00630 00631 Reg3Value = Reg3Value + ImmValue; 00632 00633 KiSetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00634 Reg3Value, 00635 ExceptionFrame, 00636 TrapFrame ); 00637 00638 } else { 00639 00640 // 00641 // floating point single load 00642 // 00643 00644 if( PreviousMode != KernelMode ){ 00645 00646 switch (OpSize) { 00647 case 0: Length = 16; break; 00648 case 1: Length = 8; break; 00649 case 2: Length = 4; break; 00650 case 3: Length = 8; break; 00651 default: 00652 return FALSE; 00653 } 00654 00655 ProbeForRead( EffectiveAddress, 00656 Length, 00657 sizeof(UCHAR) ); 00658 } 00659 KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData); 00660 KiSetFloatRegisterValue( (ULONG) FaultInstruction.u.i_field.r1, 00661 FloatData, 00662 ExceptionFrame, 00663 TrapFrame ); 00664 00665 // 00666 // Update the address register (R3) 00667 // 00668 00669 Reg3Value = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00670 ExceptionFrame, 00671 TrapFrame ); 00672 00673 // 00674 // immediate update form 00675 // 00676 00677 ImmValue = (ULONG)(FaultInstruction.u.i_field.r2 00678 + (FaultInstruction.u.i_field.x << 7)); 00679 00680 if (FaultInstruction.u.i_field.m == 1) { 00681 00682 ImmValue = 0xFFFFFFFFFFFFFF00 | ImmValue; 00683 00684 } 00685 00686 Reg3Value = Reg3Value + ImmValue; 00687 00688 KiSetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00689 Reg3Value, 00690 ExceptionFrame, 00691 TrapFrame ); 00692 } 00693 00694 break; 00695 00696 00697 case STREL_OP: 00698 00699 __mf(); 00700 00701 case ST_OP: 00702 00703 if (FaultInstruction.u.i_field.x == 1) { 00704 00705 // 00706 // xField must be 0 00707 // 00708 00709 return FALSE; 00710 } 00711 00712 if (FaultInstruction.u.i_field.m == 1) { 00713 00714 // 00715 // no register update form defined 00716 // 00717 00718 return FALSE; 00719 } 00720 00721 if( PreviousMode != KernelMode ){ 00722 ProbeForWrite( EffectiveAddress, 00723 1 << OpSize, 00724 sizeof(UCHAR) ); 00725 } 00726 Data = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r2, 00727 ExceptionFrame, 00728 TrapFrame ); 00729 00730 KiEmulateStore( EffectiveAddress, OpSize, &Data); 00731 00732 break; 00733 00734 case STREL_IMM_OP: 00735 00736 __mf(); 00737 00738 case ST_IMM_OP: 00739 00740 if( PreviousMode != KernelMode ){ 00741 ProbeForWrite( EffectiveAddress, 00742 1 << OpSize, 00743 sizeof(UCHAR) ); 00744 } 00745 Data = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r2, 00746 ExceptionFrame, 00747 TrapFrame ); 00748 00749 KiEmulateStore( EffectiveAddress, OpSize, &Data); 00750 00751 // 00752 // update the address register (R3) 00753 // 00754 00755 Reg3Value = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00756 ExceptionFrame, 00757 TrapFrame ); 00758 00759 // 00760 // immediate update form 00761 // 00762 00763 ImmValue = (ULONG)(FaultInstruction.u.i_field.r1 00764 + (FaultInstruction.u.i_field.x << 7)); 00765 00766 if (FaultInstruction.u.i_field.m == 1) { 00767 00768 ImmValue = 0xFFFFFFFFFFFFFF00 | ImmValue; 00769 00770 } 00771 00772 Reg3Value = Reg3Value + ImmValue; 00773 00774 KiSetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00775 Reg3Value, 00776 ExceptionFrame, 00777 TrapFrame ); 00778 00779 break; 00780 00781 00782 case STF_OP: 00783 00784 if (FaultInstruction.u.i_field.x) { 00785 00786 // 00787 // x field must be 0 00788 // 00789 00790 return FALSE; 00791 } 00792 00793 if (FaultInstruction.u.i_field.m) { 00794 00795 // 00796 // no register update form defined 00797 // 00798 00799 return FALSE; 00800 } 00801 00802 if( PreviousMode != KernelMode ){ 00803 00804 switch (OpSize) { 00805 case 0: Length = 16; break; 00806 case 1: Length = 8; break; 00807 case 2: Length = 4; break; 00808 case 3: Length = 8; break; 00809 default: 00810 return FALSE; 00811 } 00812 00813 ProbeForWrite( EffectiveAddress, 00814 Length, 00815 sizeof(UCHAR) ); 00816 } 00817 FloatData = KiGetFloatRegisterValue( (ULONG) FaultInstruction.u.i_field.r2, 00818 ExceptionFrame, 00819 TrapFrame ); 00820 00821 KiEmulateStoreFloat( EffectiveAddress, OpSize, &FloatData); 00822 00823 break; 00824 00825 case STF_IMM_OP: 00826 00827 if( PreviousMode != KernelMode ){ 00828 00829 switch (OpSize) { 00830 case 0: Length = 16; break; 00831 case 1: Length = 8; break; 00832 case 2: Length = 4; break; 00833 case 3: Length = 8; break; 00834 default: 00835 return FALSE; 00836 } 00837 00838 ProbeForWrite( EffectiveAddress, 00839 Length, 00840 sizeof(UCHAR) ); 00841 } 00842 FloatData = KiGetFloatRegisterValue( (ULONG) FaultInstruction.u.i_field.r2, 00843 ExceptionFrame, 00844 TrapFrame ); 00845 00846 KiEmulateStoreFloat( EffectiveAddress, OpSize, &FloatData); 00847 00848 // 00849 // update the address register (R3) 00850 // 00851 00852 Reg3Value = KiGetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00853 ExceptionFrame, 00854 TrapFrame ); 00855 // 00856 // immediate update form 00857 // 00858 00859 ImmValue = (ULONG)(FaultInstruction.u.i_field.r1 00860 + (FaultInstruction.u.i_field.x << 7)); 00861 00862 if (FaultInstruction.u.i_field.m == 1) { 00863 00864 ImmValue = 0xFFFFFFFFFFFFFF00 | ImmValue; 00865 00866 } 00867 00868 Reg3Value = Reg3Value + ImmValue; 00869 00870 KiSetRegisterValue( (ULONG) FaultInstruction.u.i_field.r3, 00871 Reg3Value, 00872 ExceptionFrame, 00873 TrapFrame ); 00874 00875 break; 00876 00877 default: 00878 00879 return FALSE; 00880 00881 } 00882 00883 // 00884 // advance instruction pointer 00885 // 00886 00887 KiAdvanceInstPointer(TrapFrame); 00888 00889 return TRUE; 00890 00891 // 00892 // If an exception occurs, then copy the new exception information to the 00893 // original exception record and handle the exception. 00894 // 00895 00896 } except (KiCopyInformation(ExceptionRecord, 00897 (GetExceptionInformation())->ExceptionRecord)) { 00898 00899 // 00900 // Preserve the original exception address. 00901 // 00902 00903 ExceptionRecord->ExceptionAddress = ExceptionAddress; 00904 } 00905 00906 // 00907 // Return a value of FALSE. 00908 // 00909 00910 return FALSE; 00911 }

VOID KiEmulateStore IN PVOID  UnalignedAddress,
IN ULONG  OperandSize,
IN PVOID  Data
 

Definition at line 962 of file ia64/alignem.c.

Referenced by KiEmulateReference().

00969 : 00970 00971 This routine store the integer value at the unaligned 00972 address passed in UnalignedAddress. 00973 00974 Arguments: 00975 00976 UnalignedAddress - Supplies a pointer to be stored 00977 00978 OperandSize - Supplies the size of data to be storeed 00979 00980 Data - Supplies a pointer to data value 00981 00982 Return Value: 00983 00984 The value at the address pointed to by UnalignedAddress. 00985 00986 --*/ 00987 { 00988 PUCHAR Source; 00989 PUCHAR Destination; 00990 ULONG i; 00991 00992 Source = (PUCHAR) Data; 00993 Destination = (PUCHAR) UnalignedAddress; 00994 OperandSize = 1 << OperandSize; 00995 00996 for (i = 0; i < OperandSize; i++) { 00997 00998 *Destination++ = *Source++; 00999 01000 } 01001 01002 return; 01003 }

VOID KiEmulateStoreFloat IN PVOID  UnalignedAddress,
IN ULONG  OperandSize,
IN PVOID  Data
 

Definition at line 1063 of file ia64/alignem.c.

References KiEmulateStoreFloat32(), KiEmulateStoreFloat64(), KiEmulateStoreFloat80(), and KiEmulateStoreFloatInt().

Referenced by KiEmulateReference().

01071 : 01072 01073 This routine stores the floating point value stored at the unaligned 01074 address passed in UnalignedAddress. 01075 01076 Arguments: 01077 01078 UnalignedAddress - Supplies a pointer to be stored. 01079 01080 OperandSize - Supplies the size of data to be loaded 01081 01082 Data - Supplies a pointer to floating point data 01083 01084 Return Value: 01085 01086 The value at the address pointed to by UnalignedAddress. 01087 01088 --*/ 01089 01090 { 01091 FLOAT128 FloatData; 01092 ULONG Length; 01093 01094 switch (OperandSize) { 01095 01096 case 0: 01097 KiEmulateStoreFloat80(&FloatData, Data); 01098 Length = 16; 01099 break; 01100 01101 case 1: 01102 KiEmulateStoreFloatInt(&FloatData, Data); 01103 Length = 8; 01104 break; 01105 01106 case 2: 01107 KiEmulateStoreFloat32(&FloatData, Data); 01108 Length = 4; 01109 break; 01110 01111 case 3: 01112 KiEmulateStoreFloat64(&FloatData, Data); 01113 Length = 8; 01114 break; 01115 01116 default: 01117 return; 01118 } 01119 01120 RtlMoveMemory(UnalignedAddress, &FloatData, Length); 01121 }

VOID KiEmulateStoreFloat32 IN PVOID  UnalignedAddress,
OUT PVOID  FloatData
 

Referenced by KiEmulateStoreFloat().

VOID KiEmulateStoreFloat64 IN PVOID  UnalignedAddress,
OUT PVOID  FloatData
 

Referenced by KiEmulateStoreFloat().

VOID KiEmulateStoreFloat80 IN PVOID  UnalignedAddress,
OUT PVOID  FloatData
 

Referenced by KiEmulateStoreFloat().

VOID KiEmulateStoreFloatInt IN PVOID  UnalignedAddress,
OUT PVOID  FloatData
 

Referenced by KiEmulateStoreFloat().


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