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
#include "ki.h"
00029
00030
VOID
00031
KiSetFloatRegisterValue (
00032 IN ULONG,
00033 IN DOUBLE,
00034 OUT PKEXCEPTION_FRAME,
00035 OUT PKTRAP_FRAME
00036 );
00037
00038 DOUBLE
00039
KiGetFloatRegisterValue (
00040 IN ULONG,
00041 IN PKEXCEPTION_FRAME,
00042 IN PKTRAP_FRAME
00043 );
00044
00045
00046
00047
00048
00049
00050
00051
00052
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
00087
00088
00089
00090
00091
00092
00093
00094
00095 typedef struct _ALFAULT {
00096 ULONG
Valid : 1;
00097 ULONG
Load : 1;
00098 ULONG
Length : 2;
00099 ULONG
Signed : 1;
00100 ULONG
Fixed : 1;
00101 ULONG
Update : 1;
00102 ULONG
Escape : 1;
00103 }
ALFAULT, *
PALFAULT;
00104
00105
00106
00107 #define LDARX_INDEX_VALUE 1
00108 #define LD_INDEX_VALUE 13
00109 #define STD_INDEX_VALUE 15
00110 #define STWCX_INDEX_VALUE 66
00111 #define STDCX_INDEX_VALUE 67
00112 #define LWBRX_INDEX_VALUE 72
00113 #define STWBRX_INDEX_VALUE 74
00114 #define LHBRX_INDEX_VALUE 76
00115 #define STHBRX_INDEX_VALUE 78
00116 #define ECIWX_INDEX_VALUE 84
00117 #define ECOWX_INDEX_VALUE 86
00118 #define DCBZ_INDEX_VALUE 95
00119 #define STFIWX_INDEX_VALUE 111
00120
00121 static ALFAULT AlFault[128] = {
00122
00123
00124 { 1, 1, 2, 0, 1, 0, 0 },
00125 { 1, 1, 3, 0, 1, 0, 1 },
00126 { 1, 0, 2, 0, 1, 0, 0 },
00127 { 0, 0, 0, 0, 0, 0, 0 },
00128 { 1, 1, 1, 0, 1, 0, 0 },
00129 { 1, 1, 1, 1, 1, 0, 0 },
00130 { 1, 0, 1, 0, 1, 0, 0 },
00131 { 0, 0, 0, 0, 0, 0, 0 },
00132 { 1, 1, 2, 0, 0, 0, 0 },
00133 { 1, 1, 3, 0, 0, 0, 0 },
00134 { 1, 0, 2, 0, 0, 0, 0 },
00135 { 1, 0, 3, 0, 0, 0, 0 },
00136 { 0, 0, 0, 0, 0, 0, 0 },
00137 { 1, 1, 0, 0, 0, 0, 1 },
00138 { 0, 0, 0, 0, 0, 0, 0 },
00139 { 1, 0, 0, 0, 0, 0, 1 },
00140 { 1, 1, 2, 0, 1, 1, 0 },
00141 { 0, 0, 0, 0, 0, 0, 0 },
00142 { 1, 0, 2, 0, 1, 1, 0 },
00143 { 0, 0, 0, 0, 0, 0, 0 },
00144 { 1, 1, 1, 0, 1, 1, 0 },
00145 { 1, 1, 1, 1, 1, 1, 0 },
00146 { 1, 0, 1, 0, 1, 1, 0 },
00147 { 0, 0, 0, 0, 0, 0, 0 },
00148 { 1, 1, 2, 0, 0, 1, 0 },
00149 { 1, 1, 3, 0, 0, 1, 0 },
00150 { 1, 0, 2, 0, 0, 1, 0 },
00151 { 1, 0, 3, 0, 0, 1, 0 },
00152 { 0, 0, 0, 0, 0, 0, 0 },
00153 { 0, 0, 0, 0, 0, 0, 0 },
00154 { 0, 0, 0, 0, 0, 0, 0 },
00155 { 0, 0, 0, 0, 0, 0, 0 },
00156 { 1, 1, 3, 0, 1, 0, 0 },
00157 { 0, 0, 0, 0, 0, 0, 0 },
00158 { 1, 0, 3, 0, 1, 0, 0 },
00159 { 0, 0, 0, 0, 0, 0, 0 },
00160 { 0, 0, 0, 0, 0, 0, 0 },
00161 { 1, 1, 2, 1, 1, 0, 0 },
00162 { 0, 0, 0, 0, 0, 0, 0 },
00163 { 0, 0, 0, 0, 0, 0, 0 },
00164 { 0, 0, 0, 0, 0, 0, 0 },
00165 { 0, 0, 0, 0, 0, 0, 0 },
00166 { 0, 0, 0, 0, 0, 0, 0 },
00167 { 0, 0, 0, 0, 0, 0, 0 },
00168 { 0, 0, 0, 0, 0, 0, 0 },
00169 { 0, 0, 0, 0, 0, 0, 0 },
00170 { 0, 0, 0, 0, 0, 0, 0 },
00171 { 0, 0, 0, 0, 0, 0, 0 },
00172 { 1, 1, 3, 0, 1, 1, 0 },
00173 { 0, 0, 0, 0, 0, 0, 0 },
00174 { 1, 0, 3, 0, 1, 1, 0 },
00175 { 0, 0, 0, 0, 0, 0, 0 },
00176 { 0, 0, 0, 0, 0, 0, 0 },
00177 { 1, 1, 2, 1, 1, 1, 0 },
00178 { 0, 0, 0, 0, 0, 0, 0 },
00179 { 0, 0, 0, 0, 0, 0, 0 },
00180 { 0, 0, 0, 0, 0, 0, 0 },
00181 { 0, 0, 0, 0, 0, 0, 0 },
00182 { 0, 0, 0, 0, 0, 0, 0 },
00183 { 0, 0, 0, 0, 0, 0, 0 },
00184 { 0, 0, 0, 0, 0, 0, 0 },
00185 { 0, 0, 0, 0, 0, 0, 0 },
00186 { 0, 0, 0, 0, 0, 0, 0 },
00187 { 0, 0, 0, 0, 0, 0, 0 },
00188 { 0, 0, 0, 0, 0, 0, 0 },
00189 { 0, 0, 0, 0, 0, 0, 0 },
00190 { 1, 0, 2, 0, 1, 0, 1 },
00191 { 1, 0, 3, 0, 1, 0, 1 },
00192 { 0, 0, 0, 0, 0, 0, 0 },
00193 { 0, 0, 0, 0, 0, 0, 0 },
00194 { 0, 0, 0, 0, 0, 0, 0 },
00195 { 0, 0, 0, 0, 0, 0, 0 },
00196 { 1, 1, 2, 0, 1, 0, 1 },
00197 { 0, 0, 0, 0, 0, 0, 0 },
00198 { 1, 0, 2, 0, 1, 0, 1 },
00199 { 0, 0, 0, 0, 0, 0, 0 },
00200 { 1, 1, 1, 0, 1, 0, 1 },
00201 { 0, 0, 0, 0, 0, 0, 0 },
00202 { 1, 0, 1, 0, 1, 0, 1 },
00203 { 0, 0, 0, 0, 0, 0, 0 },
00204 { 0, 0, 0, 0, 0, 0, 0 },
00205 { 0, 0, 0, 0, 0, 0, 0 },
00206 { 0, 0, 0, 0, 0, 0, 0 },
00207 { 0, 0, 0, 0, 0, 0, 0 },
00208 { 1, 1, 2, 0, 1, 0, 1 },
00209 { 0, 0, 0, 0, 0, 0, 0 },
00210 { 1, 0, 2, 0, 1, 0, 1 },
00211 { 0, 0, 0, 0, 0, 0, 0 },
00212 { 0, 0, 0, 0, 0, 0, 0 },
00213 { 0, 0, 0, 0, 0, 0, 0 },
00214 { 0, 0, 0, 0, 0, 0, 0 },
00215 { 0, 0, 0, 0, 0, 0, 0 },
00216 { 0, 0, 0, 0, 0, 0, 0 },
00217 { 0, 0, 0, 0, 0, 0, 0 },
00218 { 0, 0, 0, 0, 0, 0, 0 },
00219 { 1, 0, 0, 0, 0, 0, 1 },
00220 { 1, 1, 2, 0, 1, 0, 0 },
00221 { 0, 0, 0, 0, 0, 0, 0 },
00222 { 1, 0, 2, 0, 1, 0, 0 },
00223 { 0, 0, 0, 0, 0, 0, 0 },
00224 { 1, 1, 1, 0, 1, 0, 0 },
00225 { 1, 1, 1, 1, 1, 0, 0 },
00226 { 1, 0, 1, 0, 1, 0, 0 },
00227 { 0, 0, 0, 0, 0, 0, 0 },
00228 { 1, 1, 2, 0, 0, 0, 0 },
00229 { 1, 1, 3, 0, 0, 0, 0 },
00230 { 1, 0, 2, 0, 0, 0, 0 },
00231 { 1, 0, 3, 0, 0, 0, 0 },
00232 { 0, 0, 0, 0, 0, 0, 0 },
00233 { 0, 0, 0, 0, 0, 0, 0 },
00234 { 0, 0, 0, 0, 0, 0, 0 },
00235 { 1, 0, 2, 0, 1, 0, 1 },
00236 { 1, 1, 2, 0, 1, 1, 0 },
00237 { 0, 0, 0, 0, 0, 0, 0 },
00238 { 1, 0, 2, 0, 1, 1, 0 },
00239 { 0, 0, 0, 0, 0, 0, 0 },
00240 { 1, 1, 1, 0, 1, 1, 0 },
00241 { 1, 1, 1, 1, 1, 1, 0 },
00242 { 1, 0, 1, 0, 1, 1, 0 },
00243 { 0, 0, 0, 0, 0, 0, 0 },
00244 { 1, 1, 2, 0, 0, 1, 0 },
00245 { 1, 1, 3, 0, 0, 1, 0 },
00246 { 1, 0, 2, 0, 0, 1, 0 },
00247 { 1, 0, 3, 0, 0, 1, 0 },
00248 { 0, 0, 0, 0, 0, 0, 0 },
00249 { 0, 0, 0, 0, 0, 0, 0 },
00250 { 0, 0, 0, 0, 0, 0, 0 },
00251 { 0, 0, 0, 0, 0, 0, 0 }
00252 };
00253
00254 BOOLEAN
00255 KiEmulateReference (
00256 IN OUT PEXCEPTION_RECORD ExceptionRecord,
00257 IN OUT PKEXCEPTION_FRAME ExceptionFrame,
00258 IN OUT PKTRAP_FRAME TrapFrame
00259 )
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
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 }
00752
00753 BOOLEAN
00754 KiEmulateDcbz (
00755 IN OUT PEXCEPTION_RECORD ExceptionRecord,
00756 IN OUT PKEXCEPTION_FRAME ExceptionFrame,
00757 IN OUT PKTRAP_FRAME TrapFrame
00758 )
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784 {
00785
00786 PUCHAR DataAddress;
00787 PVOID ExceptionAddress;
00788
DSISR DsisrValue;
00789 ULONG TableIndex;
00790 ULONG DataRegNum;
00791
ALFAULT Info;
00792
00793
00794
00795
00796
00797
00798 ExceptionAddress = ExceptionRecord->ExceptionAddress;
00799
00800
00801
00802
00803
00804
00805
00806
00807
try {
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 DataAddress = (PUCHAR) (ExceptionRecord->ExceptionInformation[1]);
00819
00820
00821
00822
00823
00824 DsisrValue = *(
DSISR*) &(ExceptionRecord->ExceptionInformation[2]);
00825 TableIndex = DsisrValue.
Index;
00826 DataRegNum = DsisrValue.
DataReg;
00827 Info =
AlFault[TableIndex];
00828
00829
00830
00831
00832
00833
00834
00835
if (Info.
Valid && Info.
Escape && (TableIndex ==
DCBZ_INDEX_VALUE)) {
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 PULONG DcbAddress = (PULONG)((ULONG)DataAddress & ~0x1f);
00849
00850 *DcbAddress++ = 0;
00851 *DcbAddress++ = 0;
00852 *DcbAddress++ = 0;
00853 *DcbAddress++ = 0;
00854 *DcbAddress++ = 0;
00855 *DcbAddress++ = 0;
00856 *DcbAddress++ = 0;
00857 *DcbAddress++ = 0;
00858
00859
00860
00861
00862
00863 TrapFrame->Iar += 4;
00864
00865
return TRUE;
00866 }
00867
00868
00869
00870
00871
00872
00873 } except (
KiCopyInformation(ExceptionRecord,
00874 (GetExceptionInformation())->ExceptionRecord)) {
00875
00876
00877
00878
00879
00880 ExceptionRecord->ExceptionAddress = ExceptionAddress;
00881 }
00882
00883
00884
00885
00886
00887
return FALSE;
00888 }