00263 :
00264
00265 This function
is called to emulate an unaligned data reference to an
00266 address in
the user part of
the address space.
00267
00268 Arguments:
00269
00270 ExceptionRecord - Supplies a pointer to an exception record.
00271
00272 ExceptionFrame - Supplies a pointer to an exception frame.
00273
00274 TrapFrame - Supplies a pointer to a trap frame.
00275
00276 Return Value:
00277
00278
A value of
TRUE is returned
if the data reference
is successfully
00279 emulated. Otherwise, a value of
FALSE is returned.
00280
00281 --*/
00282
00283 {
00284
00285 ULONG BranchAddress;
00286 PUCHAR DataAddress;
00287
00288
union {
00289 DOUBLE Double;
00290
float Float;
00291 ULONG Long;
00292
SHORT Short;
00293 } DataReference;
00294 PUCHAR DataValue = (PUCHAR) &DataReference;
00295
00296 PVOID ExceptionAddress;
00297
DSISR DsisrValue;
00298 ULONG TableIndex;
00299 ULONG DataRegNum;
00300
ALFAULT Info;
00301 KIRQL OldIrql;
00302
00303
00304
00305
00306
if (
KiProfileAlignmentFixup) {
00307
00308
if (++
KiProfileAlignmentFixupCount >=
KiProfileAlignmentFixupInterval) {
00309
00310
KeRaiseIrql(PROFILE_LEVEL, &OldIrql);
00311
KiProfileAlignmentFixupCount = 0;
00312
KeProfileInterruptWithSource(TrapFrame, ProfileAlignmentFixup);
00313
KeLowerIrql(OldIrql);
00314
00315 }
00316 }
00317
00318
00319
00320
00321
00322
00323 ExceptionAddress = ExceptionRecord->ExceptionAddress;
00324
00325
00326
00327
00328
00329
00330
00331
00332
try {
00333
00334
00335
00336
00337
00338 BranchAddress = TrapFrame->Iar + 4;
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 DataAddress = (PUCHAR) (ExceptionRecord->ExceptionInformation[1]);
00350
00351
if ((ULONG)DataAddress < MM_USER_PROBE_ADDRESS) {
00352
00353
00354
00355
00356
00357 DsisrValue = *(
DSISR*) &(ExceptionRecord->ExceptionInformation[2]);
00358 TableIndex = DsisrValue.
Index;
00359 DataRegNum = DsisrValue.
DataReg;
00360 Info =
AlFault[TableIndex];
00361
00362
00363
00364
00365
00366
if (!Info.
Valid)
00367
return FALSE;
00368
00369
00370
00371
00372
00373
00374
if (!Info.
Escape) {
00375
00376
00377
00378
00379
00380
if (Info.
Fixed) {
00381
00382
00383
00384
00385
00386
if (Info.
Load) {
00387
00388
00389
00390
00391
00392
switch (Info.
Length) {
00393
00394
00395
00396
00397
00398
case 1:
00399 DataValue[0] = DataAddress[0];
00400 DataValue[1] = DataAddress[1];
00401
KiSetRegisterValue
00402 (DataRegNum,
00403 Info.
Signed ?
00404 (ULONG) ((LONG) DataReference.Short) :
00405 (ULONG) ((
USHORT) DataReference.Short),
00406 ExceptionFrame,
00407 TrapFrame);
00408
break;
00409
00410
00411
00412
00413
00414
case 2:
00415 DataValue[0] = DataAddress[0];
00416 DataValue[1] = DataAddress[1];
00417 DataValue[2] = DataAddress[2];
00418 DataValue[3] = DataAddress[3];
00419
KiSetRegisterValue
00420 (DataRegNum,
00421 DataReference.Long,
00422 ExceptionFrame,
00423 TrapFrame);
00424
break;
00425
00426
00427
00428
00429
00430
case 3:
00431
return FALSE;
00432
00433 }
00434 }
else {
00435
00436
00437
00438
00439
00440
switch (Info.
Length) {
00441
00442
00443
00444
00445
00446
case 1:
00447 DataReference.Short = (
SHORT)
00448
KiGetRegisterValue
00449 (DataRegNum,
00450 ExceptionFrame,
00451 TrapFrame);
00452 DataAddress[0] = DataValue[0];
00453 DataAddress[1] = DataValue[1];
00454
break;
00455
00456
00457
00458
00459
00460
case 2:
00461 DataReference.Long =
00462
KiGetRegisterValue
00463 (DataRegNum,
00464 ExceptionFrame,
00465 TrapFrame);
00466 DataAddress[0] = DataValue[0];
00467 DataAddress[1] = DataValue[1];
00468 DataAddress[2] = DataValue[2];
00469 DataAddress[3] = DataValue[3];
00470
break;
00471
00472
00473
00474
00475
00476
case 3:
00477
00478
return FALSE;
00479 }
00480 }
00481 }
else {
00482
00483
00484
00485
00486
00487
if (Info.
Load) {
00488
00489
00490
00491
00492
00493
if (Info.
Length == 2) {
00494
00495
00496
00497
00498 DataValue[0] = DataAddress[0];
00499 DataValue[1] = DataAddress[1];
00500 DataValue[2] = DataAddress[2];
00501 DataValue[3] = DataAddress[3];
00502
KiSetFloatRegisterValue
00503 (DataRegNum,
00504 (DOUBLE) DataReference.Float,
00505 ExceptionFrame,
00506 TrapFrame);
00507
00508 }
else {
00509
00510
00511
00512
00513 DataValue[0] = DataAddress[0];
00514 DataValue[1] = DataAddress[1];
00515 DataValue[2] = DataAddress[2];
00516 DataValue[3] = DataAddress[3];
00517 DataValue[4] = DataAddress[4];
00518 DataValue[5] = DataAddress[5];
00519 DataValue[6] = DataAddress[6];
00520 DataValue[7] = DataAddress[7];
00521
KiSetFloatRegisterValue
00522 (DataRegNum,
00523 DataReference.Double,
00524 ExceptionFrame,
00525 TrapFrame);
00526 }
00527 }
else {
00528
00529
00530
00531
00532
00533
if (Info.
Length == 2) {
00534
00535
00536
00537
00538
00539 DataReference.Float = (
float)
00540
KiGetFloatRegisterValue
00541 (DataRegNum,
00542 ExceptionFrame,
00543 TrapFrame);
00544 DataAddress[0] = DataValue[0];
00545 DataAddress[1] = DataValue[1];
00546 DataAddress[2] = DataValue[2];
00547 DataAddress[3] = DataValue[3];
00548
00549 }
else {
00550
00551
00552
00553
00554 DataReference.Double =
00555
KiGetFloatRegisterValue
00556 (DataRegNum,
00557 ExceptionFrame,
00558 TrapFrame);
00559 DataAddress[0] = DataValue[0];
00560 DataAddress[1] = DataValue[1];
00561 DataAddress[2] = DataValue[2];
00562 DataAddress[3] = DataValue[3];
00563 DataAddress[4] = DataValue[4];
00564 DataAddress[5] = DataValue[5];
00565 DataAddress[6] = DataValue[6];
00566 DataAddress[7] = DataValue[7];
00567 }
00568 }
00569 }
00570
00571
00572
00573
00574
00575
if (Info.
Update)
00576
KiSetRegisterValue
00577 (DsisrValue.
UpdateReg,
00578 (ULONG) DataAddress,
00579 ExceptionFrame,
00580 TrapFrame);
00581
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
else {
00592
switch (TableIndex) {
00593
00594
00595
00596
00597
00598
case LD_INDEX_VALUE:
00599
case STD_INDEX_VALUE:
00600
return FALSE;
00601
00602
00603
00604
00605
00606
00607
case LDARX_INDEX_VALUE:
00608
case STWCX_INDEX_VALUE:
00609
case STDCX_INDEX_VALUE:
00610
return FALSE;
00611
00612
00613
00614
00615
00616
case LWBRX_INDEX_VALUE:
00617 DataValue[0] = DataAddress[3];
00618 DataValue[1] = DataAddress[2];
00619 DataValue[2] = DataAddress[1];
00620 DataValue[3] = DataAddress[0];
00621
KiSetRegisterValue
00622 (DataRegNum,
00623 DataReference.Long,
00624 ExceptionFrame,
00625 TrapFrame);
00626
break;
00627
00628
00629
00630
00631
00632
case STWBRX_INDEX_VALUE:
00633 DataReference.Long =
00634
KiGetRegisterValue
00635 (DataRegNum,
00636 ExceptionFrame,
00637 TrapFrame);
00638 DataAddress[0] = DataValue[3];
00639 DataAddress[1] = DataValue[2];
00640 DataAddress[2] = DataValue[1];
00641 DataAddress[3] = DataValue[0];
00642
break;
00643
00644
00645
00646
00647
00648
case LHBRX_INDEX_VALUE:
00649 DataValue[0] = DataAddress[1];
00650 DataValue[1] = DataAddress[0];
00651
KiSetRegisterValue
00652 (DataRegNum,
00653 Info.
Signed ?
00654 (ULONG) ((LONG) DataReference.Short) :
00655 (ULONG) ((
USHORT) DataReference.Short),
00656 ExceptionFrame,
00657 TrapFrame);
00658
break;
00659
00660
00661
00662
00663
00664
case STHBRX_INDEX_VALUE:
00665 DataReference.Short = (
SHORT)
00666
KiGetRegisterValue
00667 (DataRegNum,
00668 ExceptionFrame,
00669 TrapFrame);
00670 DataAddress[0] = DataValue[1];
00671 DataAddress[1] = DataValue[0];
00672
break;
00673
00674
00675
00676
00677
00678
case ECIWX_INDEX_VALUE:
00679
case ECOWX_INDEX_VALUE:
00680
return FALSE;
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
case DCBZ_INDEX_VALUE: {
00697 PULONG DcbAddress = (PULONG)((ULONG)DataAddress & ~0x1f);
00698
00699 *DcbAddress++ = 0;
00700 *DcbAddress++ = 0;
00701 *DcbAddress++ = 0;
00702 *DcbAddress++ = 0;
00703 *DcbAddress++ = 0;
00704 *DcbAddress++ = 0;
00705 *DcbAddress++ = 0;
00706 *DcbAddress++ = 0;
00707
break;
00708 }
00709
00710
00711
00712
00713
00714
case STFIWX_INDEX_VALUE:
00715 DataReference.Double =
00716
KiGetFloatRegisterValue
00717 (DataRegNum,
00718 ExceptionFrame,
00719 TrapFrame);
00720 DataAddress[0] = DataValue[0];
00721 DataAddress[1] = DataValue[1];
00722 DataAddress[2] = DataValue[2];
00723 DataAddress[3] = DataValue[3];
00724 }
00725 }
00726
00727 TrapFrame->Iar = BranchAddress;
00728
return TRUE;
00729 }
00730
00731
00732
00733
00734
00735
00736 } except (
KiCopyInformation(ExceptionRecord,
00737 (GetExceptionInformation())->ExceptionRecord)) {
00738
00739
00740
00741
00742
00743 ExceptionRecord->ExceptionAddress = ExceptionAddress;
00744 }
00745
00746
00747
00748
00749
00750
return FALSE;
00751 }