test: byteem.c File Reference

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

# byteem.c File Reference

`#include "ki.h"`

Go to the source code of this file.

## Functions

VOID | KiInterlockedStoreByte (IN PUCHAR Address, IN UCHAR Data)
VOID | KiInterlockedStoreWord (IN PUSHORT Address, IN USHORT Data)
BOOLEAN | KiEmulateByteWord (IN OUT PEXCEPTION_RECORD ExceptionRecord, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame)

## Function Documentation

BOOLEAN KiEmulateByteWord | ( | IN OUT PEXCEPTION_RECORD | ExceptionRecord,
|  | IN OUT PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN OUT PKTRAP_FRAME | TrapFrame
| ) |

Definition at line 49 of file byteem.c.

References CHAR, FALSE, KeLowerIrql(), KeProfileInterruptWithSource(), KeRaiseIrql(), KernelMode, KiCopyInformation(), KiGetRegisterValue(), KiInterlockedStoreByte(), KiInterlockedStoreWord(), KiSetRegisterValue(), KPROCESSOR_MODE, ProbeForRead, ProbeForWrite(), PROFILE_LEVEL, PSR, PUSHORT, SHORT, TRUE, and USHORT.

Referenced by KiDispatchException().

    00057                    :
    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 }
    }

VOID KiInterlockedStoreByte | ( | IN PUCHAR | Address,
|  | IN UCHAR | Data
| ) |

| Referenced by KiEmulateByteWord().

VOID KiInterlockedStoreWord | ( | IN PUSHORT | Address,
|  | IN USHORT | Data
| ) |

| Referenced by KiEmulateByteWord().