00037 :
00038
00039 This function
is called to emulate an unaligned data reference to an
00040 address in
the user part of
the address space.
00041
00042 Arguments:
00043
00044 ExceptionRecord - Supplies a pointer to an exception record.
00045
00046 ExceptionFrame - Supplies a pointer to an exception frame.
00047
00048 TrapFrame - Supplies a pointer to a trap frame.
00049
00050 Return Value:
00051
00052
A value of
TRUE is returned
if the data reference
is successfully
00053 emulated. Otherwise, a value of
FALSE is returned.
00054
00055 --*/
00056
00057 {
00058
00059 ULONG BranchAddress;
00060 PUCHAR DataAddress;
00061
00062
union {
00063 ULONGLONG Longlong;
00064 ULONG Long;
00065
USHORT Short;
00066 } DataReference;
00067
00068 PUCHAR DataValue;
00069 PVOID ExceptionAddress;
00070 MIPS_INSTRUCTION FaultInstruction;
00071 ULONG Rt;
00072 KIRQL OldIrql;
00073
00074
00075
00076
00077
00078
00079
if (
KiProfileAlignmentFixup) {
00080
KiProfileAlignmentFixupCount += 1;
00081
if (
KiProfileAlignmentFixupCount >=
KiProfileAlignmentFixupInterval) {
00082
KeRaiseIrql(PROFILE_LEVEL, &OldIrql);
00083
KiProfileAlignmentFixupCount = 0;
00084
KeProfileInterruptWithSource(TrapFrame, ProfileAlignmentFixup);
00085
KeLowerIrql(OldIrql);
00086 }
00087 }
00088
00089
00090
00091
00092
00093
00094 ExceptionAddress = ExceptionRecord->ExceptionAddress;
00095
00096
00097
00098
00099
00100
00101
00102
00103
try {
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
if ((TrapFrame->Fir + 4) == (ULONG)ExceptionRecord->ExceptionAddress) {
00115 BranchAddress =
KiEmulateBranch(ExceptionFrame, TrapFrame);
00116
00117 }
else {
00118 BranchAddress = TrapFrame->Fir + 4;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128 FaultInstruction.Long = *((PULONG)ExceptionRecord->ExceptionAddress);
00129 DataAddress = (PUCHAR)
KiGetRegisterValue64(FaultInstruction.i_format.Rs,
00130 ExceptionFrame,
00131 TrapFrame);
00132
00133 DataAddress = (PUCHAR)((LONG)DataAddress +
00134 (LONG)FaultInstruction.i_format.Simmediate);
00135
00136
00137
00138
00139
00140
00141
if ((ULONG)DataAddress < 0x7ffffff0) {
00142
00143
00144
00145
00146
00147 DataValue = (PUCHAR)&DataReference;
00148 Rt = FaultInstruction.i_format.Rt;
00149
switch (FaultInstruction.i_format.Opcode) {
00150
00151
00152
00153
00154
00155
case LH_OP:
00156 DataValue[0] = DataAddress[0];
00157 DataValue[1] = DataAddress[1];
00158
KiSetRegisterValue64(Rt,
00159 (SHORT)DataReference.Short,
00160 ExceptionFrame,
00161 TrapFrame);
00162
00163
break;
00164
00165
00166
00167
00168
00169
case LHU_OP:
00170 DataValue[0] = DataAddress[0];
00171 DataValue[1] = DataAddress[1];
00172
KiSetRegisterValue64(Rt,
00173 DataReference.Short,
00174 ExceptionFrame,
00175 TrapFrame);
00176
00177
break;
00178
00179
00180
00181
00182
00183
case LWC1_OP:
00184 DataValue[0] = DataAddress[0];
00185 DataValue[1] = DataAddress[1];
00186 DataValue[2] = DataAddress[2];
00187 DataValue[3] = DataAddress[3];
00188
KiSetRegisterValue(Rt + 32,
00189 DataReference.Long,
00190 ExceptionFrame,
00191 TrapFrame);
00192
00193
break;
00194
00195
00196
00197
00198
00199
case LW_OP:
00200 DataValue[0] = DataAddress[0];
00201 DataValue[1] = DataAddress[1];
00202 DataValue[2] = DataAddress[2];
00203 DataValue[3] = DataAddress[3];
00204
KiSetRegisterValue64(Rt,
00205 (LONG)DataReference.Long,
00206 ExceptionFrame,
00207 TrapFrame);
00208
00209
break;
00210
00211
00212
00213
00214
00215
case LD_OP:
00216 DataValue[0] = DataAddress[0];
00217 DataValue[1] = DataAddress[1];
00218 DataValue[2] = DataAddress[2];
00219 DataValue[3] = DataAddress[3];
00220 DataValue[4] = DataAddress[4];
00221 DataValue[5] = DataAddress[5];
00222 DataValue[6] = DataAddress[6];
00223 DataValue[7] = DataAddress[7];
00224
KiSetRegisterValue64(Rt,
00225 DataReference.Longlong,
00226 ExceptionFrame,
00227 TrapFrame);
00228
00229
break;
00230
00231
00232
00233
00234
00235
case LDC1_OP:
00236 Rt = (Rt & 0x1e) + 32;
00237 DataValue[0] = DataAddress[0];
00238 DataValue[1] = DataAddress[1];
00239 DataValue[2] = DataAddress[2];
00240 DataValue[3] = DataAddress[3];
00241
KiSetRegisterValue(Rt,
00242 DataReference.Long,
00243 ExceptionFrame,
00244 TrapFrame);
00245
00246 DataValue[0] = DataAddress[4];
00247 DataValue[1] = DataAddress[5];
00248 DataValue[2] = DataAddress[6];
00249 DataValue[3] = DataAddress[7];
00250
KiSetRegisterValue(Rt + 1,
00251 DataReference.Long,
00252 ExceptionFrame,
00253 TrapFrame);
00254
00255
break;
00256
00257
00258
00259
00260
00261
case SH_OP:
00262 DataReference.Longlong =
KiGetRegisterValue64(Rt,
00263 ExceptionFrame,
00264 TrapFrame);
00265
00266 DataAddress[0] = DataValue[0];
00267 DataAddress[1] = DataValue[1];
00268
break;
00269
00270
00271
00272
00273
00274
case SWC1_OP:
00275 DataReference.Long =
KiGetRegisterValue(Rt + 32,
00276 ExceptionFrame,
00277 TrapFrame);
00278
00279 DataAddress[0] = DataValue[0];
00280 DataAddress[1] = DataValue[1];
00281 DataAddress[2] = DataValue[2];
00282 DataAddress[3] = DataValue[3];
00283
break;
00284
00285
00286
00287
00288
00289
case SW_OP:
00290 DataReference.Longlong =
KiGetRegisterValue64(Rt,
00291 ExceptionFrame,
00292 TrapFrame);
00293
00294 DataAddress[0] = DataValue[0];
00295 DataAddress[1] = DataValue[1];
00296 DataAddress[2] = DataValue[2];
00297 DataAddress[3] = DataValue[3];
00298
break;
00299
00300
00301
00302
00303
00304
case SD_OP:
00305 DataReference.Longlong =
KiGetRegisterValue64(Rt,
00306 ExceptionFrame,
00307 TrapFrame);
00308
00309 DataAddress[0] = DataValue[0];
00310 DataAddress[1] = DataValue[1];
00311 DataAddress[2] = DataValue[2];
00312 DataAddress[3] = DataValue[3];
00313 DataAddress[4] = DataValue[4];
00314 DataAddress[5] = DataValue[5];
00315 DataAddress[6] = DataValue[6];
00316 DataAddress[7] = DataValue[7];
00317
break;
00318
00319
00320
00321
00322
00323
case SDC1_OP:
00324 Rt = (Rt & 0x1e) + 32;
00325 DataReference.Long =
KiGetRegisterValue(Rt,
00326 ExceptionFrame,
00327 TrapFrame);
00328
00329 DataAddress[0] = DataValue[0];
00330 DataAddress[1] = DataValue[1];
00331 DataAddress[2] = DataValue[2];
00332 DataAddress[3] = DataValue[3];
00333 DataReference.Long =
KiGetRegisterValue(Rt + 1,
00334 ExceptionFrame,
00335 TrapFrame);
00336
00337 DataAddress[4] = DataValue[0];
00338 DataAddress[5] = DataValue[1];
00339 DataAddress[6] = DataValue[2];
00340 DataAddress[7] = DataValue[3];
00341
break;
00342
00343
00344
00345
00346
00347
default:
00348
return FALSE;
00349 }
00350
00351 TrapFrame->Fir = BranchAddress;
00352
return TRUE;
00353 }
00354
00355
00356
00357
00358
00359
00360 } except (
KiCopyInformation(ExceptionRecord,
00361 (GetExceptionInformation())->ExceptionRecord)) {
00362
00363
00364
00365
00366
00367 ExceptionRecord->ExceptionAddress = ExceptionAddress;
00368 }
00369
00370
00371
00372
00373
00374
return FALSE;
00375 }
}