test: alpha/alignem.c File Reference

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().