00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#ifndef _PPCH_
00024
#define _PPCH_
00025
00026
00027
00028
#if defined(_PPC_)
00029
00030
00031
00032
00033
00034
#define FLUSH_MULTIPLE_MAXIMUM 48
00035
00036
00037
00038
00039
00040
00041
#define ALLOC_PRAGMA 1
00042
00043
00044
00045
00046
00047
00048
00049
00050
#if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_)
00051
00052
#define NTKERNELAPI DECLSPEC_IMPORT // wdm
00053
00054
#else
00055
00056
#define NTKERNELAPI
00057
00058
#endif
00059
00060
00061
00062
00063
00064
00065
#if !defined(_NTHAL_)
00066
00067
#define NTHALAPI DECLSPEC_IMPORT // wdm
00068
00069
#else
00070
00071
#define NTHALAPI
00072
00073
#endif
00074
00075
00076
00077
00078
00079
00080
#define IMPORT_NAME(name) __imp_##name
00081
00082
00083
00084
00085
00086
00087
00088
00089
#define RESULT_ZERO 0
00090
#define RESULT_NEGATIVE -2
00091
#define RESULT_POSITIVE -1
00092
00093
00094
00095
00096
00097
00098
typedef enum _INTERLOCKED_RESULT {
00099 ResultNegative = RESULT_NEGATIVE,
00100 ResultZero = RESULT_ZERO,
00101 ResultPositive = RESULT_POSITIVE
00102 } INTERLOCKED_RESULT;
00103
00104
00105
00106
00107
00108
00109
#define ExInterlockedIncrementLong(Addend, Lock) \
00110
ExPpcInterlockedIncrementLong(Addend)
00111
00112
#define ExInterlockedDecrementLong(Addend, Lock) \
00113
ExPpcInterlockedDecrementLong(Addend)
00114
00115
#define ExInterlockedExchangeUlong(Target, Value, Lock) \
00116
ExPpcInterlockedExchangeUlong(Target, Value)
00117
00118
NTKERNELAPI
00119 INTERLOCKED_RESULT
00120 ExPpcInterlockedIncrementLong (
00121 IN PLONG Addend
00122 );
00123
00124
NTKERNELAPI
00125 INTERLOCKED_RESULT
00126 ExPpcInterlockedDecrementLong (
00127 IN PLONG Addend
00128 );
00129
00130
NTKERNELAPI
00131 LARGE_INTEGER
00132 ExInterlockedExchangeAddLargeInteger (
00133 IN PLARGE_INTEGER Addend,
00134 IN LARGE_INTEGER Increment,
00135 IN PKSPIN_LOCK Lock
00136 );
00137
00138
NTKERNELAPI
00139 ULONG
00140 ExPpcInterlockedExchangeUlong (
00141 IN PULONG Target,
00142 IN ULONG Value
00143 );
00144
00145
00146
00147
00148
00149
00150
00151
#if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000) && !defined(RC_INVOKED)
00152
00153
#define InterlockedIncrement _InterlockedIncrement
00154
#define InterlockedDecrement _InterlockedDecrement
00155
#define InterlockedExchange _InterlockedExchange
00156
#define InterlockedExchangeAdd _InterlockedExchangeAdd
00157
#define InterlockedCompareExchange _InterlockedCompareExchange
00158
00159 LONG
00160 InterlockedIncrement(
00161 IN OUT PLONG Addend
00162 );
00163
00164 LONG
00165 InterlockedDecrement(
00166 IN OUT PLONG Addend
00167 );
00168
00169 LONG
00170 InterlockedExchange(
00171 IN OUT PLONG Target,
00172 IN LONG Increment
00173 );
00174
00175 LONG
00176 InterlockedExchangeAdd(
00177 IN OUT PLONG Addend,
00178 IN LONG Value
00179 );
00180
00181 PVOID
00182 InterlockedCompareExchange (
00183 IN OUT PVOID *Destination,
00184 IN PVOID Exchange,
00185 IN PVOID Comperand
00186 );
00187
00188
#pragma intrinsic(_InterlockedIncrement)
00189
#pragma intrinsic(_InterlockedDecrement)
00190
#pragma intrinsic(_InterlockedExchange)
00191
#pragma intrinsic(_InterlockedExchangeAdd)
00192
#pragma intrinsic(_InterlockedCompareExchange)
00193
00194
#else
00195
00196
NTKERNELAPI
00197 LONG
00198 InterlockedIncrement(
00199 IN OUT PLONG Addend
00200 );
00201
00202
NTKERNELAPI
00203 LONG
00204 InterlockedDecrement(
00205 IN OUT PLONG Addend
00206 );
00207
00208
NTKERNELAPI
00209 LONG
00210 InterlockedExchange(
00211 IN OUT PLONG Target,
00212 IN LONG Increment
00213 );
00214
00215
NTKERNELAPI
00216 LONG
00217 InterlockedExchangeAdd(
00218 IN OUT PLONG Addend,
00219 IN LONG Value
00220 );
00221
00222
NTKERNELAPI
00223 PVOID
00224 InterlockedCompareExchange (
00225 IN OUT PVOID *Destination,
00226 IN PVOID Exchange,
00227 IN PVOID Comperand
00228 );
00229
00230
#endif
00231
00232
00233
00234
00235
00236
00237
00238
#define DISPATCH_LENGTH 4 // Length of dispatch code in instructions
00239
00240
00241
00242
00243
00244
#define PASSIVE_LEVEL 0 // Passive release level
00245
#define LOW_LEVEL 0 // Lowest interrupt level
00246
#define APC_LEVEL 1 // APC interrupt level
00247
#define DISPATCH_LEVEL 2 // Dispatcher level
00248
#define PROFILE_LEVEL 27 // Profiling level
00249
#define IPI_LEVEL 29 // Interprocessor interrupt level
00250
#define POWER_LEVEL 30 // Power failure level
00251
#define FLOAT_LEVEL 31 // Floating interrupt level
00252
#define HIGH_LEVEL 31 // Highest interrupt level
00253
#define SYNCH_LEVEL DISPATCH_LEVEL // Synchronization level
00254
00255
00256
00257
00258
00259
00260
#define DEFAULT_PROFILE_COUNT 0x40000000 // ~= 20 seconds @50mhz
00261
#define DEFAULT_PROFILE_INTERVAL (10 * 500) // 500 microseconds
00262
#define MAXIMUM_PROFILE_INTERVAL (10 * 1000 * 1000) // 1 second
00263
#define MINIMUM_PROFILE_INTERVAL (10 * 40) // 40 microseconds
00264
00265
00266
00267
#define KiSynchIrql SYNCH_LEVEL // enable portable code
00268
#define KiProfileIrql PROFILE_LEVEL // enable portable code
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
extern ULONG KiInterruptTemplate[];
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
#define SANITIZE_FPSCR(fpscr, mode) (fpscr)
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
#define SANITIZE_MSR(msr, mode) \
00329
((mode) == KernelMode ? \
00330
((0x00010001L) | ((msr) & 0x0007FF77L)) : \
00331
((0x0001F033L) | ((msr) & 0x0001FF37L)))
00332
00333
00334
00335
00336
00337
00338
#define MAXIMUM_VECTOR 256
00339
00340
00341
00342
00343
00344
00345
00346
00347
#define PCR_MINOR_VERSION 1
00348
#define PCR_MAJOR_VERSION 1
00349
00350
typedef struct _KPCR {
00351
00352
00353
00354
00355
00356
USHORT MinorVersion;
00357
USHORT MajorVersion;
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR];
00368 ULONG PcrPage2;
00369 ULONG Kseg0Top;
00370 ULONG Spare7[30];
00371
00372
00373
00374
00375
00376 ULONG FirstLevelDcacheSize;
00377 ULONG FirstLevelDcacheFillSize;
00378 ULONG FirstLevelIcacheSize;
00379 ULONG FirstLevelIcacheFillSize;
00380 ULONG SecondLevelDcacheSize;
00381 ULONG SecondLevelDcacheFillSize;
00382 ULONG SecondLevelIcacheSize;
00383 ULONG SecondLevelIcacheFillSize;
00384
00385
00386
00387
00388
00389
struct _KPRCB *Prcb;
00390
00391
00392
00393
00394
00395
00396 PVOID Teb;
00397
00398
00399
00400
00401
00402
00403
00404 ULONG DcacheAlignment;
00405 ULONG DcacheFillSize;
00406
00407
00408
00409
00410
00411
00412
00413 ULONG IcacheAlignment;
00414 ULONG IcacheFillSize;
00415
00416
00417
00418
00419
00420 ULONG ProcessorVersion;
00421 ULONG ProcessorRevision;
00422
00423
00424
00425
00426
00427 ULONG ProfileInterval;
00428 ULONG ProfileCount;
00429
00430
00431
00432
00433
00434 ULONG StallExecutionCount;
00435 ULONG StallScaleFactor;
00436
00437
00438
00439
00440
00441 ULONG Spare;
00442
00443
00444
00445
00446
00447
00448
union {
00449 ULONG CachePolicy;
00450
struct {
00451 UCHAR IcacheMode;
00452 UCHAR DcacheMode;
00453
USHORT ModeSpare;
00454 };
00455 };
00456
00457
00458
00459
00460
00461 UCHAR IrqlMask[32];
00462 UCHAR IrqlTable[9];
00463
00464
00465
00466
00467
00468 UCHAR CurrentIrql;
00469
00470
00471
00472
00473 CCHAR Number;
00474 KAFFINITY
SetMember;
00475
00476
00477
00478
00479
00480 ULONG ReservedVectors;
00481
00482
00483
00484
00485
00486
struct _KTHREAD *CurrentThread;
00487
00488
00489
00490
00491
00492
00493 ULONG AlignedCachePolicy;
00494
00495
00496
00497
00498
union {
00499 ULONG SoftwareInterrupt;
00500
struct {
00501 UCHAR ApcInterrupt;
00502 UCHAR DispatchInterrupt;
00503 UCHAR
Spare4;
00504 UCHAR
Spare5;
00505 };
00506 };
00507
00508
00509
00510
00511
00512 KAFFINITY NotMember;
00513
00514
00515
00516
00517
00518 ULONG SystemReserved[16];
00519
00520
00521
00522
00523
00524 ULONG HalReserved[16];
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 ULONG FirstLevelActive;
00542
00543
00544
00545
00546
00547 ULONG SystemServiceDispatchStart;
00548 ULONG SystemServiceDispatchEnd;
00549
00550
00551
00552
00553
00554 ULONG InterruptStack;
00555
00556
00557
00558
00559
00560 ULONG QuantumEnd;
00561
00562
00563
00564
00565
00566 PVOID InitialStack;
00567 PVOID PanicStack;
00568 ULONG BadVaddr;
00569 PVOID StackLimit;
00570 PVOID SavedStackLimit;
00571 ULONG SavedV0;
00572 ULONG SavedV1;
00573 UCHAR DebugActive;
00574 UCHAR
Spare6[3];
00575
00576
00577
00578
00579 ULONG GprSave[6];
00580
00581
00582
00583
00584
00585 ULONG SiR0;
00586 ULONG SiR2;
00587 ULONG SiR3;
00588 ULONG SiR4;
00589 ULONG SiR5;
00590
00591 ULONG Spare0;
00592 ULONG Spare8;
00593
00594
00595
00596
00597
00598
00599
00600 ULONG PgDirRa;
00601
00602
00603
00604
00605
00606 ULONG OnInterruptStack;
00607 ULONG SavedInitialStack;
00608
00609 } KPCR, *PKPCR;
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 KPCR * KiGetPcr(VOID);
00626
00627
00628
00629
#define KIPCR2 0xffffe000 // kernel address of second PCR
00630
#define KI_USER_SHARED_DATA KIPCR2
00631
#define SharedUserData ((KUSER_SHARED_DATA * const)KIPCR2)
00632
00633
00634
00635
#define KIPCR 0xffffd000 // kernel address of first PCR
00636
00637
#define PCR ((volatile KPCR * const)KIPCR)
00638
00639
#if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000)
00640
unsigned __sregister_get(
unsigned const regnum );
00641
#define _PPC_SPRG1_ 273
00642
#define PCRsprg1 ((volatile KPCR * volatile)__sregister_get(_PPC_SPRG1_))
00643
#else
00644
KPCR * __builtin_get_sprg1(VOID);
00645
#define PCRsprg1 ((volatile KPCR * volatile)__builtin_get_sprg1())
00646
#endif
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
#if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000)
00662
00663
unsigned __sregister_get(
unsigned const regnum );
00664
void __sregister_set(
unsigned const regnum,
unsigned value );
00665
#define _PPC_MSR_ (unsigned)(~0x0)
00666
#define _enable() (__sregister_set(_PPC_MSR_, __sregister_get(_PPC_MSR_) | 0x00008000), __emit(0x4C000382))
00667
#define _disable() (__sregister_set(_PPC_MSR_, __sregister_get(_PPC_MSR_) & 0xffff7fff), __emit(0x4C000382))
00668
#define __builtin_get_msr() __sregister_get(_PPC_MSR_)
00669
00670
#else
00671
00672 ULONG __builtin_get_msr(VOID);
00673
VOID __builtin_set_msr(ULONG);
00674
#define _enable() (__builtin_set_msr(__builtin_get_msr() | 0x00008000), __builtin_isync())
00675
#define _disable() (__builtin_set_msr(__builtin_get_msr() & 0xffff7fff), __builtin_isync())
00676
00677
#endif
00678
00679
00680
00681
00682
00683
#define KeGetCurrentIrql() PCR->CurrentIrql
00684
00685
00686
00687
00688
00689
#define KeGetCurrentPrcb() PCR->Prcb
00690
00691
00692
00693
00694
00695
#define KeGetPcr() PCR
00696
00697
00698
00699
00700
00701
#define KeGetCurrentThread() PCR->CurrentThread
00702
00703
00704
00705
00706
00707
#if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000)
00708
unsigned __sregister_get(
unsigned const regnum );
00709
#define _PPC_PVR_ 287
00710
#define KeGetPvr() __sregister_get(_PPC_PVR_)
00711
#else
00712
ULONG __builtin_get_pvr(VOID);
00713
#define KeGetPvr() __builtin_get_pvr()
00714
#endif
00715
00716
00717
00718
00719
00720
00721
#define KeGetCurrentProcessorNumber() PCR->Number
00722
00723
00724
00725
00726
00727
00728
00729
#define KeGetDcacheFillSize() PCR->DcacheFillSize
00730
00731
00732
00733
00734
00735
00736
00737
#define KeGetPreviousMode() (KPROCESSOR_MODE)PCR->CurrentThread->PreviousMode
00738
00739
00740
00741
00742
00743 BOOLEAN
00744 KeIsExecutingDpc (
00745 VOID
00746 );
00747
00748
00749
00750
00751
00752
00753
#define KeSaveFloatingPointState(a) STATUS_SUCCESS
00754
#define KeRestoreFloatingPointState(a) STATUS_SUCCESS
00755
00756
00757
00758
00759
00760
00761
00762
00763
NTKERNELAPI
00764
VOID
00765 KeFillEntryTb (
00766 IN HARDWARE_PTE Pte[2],
00767 IN PVOID Virtual,
00768 IN BOOLEAN Invalid
00769 );
00770
00771
00772
00773
00774
00775
00776
NTKERNELAPI
00777
VOID
00778
KeChangeColorPage (
00779 IN PVOID NewColor,
00780 IN PVOID OldColor,
00781 IN ULONG PageFrame
00782 );
00783
00784
NTKERNELAPI
00785
VOID
00786
KeSweepDcache (
00787 IN BOOLEAN AllProcessors
00788 );
00789
00790
#define KeSweepCurrentDcache() \
00791
HalSweepDcache();
00792
00793
NTKERNELAPI
00794
VOID
00795
KeSweepIcache (
00796 IN BOOLEAN AllProcessors
00797 );
00798
00799
#define KeSweepCurrentIcache() \
00800
HalSweepIcache(); \
00801
HalSweepDcache();
00802
00803
NTKERNELAPI
00804
VOID
00805
KeSweepIcacheRange (
00806 IN BOOLEAN AllProcessors,
00807 IN PVOID BaseAddress,
00808 IN ULONG Length
00809 );
00810
00811
00812
00813
00814
00815
00816
NTKERNELAPI
00817
VOID
00818
KeFlushIoBuffers (
00819 IN
PMDL Mdl,
00820 IN BOOLEAN ReadOperation,
00821 IN BOOLEAN DmaOperation
00822 );
00823
00824
00825
00826
00827
00828
00829
00830
struct _KEXCEPTION_FRAME;
00831
struct _KTRAP_FRAME;
00832
00833
NTKERNELAPI
00834
VOID
00835 KeIpiInterrupt (
00836 IN
struct _KTRAP_FRAME *TrapFrame
00837 );
00838
00839
NTKERNELAPI
00840
VOID
00841
KeProfileInterrupt (
00842 IN
struct _KTRAP_FRAME *TrapFrame
00843 );
00844
00845
NTKERNELAPI
00846
VOID
00847
KeProfileInterruptWithSource (
00848 IN
struct _KTRAP_FRAME *TrapFrame,
00849 IN KPROFILE_SOURCE ProfileSource
00850 );
00851
00852
NTKERNELAPI
00853
VOID
00854
KeUpdateRunTime (
00855 IN
struct _KTRAP_FRAME *TrapFrame
00856 );
00857
00858
NTKERNELAPI
00859
VOID
00860
KeUpdateSystemTime (
00861 IN
struct _KTRAP_FRAME *TrapFrame,
00862 IN ULONG TimeIncrement
00863 );
00864
00865
00866
00867
00868
00869
00870
#if defined(NT_UP)
00871
00872
#define KiAcquireSpinLock(SpinLock)
00873
00874
#else
00875
00876
NTKERNELAPI
00877
VOID
00878 KiAcquireSpinLock (
00879 IN PKSPIN_LOCK SpinLock
00880 );
00881
00882
#endif
00883
00884
#if defined(NT_UP)
00885
00886
#define KiReleaseSpinLock(SpinLock)
00887
00888
#else
00889
00890
NTKERNELAPI
00891
VOID
00892 KiReleaseSpinLock (
00893 IN PKSPIN_LOCK SpinLock
00894 );
00895
00896
#endif
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
NTKERNELAPI
00913 KIRQL
00914 KfRaiseIrqlToDpcLevel (
00915 VOID
00916 );
00917
00918
#define KeRaiseIrqlToDpcLevel(OldIrql) (*(OldIrql) = KfRaiseIrqlToDpcLevel())
00919
00920
NTKERNELAPI
00921 KIRQL
00922 KeRaiseIrqlToSynchLevel (
00923 VOID
00924 );
00925
00926
00927
#if defined(NT_UP) && !defined(_NTDDK_) && !defined(_NTIFS_)
00928
#define ExAcquireSpinLock(Lock, OldIrql) KeRaiseIrqlToDpcLevel((OldIrql))
00929
#define ExReleaseSpinLock(Lock, OldIrql) KeLowerIrql((OldIrql))
00930
#define ExAcquireSpinLockAtDpcLevel(Lock)
00931
#define ExReleaseSpinLockFromDpcLevel(Lock)
00932
#else
00933
00934
00935
#define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql))
00936
#define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql))
00937
#define ExAcquireSpinLockAtDpcLevel(Lock) KeAcquireSpinLockAtDpcLevel(Lock)
00938
#define ExReleaseSpinLockFromDpcLevel(Lock) KeReleaseSpinLockFromDpcLevel(Lock)
00939
00940
00941
#endif
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
#if defined(NT_UP) && !DBG
00952
#define ExAcquireFastLock(Lock, OldIrql) _disable()
00953
#else
00954
#define ExAcquireFastLock(Lock, OldIrql) \
00955
ExAcquireSpinLock(Lock, OldIrql)
00956
#endif
00957
00958
#if defined(NT_UP) && !DBG
00959
#define ExReleaseFastLock(Lock, OldIrql) _enable()
00960
#else
00961
#define ExReleaseFastLock(Lock, OldIrql) \
00962
ExReleaseSpinLock(Lock, OldIrql)
00963
#endif
00964
00965
00966
00967
00968
00969
00970
00971
#define KiQuerySystemTime(CurrentTime) \
00972
do { \
00973
(CurrentTime)->HighPart = SharedUserData->SystemTime.High1Time; \
00974
(CurrentTime)->LowPart = SharedUserData->SystemTime.LowPart; \
00975
} while ((CurrentTime)->HighPart != SharedUserData->SystemTime.High2Time)
00976
00977
00978
00979
00980
00981
#if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_)
00982
00983
00984
00985
#define KeQueryTickCount(CurrentCount) { \
00986
PKSYSTEM_TIME _TickCount = *((PKSYSTEM_TIME *)(&KeTickCount)); \
00987
do { \
00988
(CurrentCount)->HighPart = _TickCount->High1Time; \
00989
(CurrentCount)->LowPart = _TickCount->LowPart; \
00990
} while ((CurrentCount)->HighPart != _TickCount->High2Time); \
00991
}
00992
00993
00994
00995
#else
00996
00997
00998
#define KiQueryTickCount(CurrentCount) \
00999
do { \
01000
(CurrentCount)->HighPart = KeTickCount.High1Time; \
01001
(CurrentCount)->LowPart = KeTickCount.LowPart; \
01002
} while ((CurrentCount)->HighPart != KeTickCount.High2Time)
01003
01004
NTKERNELAPI
01005
VOID
01006
KeQueryTickCount (
01007 OUT PLARGE_INTEGER CurrentCount
01008 );
01009
01010
01011
#endif
01012
01013
#define KiQueryLowTickCount() KeTickCount.LowPart
01014
01015
01016
01017
01018
01019
#define KiQueryInterruptTime(CurrentTime) \
01020
do { \
01021
(CurrentTime)->HighPart = SharedUserData->InterruptTime.High1Time; \
01022
(CurrentTime)->LowPart = SharedUserData->InterruptTime.LowPart; \
01023
} while ((CurrentTime)->HighPart != SharedUserData->InterruptTime.High2Time)
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 ULONG
01036
KiEmulateBranch (
01037 IN
struct _KEXCEPTION_FRAME *ExceptionFrame,
01038 IN
struct _KTRAP_FRAME *TrapFrame
01039 );
01040
01041 BOOLEAN
01042
KiEmulateFloating (
01043 IN OUT PEXCEPTION_RECORD ExceptionRecord,
01044 IN OUT
struct _KEXCEPTION_FRAME *ExceptionFrame,
01045 IN OUT
struct _KTRAP_FRAME *TrapFrame
01046 );
01047
01048 BOOLEAN
01049
KiEmulateReference (
01050 IN OUT PEXCEPTION_RECORD ExceptionRecord,
01051 IN OUT
struct _KEXCEPTION_FRAME *ExceptionFrame,
01052 IN OUT
struct _KTRAP_FRAME *TrapFrame
01053 );
01054
01055 ULONG
01056
KiGetRegisterValue (
01057 IN ULONG Register,
01058 IN
struct _KEXCEPTION_FRAME *ExceptionFrame,
01059 IN
struct _KTRAP_FRAME *TrapFrame
01060 );
01061
01062
VOID
01063
KiSetRegisterValue (
01064 IN ULONG Register,
01065 IN ULONG Value,
01066 OUT
struct _KEXCEPTION_FRAME *ExceptionFrame,
01067 OUT
struct _KTRAP_FRAME *TrapFrame
01068 );
01069
01070
VOID
01071
KiRequestSoftwareInterrupt (
01072 ULONG RequestIrql
01073 );
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
#define READ_REGISTER_UCHAR(x) \
01086
*(volatile UCHAR * const)(x)
01087
01088
#define READ_REGISTER_USHORT(x) \
01089
*(volatile USHORT * const)(x)
01090
01091
#define READ_REGISTER_ULONG(x) \
01092
*(volatile ULONG * const)(x)
01093
01094
#define READ_REGISTER_BUFFER_UCHAR(x, y, z) { \
01095
PUCHAR registerBuffer = x; \
01096
PUCHAR readBuffer = y; \
01097
ULONG readCount; \
01098
for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \
01099
*readBuffer = *(volatile UCHAR * const)(registerBuffer); \
01100
} \
01101
}
01102
01103
#define READ_REGISTER_BUFFER_USHORT(x, y, z) { \
01104
PUSHORT registerBuffer = x; \
01105
PUSHORT readBuffer = y; \
01106
ULONG readCount; \
01107
for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \
01108
*readBuffer = *(volatile USHORT * const)(registerBuffer); \
01109
} \
01110
}
01111
01112
#define READ_REGISTER_BUFFER_ULONG(x, y, z) { \
01113
PULONG registerBuffer = x; \
01114
PULONG readBuffer = y; \
01115
ULONG readCount; \
01116
for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \
01117
*readBuffer = *(volatile ULONG * const)(registerBuffer); \
01118
} \
01119
}
01120
01121
#define WRITE_REGISTER_UCHAR(x, y) { \
01122
*(volatile UCHAR * const)(x) = y; \
01123
KeFlushWriteBuffer(); \
01124
}
01125
01126
#define WRITE_REGISTER_USHORT(x, y) { \
01127
*(volatile USHORT * const)(x) = y; \
01128
KeFlushWriteBuffer(); \
01129
}
01130
01131
#define WRITE_REGISTER_ULONG(x, y) { \
01132
*(volatile ULONG * const)(x) = y; \
01133
KeFlushWriteBuffer(); \
01134
}
01135
01136
#define WRITE_REGISTER_BUFFER_UCHAR(x, y, z) { \
01137
PUCHAR registerBuffer = x; \
01138
PUCHAR writeBuffer = y; \
01139
ULONG writeCount; \
01140
for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
01141
*(volatile UCHAR * const)(registerBuffer) = *writeBuffer; \
01142
} \
01143
KeFlushWriteBuffer(); \
01144
}
01145
01146
#define WRITE_REGISTER_BUFFER_USHORT(x, y, z) { \
01147
PUSHORT registerBuffer = x; \
01148
PUSHORT writeBuffer = y; \
01149
ULONG writeCount; \
01150
for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
01151
*(volatile USHORT * const)(registerBuffer) = *writeBuffer; \
01152
} \
01153
KeFlushWriteBuffer(); \
01154
}
01155
01156
#define WRITE_REGISTER_BUFFER_ULONG(x, y, z) { \
01157
PULONG registerBuffer = x; \
01158
PULONG writeBuffer = y; \
01159
ULONG writeCount; \
01160
for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
01161
*(volatile ULONG * const)(registerBuffer) = *writeBuffer; \
01162
} \
01163
KeFlushWriteBuffer(); \
01164
}
01165
01166
01167
#define READ_PORT_UCHAR(x) \
01168
*(volatile UCHAR * const)(x)
01169
01170
#define READ_PORT_USHORT(x) \
01171
*(volatile USHORT * const)(x)
01172
01173
#define READ_PORT_ULONG(x) \
01174
*(volatile ULONG * const)(x)
01175
01176
#define READ_PORT_BUFFER_UCHAR(x, y, z) { \
01177
PUCHAR readBuffer = y; \
01178
ULONG readCount; \
01179
for (readCount = 0; readCount < z; readCount++, readBuffer++) { \
01180
*readBuffer = *(volatile UCHAR * const)(x); \
01181
} \
01182
}
01183
01184
#define READ_PORT_BUFFER_USHORT(x, y, z) { \
01185
PUSHORT readBuffer = y; \
01186
ULONG readCount; \
01187
for (readCount = 0; readCount < z; readCount++, readBuffer++) { \
01188
*readBuffer = *(volatile USHORT * const)(x); \
01189
} \
01190
}
01191
01192
#define READ_PORT_BUFFER_ULONG(x, y, z) { \
01193
PULONG readBuffer = y; \
01194
ULONG readCount; \
01195
for (readCount = 0; readCount < z; readCount++, readBuffer++) { \
01196
*readBuffer = *(volatile ULONG * const)(x); \
01197
} \
01198
}
01199
01200
#define WRITE_PORT_UCHAR(x, y) { \
01201
*(volatile UCHAR * const)(x) = y; \
01202
KeFlushWriteBuffer(); \
01203
}
01204
01205
#define WRITE_PORT_USHORT(x, y) { \
01206
*(volatile USHORT * const)(x) = y; \
01207
KeFlushWriteBuffer(); \
01208
}
01209
01210
#define WRITE_PORT_ULONG(x, y) { \
01211
*(volatile ULONG * const)(x) = y; \
01212
KeFlushWriteBuffer(); \
01213
}
01214
01215
#define WRITE_PORT_BUFFER_UCHAR(x, y, z) { \
01216
PUCHAR writeBuffer = y; \
01217
ULONG writeCount; \
01218
for (writeCount = 0; writeCount < z; writeCount++, writeBuffer++) { \
01219
*(volatile UCHAR * const)(x) = *writeBuffer; \
01220
KeFlushWriteBuffer(); \
01221
} \
01222
}
01223
01224
#define WRITE_PORT_BUFFER_USHORT(x, y, z) { \
01225
PUSHORT writeBuffer = y; \
01226
ULONG writeCount; \
01227
for (writeCount = 0; writeCount < z; writeCount++, writeBuffer++) { \
01228
*(volatile USHORT * const)(x) = *writeBuffer; \
01229
KeFlushWriteBuffer(); \
01230
} \
01231
}
01232
01233
#define WRITE_PORT_BUFFER_ULONG(x, y, z) { \
01234
PULONG writeBuffer = y; \
01235
ULONG writeCount; \
01236
for (writeCount = 0; writeCount < z; writeCount++, writeBuffer++) { \
01237
*(volatile ULONG * const)(x) = *writeBuffer; \
01238
KeFlushWriteBuffer(); \
01239
} \
01240
}
01241
01242
01243
01244
01245
01246
01247
01248
#define DR6_LEGAL 0x0000e00f
01249
01250
#define DR7_LEGAL 0xffff0155
01251
01252
#define DR7_ACTIVE 0x00000055 // If any of these bits are set a debug
01253
01254
01255
#define SANITIZE_DR6(Dr6, mode) ((Dr6 & DR6_LEGAL));
01256
01257
#define SANITIZE_DR7(Dr7, mode) ((Dr7 & DR7_LEGAL));
01258
01259
#define SANITIZE_DRADDR(DrReg, mode) ( \
01260
(mode) == KernelMode ? \
01261
(DrReg): \
01262
(((PVOID)DrReg <= MM_HIGHEST_USER_ADDRESS) ? \
01263
(DrReg): \
01264
(0) \
01265
) \
01266
)
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
#define CR_VOLATILE_FIELDS 0xFF000FFFL
01281
01282
typedef struct _KTRAP_FRAME {
01283
01284 PVOID TrapFrame;
01285
01286 UCHAR OldIrql;
01287 UCHAR PreviousMode;
01288 UCHAR SavedApcStateIndex;
01289 UCHAR SavedKernelApcDisable;
01290
01291
01292
01293
01294 UCHAR ExceptionRecord[(
sizeof(EXCEPTION_RECORD) + 7) & (~7)];
01295
01296 ULONG FILL2;
01297
01298
01299
01300 ULONG Gpr0;
01301 ULONG Gpr1;
01302 ULONG Gpr2;
01303 ULONG Gpr3;
01304 ULONG Gpr4;
01305 ULONG Gpr5;
01306 ULONG Gpr6;
01307 ULONG Gpr7;
01308 ULONG Gpr8;
01309 ULONG Gpr9;
01310 ULONG Gpr10;
01311 ULONG Gpr11;
01312 ULONG Gpr12;
01313
01314
01315
01316 DOUBLE Fpr0;
01317 DOUBLE Fpr1;
01318 DOUBLE Fpr2;
01319 DOUBLE Fpr3;
01320 DOUBLE Fpr4;
01321 DOUBLE Fpr5;
01322 DOUBLE Fpr6;
01323 DOUBLE Fpr7;
01324 DOUBLE Fpr8;
01325 DOUBLE Fpr9;
01326 DOUBLE Fpr10;
01327 DOUBLE Fpr11;
01328 DOUBLE Fpr12;
01329 DOUBLE Fpr13;
01330
01331
01332
01333 DOUBLE Fpscr;
01334
01335
01336
01337 ULONG Cr;
01338
01339 ULONG Xer;
01340 ULONG Msr;
01341 ULONG Iar;
01342 ULONG Lr;
01343 ULONG Ctr;
01344
01345
01346
01347 ULONG Dr0;
01348 ULONG Dr1;
01349 ULONG Dr2;
01350 ULONG Dr3;
01351 ULONG Dr4;
01352 ULONG Dr5;
01353 ULONG Dr6;
01354 ULONG Dr7;
01355
01356 } KTRAP_FRAME, *PKTRAP_FRAME;
01357
01358
#define KTRAP_FRAME_LENGTH ((sizeof(KTRAP_FRAME) + 7) & (~7))
01359
#define KTRAP_FRAME_ALIGN (sizeof(DOUBLE))
01360
#define KTRAP_FRAME_ROUND (KTRAP_FRAME_ALIGN - 1)
01361
01362
01363
01364
01365
01366
01367
01368
01369
typedef struct _KCALLOUT_FRAME {
01370 STACK_FRAME_HEADER Frame;
01371 ULONG CbStk;
01372 ULONG TrFr;
01373 ULONG InStk;
01374 ULONG
TrIar;
01375 ULONG TrToc;
01376 ULONG R3;
01377 ULONG R4;
01378 ULONG Lr;
01379 ULONG Gpr[18];
01380 DOUBLE Fpr[18];
01381 } KCALLOUT_FRAME, *PKCALLOUT_FRAME;
01382
01383
typedef struct _UCALLOUT_FRAME {
01384 STACK_FRAME_HEADER Frame;
01385 PVOID
Buffer;
01386 ULONG Length;
01387 ULONG ApiNumber;
01388 ULONG Lr;
01389 ULONG Toc;
01390 ULONG Pad;
01391 } UCALLOUT_FRAME, *PUCALLOUT_FRAME;
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
typedef struct _KEXCEPTION_FRAME {
01408
01409 ULONG Fill1;
01410
01411 ULONG Gpr13;
01412 ULONG Gpr14;
01413 ULONG Gpr15;
01414 ULONG Gpr16;
01415 ULONG Gpr17;
01416 ULONG Gpr18;
01417 ULONG Gpr19;
01418 ULONG Gpr20;
01419 ULONG Gpr21;
01420 ULONG Gpr22;
01421 ULONG Gpr23;
01422 ULONG Gpr24;
01423 ULONG Gpr25;
01424 ULONG Gpr26;
01425 ULONG Gpr27;
01426 ULONG Gpr28;
01427 ULONG Gpr29;
01428 ULONG Gpr30;
01429 ULONG Gpr31;
01430
01431 DOUBLE Fpr14;
01432 DOUBLE Fpr15;
01433 DOUBLE Fpr16;
01434 DOUBLE Fpr17;
01435 DOUBLE Fpr18;
01436 DOUBLE Fpr19;
01437 DOUBLE Fpr20;
01438 DOUBLE Fpr21;
01439 DOUBLE Fpr22;
01440 DOUBLE Fpr23;
01441 DOUBLE Fpr24;
01442 DOUBLE Fpr25;
01443 DOUBLE Fpr26;
01444 DOUBLE Fpr27;
01445 DOUBLE Fpr28;
01446 DOUBLE Fpr29;
01447 DOUBLE Fpr30;
01448 DOUBLE Fpr31;
01449
01450 } KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
01451
01452
01453
01454
01455
01456
01457
01458
typedef struct _KSWAP_FRAME {
01459 KEXCEPTION_FRAME ExceptionFrame;
01460 ULONG ConditionRegister;
01461 ULONG SwapReturn;
01462 } KSWAP_FRAME, *PKSWAP_FRAME;
01463
01464
01465
01466
01467
01468
01469
01470
typedef struct _KFLOATING_SAVE {
01471 ULONG Reserved;
01472 } KFLOATING_SAVE, *PKFLOATING_SAVE;
01473
01474
01475
01476
01477
01478
01479
#define STK_SLACK_SPACE 232
01480
01481
typedef struct _KEXCEPTION_STACK_FRAME {
01482 STACK_FRAME_HEADER
Header;
01483 ULONG AdditionalParameters[8];
01484 KTRAP_FRAME TrapFrame;
01485 KEXCEPTION_FRAME ExceptionFrame;
01486 PVOID Lr;
01487 PVOID Cr;
01488 UCHAR SlackSpace[STK_SLACK_SPACE];
01489 } KEXCEPTION_STACK_FRAME, *PKEXCEPTION_STACK_FRAME;
01490
01491
01492
01493
01494
#ifdef _PPC_
01495
01496
01497
01498
01499
typedef struct _KSPECIAL_REGISTERS {
01500 ULONG KernelDr0;
01501 ULONG KernelDr1;
01502 ULONG KernelDr2;
01503 ULONG KernelDr3;
01504 ULONG KernelDr4;
01505 ULONG KernelDr5;
01506 ULONG KernelDr6;
01507 ULONG KernelDr7;
01508 ULONG Sprg0;
01509 ULONG Sprg1;
01510 ULONG Sr0;
01511 ULONG Sr1;
01512 ULONG Sr2;
01513 ULONG Sr3;
01514 ULONG Sr4;
01515 ULONG Sr5;
01516 ULONG Sr6;
01517 ULONG Sr7;
01518 ULONG Sr8;
01519 ULONG Sr9;
01520 ULONG Sr10;
01521 ULONG Sr11;
01522 ULONG Sr12;
01523 ULONG Sr13;
01524 ULONG Sr14;
01525 ULONG Sr15;
01526 ULONG DBAT0L;
01527 ULONG DBAT0U;
01528 ULONG DBAT1L;
01529 ULONG DBAT1U;
01530 ULONG DBAT2L;
01531 ULONG DBAT2U;
01532 ULONG DBAT3L;
01533 ULONG DBAT3U;
01534 ULONG IBAT0L;
01535 ULONG IBAT0U;
01536 ULONG IBAT1L;
01537 ULONG IBAT1U;
01538 ULONG IBAT2L;
01539 ULONG IBAT2U;
01540 ULONG IBAT3L;
01541 ULONG IBAT3U;
01542 ULONG Sdr1;
01543 ULONG Reserved[9];
01544 } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
01545
01546
01547
01548
01549
01550
typedef struct _KPROCESSOR_STATE {
01551
struct _CONTEXT ContextFrame;
01552
struct _KSPECIAL_REGISTERS SpecialRegisters;
01553 } KPROCESSOR_STATE, *PKPROCESSOR_STATE;
01554
01555
#endif // _PPC_
01556
01557
01558
01559
01560
01561
01562
#define PRCB_MINOR_VERSION 1
01563
#define PRCB_MAJOR_VERSION 1
01564
#define PRCB_BUILD_DEBUG 0x0001
01565
#define PRCB_BUILD_UNIPROCESSOR 0x0002
01566
01567
struct _RESTART_BLOCK;
01568
01569
typedef struct _KPRCB {
01570
01571
01572
01573
01574
01575
USHORT MinorVersion;
01576
USHORT MajorVersion;
01577
01578
01579
01580
01581
01582
01583
01584
struct _KTHREAD *CurrentThread;
01585
struct _KTHREAD *RESTRICTED_POINTER NextThread;
01586
struct _KTHREAD *IdleThread;
01587 CCHAR Number;
01588 CCHAR Reserved;
01589
USHORT BuildType;
01590 KAFFINITY
SetMember;
01591
struct _RESTART_BLOCK *RestartBlock;
01592 ULONG PcrPage;
01593 ULONG PcrPage2;
01594
01595
01596
01597
01598
01599 ULONG SystemReserved[15];
01600
01601
01602
01603
01604
01605 ULONG HalReserved[16];
01606
01607
01608
01609
01610
01611 ULONG DpcTime;
01612 ULONG InterruptTime;
01613 ULONG KernelTime;
01614 ULONG UserTime;
01615 ULONG AdjustDpcThreshold;
01616 ULONG InterruptCount;
01617 ULONG ApcBypassCount;
01618 ULONG DpcBypassCount;
01619 ULONG
Spare6[5];
01620
01621
01622
01623
01624
01625 PVOID Spare1;
01626 PVOID
Spare2;
01627
volatile ULONG IpiFrozen;
01628
struct _KPROCESSOR_STATE ProcessorState;
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641 PVOID SpareHotData[2];
01642
01643
01644
01645
01646
01647 ULONG
CcFastReadNoWait;
01648 ULONG
CcFastReadWait;
01649 ULONG
CcFastReadNotPossible;
01650 ULONG
CcCopyReadNoWait;
01651 ULONG
CcCopyReadWait;
01652 ULONG
CcCopyReadNoWaitMiss;
01653
01654
01655
01656
01657
01658 ULONG KeAlignmentFixupCount;
01659 ULONG KeContextSwitches;
01660 ULONG
KeDcacheFlushCount;
01661 ULONG KeExceptionDispatchCount;
01662 ULONG KeFirstLevelTbFills;
01663 ULONG KeFloatingEmulationCount;
01664 ULONG
KeIcacheFlushCount;
01665 ULONG KeSecondLevelTbFills;
01666 ULONG KeSystemCalls;
01667
01668 ULONG PagedPoolLookasideHits;
01669
01670
01671
01672
01673
01674 ULONG ReservedCounter[14];
01675
01676
01677
01678
01679
01680
union {
01681 ULONG ReservedPad[16 * 8];
01682 PVOID PagedFreeEntry[
POOL_SMALL_LISTS];
01683 };
01684
01685
01686
01687
01688
01689
01690
01691
volatile PVOID CurrentPacket[3];
01692
volatile KAFFINITY TargetSet;
01693
volatile PKIPI_WORKER WorkerRoutine;
01694 ULONG CachePad1[3];
01695
01696
01697
01698
01699
01700
volatile ULONG RequestSummary;
01701
volatile struct _KPRCB *SignalDone;
01702 ULONG CachePad2[6];
01703
01704
01705
01706
01707
01708 ULONG DpcInterruptRequested;
01709 ULONG CachePad3[7];
01710
01711
01712
01713
01714
01715 ULONG MaximumDpcQueueDepth;
01716 ULONG MinimumDpcRate;
01717
01718
01719
01720
01721
01722 ULONG
Spare4[2];
01723
01724
01725
01726
01727
01728 PVOID SmallIrpFreeEntry;
01729 PVOID LargeIrpFreeEntry;
01730 PVOID MdlFreeEntry;
01731
01732
01733
01734
01735
01736 PVOID CreateInfoFreeEntry;
01737 PVOID NameBufferFreeEntry;
01738
01739
01740
01741
01742
01743 PVOID SharedCacheMapEntry;
01744
01745
01746
01747
01748
01749 ULONG
Spare5[2];
01750
01751
01752
01753
01754
01755
PKIPI_COUNTS IpiCounts;
01756 LARGE_INTEGER StartCount;
01757
01758
01759
01760
01761
01762 KSPIN_LOCK DpcLock;
01763 LIST_ENTRY DpcListHead;
01764 ULONG DpcQueueDepth;
01765 ULONG DpcCount;
01766 ULONG DpcLastCount;
01767 ULONG DpcRequestRate;
01768 ULONG DpcRoutineActive;
01769 BOOLEAN SkipTick;
01770 ULONG CachePad4[5];
01771
01772
01773
01774
01775 PROCESSOR_POWER_STATE PowerState;
01776
01777
01778 } KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB;
01779
01780
01781
01782
01783
01784
01785
#define PAGE_SIZE (ULONG)0x1000
01786
01787
01788
01789
01790
01791
01792
01793
#define PAGE_SHIFT 12L
01794
01795
01796
01797
01798
01799
01800
01801
01802
#define PDI_SHIFT 22
01803
01804
01805
01806
01807
01808
01809
#define PTI_SHIFT 12
01810
01811
01812
01813
01814
01815
01816
01817
01818
#define MM_HIGHEST_USER_ADDRESS (PVOID)0x7FFEFFFF // highest user address
01819
#define MM_SYSTEM_RANGE_START (PVOID)KSEG0_BASE // start of system space
01820
#define MM_USER_PROBE_ADDRESS 0x7FFF0000 // starting address of guard page
01821
01822
01823
01824
01825
01826
extern PVOID
MmHighestUserAddress;
01827
extern PVOID
MmSystemRangeStart;
01828
extern ULONG
MmUserProbeAddress;
01829
01830
01831
01832
01833
01834
#define MM_LOWEST_USER_ADDRESS (PVOID)0x00010000
01835
01836
01837
01838
#define MmGetProcedureAddress(Address) *((PVOID *)(Address))
01839
#define MmLockPagableCodeSection(Address) MmLockPagableDataSection(*((PVOID *)(Address)))
01840
01841
01842
01843
01844
01845
01846
01847
#define PDE_BASE (ULONG)0xC0300000
01848
#define PTE_BASE (ULONG)0xC0000000
01849
01850
01851
01852
01853
01854
01855
#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0x80000000
01856
#define SYSTEM_BASE 0x80000000 // start of system space (no typecast)
01857
01858
01859
#endif // defined(_PPC_)
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870 #define UNCACHED_POLICY 2 // uncached
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880 typedef struct _DSISR {
01881 ULONG
UpdateReg : 5;
01882 ULONG
DataReg : 5;
01883 ULONG
Index : 7;
01884 ULONG
Fill2 : 1;
01885 ULONG
XO : 2;
01886 ULONG
Fill1 : 12;
01887 }
DSISR, *
PDSISR;
01888
01889
DSISR KiGetDsisr ();
01890
void KiSetDsisr (
DSISR Value);
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911 #define KiIsThreadNumericStateSaved(a) TRUE
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922 #define KiRundownThread(a)
01923
01924
01925
01926
01927
01928
01929
01930 #define Isx86FeaturePresent(_f_) TRUE
01931
01932
01933
01934
01935 #define ppc_machine_check 1
01936 #define ppc_data_storage 2
01937 #define ppc_instruction_storage 3
01938 #define ppc_external 4
01939 #define ppc_alignment 5
01940 #define ppc_program 6
01941 #define ppc_fp_unavailable 7
01942 #define ppc_decrementer 8
01943 #define ppc_direct_store_error 9
01944 #define ppc_syscall 10
01945 #define ppc_trace 11
01946 #define ppc_fp_assist 12
01947 #define ppc_run_mode 13
01948
01949
#endif // _PPCH_