00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
#include "ki.h"
00031
00032
00033
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
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
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
00095
00096
00097 ExceptionAddress = ExceptionRecord->ExceptionAddress;
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 PreviousMode = (
KPROCESSOR_MODE)(((
PSR *)(&TrapFrame->Psr))->MODE);
00112
00113
try {
00114
00115
00116
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
00129
00130
00131
case LDBU_OP :
00132
case LDWU_OP :
00133
case STB_OP :
00134
case STW_OP :
00135
00136
00137
00138
00139
00140
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
00156
00157
00158
switch (Instruction.Memory.Opcode) {
00159
00160
00161
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
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
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
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
00239
00240
00241
case SEXT_OP :
00242
switch (Instruction.OpReg.Function) {
00243
00244
00245
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
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
00274
00275
00276
default :
00277
return FALSE;
00278 }
00279
00280
break;
00281
00282
00283
00284
00285
00286
default :
00287
return FALSE;
00288 }
00289
00290
#if 0
00291
00292
00293
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
00318
00319
00320 ExceptionRecord->ExceptionAddress = ExceptionAddress;
00321
00322
return FALSE;
00323 }
00324
00325 AlignmentFault :
00326
00327
00328
00329
00330
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 }