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
#include "ki.h"
00026
00027 #define IDBG 1
00028
00029
00030 #define FrozenState(a) (a & 0xF)
00031
00032
00033 #define RUNNING 0x00
00034 #define TARGET_FROZEN 0x02
00035 #define TARGET_THAW 0x03
00036 #define FREEZE_OWNER 0x04
00037
00038
00039 #define FREEZE_ACTIVE 0x20
00040
00041
00042
00043
00044
00045
00046 KIRQL
KiOldIrql;
00047
00048
#ifndef NT_UP
00049 PKPRCB
KiFreezeOwner;
00050
#endif
00051
00052
00053
00054 BOOLEAN
00055 KeFreezeExecution (
00056 IN PKTRAP_FRAME TrapFrame,
00057 IN PKEXCEPTION_FRAME ExceptionFrame
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 BOOLEAN Enable;
00084
00085
#if !defined(NT_UP)
00086
00087 BOOLEAN Flag;
00088 PKPRCB Prcb;
00089 ULONG TargetSet;
00090 ULONG BitNumber;
00091 KIRQL OldIrql;
00092
00093
#if IDBG
00094
00095 ULONG
Count = 30000;
00096
00097
#endif
00098
#endif
00099
00100
00101
00102
00103
00104 Enable =
KiDisableInterrupts();
00105
KiFreezeFlag =
FREEZE_FROZEN;
00106
00107
#if !defined(NT_UP)
00108
00109
00110
00111
00112
KeRaiseIrql(
HIGH_LEVEL, &OldIrql);
00113
00114
if (
FrozenState(
KeGetCurrentPrcb()->IpiFrozen) ==
FREEZE_OWNER) {
00115
00116
00117
00118
00119
00120
00121
return Enable;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
while (
KiTryToAcquireSpinLock (&
KiFreezeExecutionLock) ==
FALSE) {
00133
00134
00135
00136
00137
00138
00139
KiRestoreInterrupts(Enable);
00140 Flag =
KiIpiServiceRoutine((PVOID)TrapFrame, (PVOID)ExceptionFrame);
00141
KiDisableInterrupts();
00142
00143
#if IDBG
00144
00145
if (Flag !=
FALSE) {
00146
Count = 30000;
00147
continue;
00148 }
00149
00150
KeStallExecutionProcessor (100);
00151
if (!
Count--) {
00152
Count = 30000;
00153
if (
KiTryToAcquireSpinLock (&
KiFreezeLockBackup) ==
TRUE) {
00154
KiFreezeFlag |=
FREEZE_BACKUP;
00155
break;
00156 }
00157 }
00158
00159
#endif
00160
00161 }
00162
00163
00164
00165
00166
00167
00168 Prcb =
KeGetCurrentPrcb();
00169 TargetSet =
KeActiveProcessors & ~(1 << Prcb->Number);
00170
if (TargetSet) {
00171
00172
#if IDBG
00173
Count = 400;
00174
#endif
00175
00176
KiFreezeOwner = Prcb;
00177 Prcb->IpiFrozen =
FREEZE_OWNER |
FREEZE_ACTIVE;
00178 Prcb->SkipTick =
TRUE;
00179
KiIpiSend((KAFFINITY) TargetSet,
IPI_FREEZE);
00180
00181
while (TargetSet != 0) {
00182 BitNumber =
KeFindFirstSetRightMember(TargetSet);
00183
ClearMember(BitNumber, TargetSet);
00184 Prcb =
KiProcessorBlock[BitNumber];
00185
00186
#if IDBG
00187
00188
while (Prcb->IpiFrozen !=
TARGET_FROZEN) {
00189
if (
Count == 0) {
00190
KiFreezeFlag |=
FREEZE_SKIPPED_PROCESSOR;
00191
break;
00192 }
00193
00194
KeStallExecutionProcessor (10000);
00195
Count--;
00196 }
00197
00198
#else
00199
00200
while (Prcb->IpiFrozen !=
TARGET_FROZEN) {
00201 KeYieldProcessor();
00202 }
00203
#endif
00204
00205 }
00206 }
00207
00208
00209
00210
00211
00212
KiOldIrql = OldIrql;
00213
00214
#endif // !defined(NT_UP)
00215
00216
return Enable;
00217 }
00218
00219
VOID
00220 KiFreezeTargetExecution (
00221 IN PKTRAP_FRAME TrapFrame,
00222 IN PKEXCEPTION_FRAME ExceptionFrame
00223 )
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 {
00248
00249
#if !defined(NT_UP)
00250
00251 KIRQL OldIrql;
00252 PKPRCB Prcb;
00253 BOOLEAN Enable;
00254
KCONTINUE_STATUS Status;
00255 EXCEPTION_RECORD ExceptionRecord;
00256
00257 Enable =
KiDisableInterrupts();
00258
KeRaiseIrql(
HIGH_LEVEL, &OldIrql);
00259
00260 Prcb =
KeGetCurrentPrcb();
00261 Prcb->IpiFrozen =
TARGET_FROZEN;
00262 Prcb->SkipTick =
TRUE;
00263
00264
if (TrapFrame !=
NULL) {
00265
KiSaveProcessorState(TrapFrame, ExceptionFrame);
00266 }
00267
00268
00269
00270
00271
00272
00273 KeSweepCurrentDcache();
00274
00275
00276
00277
00278
00279
00280
while (
FrozenState(Prcb->IpiFrozen) ==
TARGET_FROZEN) {
00281
if (Prcb->IpiFrozen &
FREEZE_ACTIVE) {
00282
00283
00284
00285
00286
if (TrapFrame) {
00287 RtlZeroMemory (&ExceptionRecord,
sizeof ExceptionRecord);
00288 ExceptionRecord.ExceptionCode = STATUS_WAKE_SYSTEM_DEBUGGER;
00289 ExceptionRecord.ExceptionRecord = &ExceptionRecord;
00290 ExceptionRecord.ExceptionAddress =
00291 (PVOID)CONTEXT_TO_PROGRAM_COUNTER (&Prcb->ProcessorState.ContextFrame);
00292
00293
Status = (
KiDebugSwitchRoutine) (
00294 &ExceptionRecord,
00295 &Prcb->ProcessorState.ContextFrame,
00296
FALSE
00297 );
00298
00299 }
else {
00300
Status =
ContinueError;
00301 }
00302
00303
00304
00305
00306
00307
00308
if (
Status !=
ContinueNextProcessor) {
00309 Prcb->IpiFrozen &= ~
FREEZE_ACTIVE;
00310
KiFreezeOwner->IpiFrozen |=
FREEZE_ACTIVE;
00311 }
00312 }
00313 KeYieldProcessor();
00314 }
00315
00316
if (TrapFrame !=
NULL) {
00317
KiRestoreProcessorState(TrapFrame, ExceptionFrame);
00318 }
00319
00320 Prcb->IpiFrozen =
RUNNING;
00321
00322
KeFlushCurrentTb();
00323 KeSweepCurrentIcache();
00324
00325
KeLowerIrql(OldIrql);
00326
KiRestoreInterrupts(Enable);
00327
#endif // !define(NT_UP)
00328
00329
return;
00330 }
00331
00332
00333
KCONTINUE_STATUS
00334 KeSwitchFrozenProcessor (
00335 IN ULONG ProcessorNumber
00336 )
00337 {
00338
#if !defined(NT_UP)
00339
PKPRCB TargetPrcb, CurrentPrcb;
00340
00341
00342
00343
00344
00345
if (ProcessorNumber >= (ULONG)
KeNumberProcessors) {
00346
return ContinueProcessorReselected;
00347 }
00348
00349 TargetPrcb =
KiProcessorBlock[ProcessorNumber];
00350 CurrentPrcb =
KeGetCurrentPrcb();
00351
00352
00353
00354
00355
00356 CurrentPrcb->IpiFrozen &= ~
FREEZE_ACTIVE;
00357 TargetPrcb->IpiFrozen |=
FREEZE_ACTIVE;
00358
00359
00360
00361
00362
00363
if (
FrozenState(CurrentPrcb->IpiFrozen) ==
TARGET_FROZEN) {
00364
return ContinueNextProcessor;
00365 }
00366
00367
00368
00369
00370
00371
00372
if (
FrozenState(CurrentPrcb->IpiFrozen) !=
FREEZE_OWNER) {
00373
return ContinueError;
00374 }
00375
00376
while (!(CurrentPrcb->IpiFrozen &
FREEZE_ACTIVE)) {
00377 KeYieldProcessor();
00378 }
00379
00380
#endif // !defined(NT_UP)
00381
00382
00383
00384
00385
00386
return ContinueProcessorReselected;
00387 }
00388
00389
00390
VOID
00391 KeThawExecution (
00392 IN BOOLEAN Enable
00393 )
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 {
00415
#if !defined(NT_UP)
00416
00417 KIRQL OldIrql;
00418 ULONG TargetSet;
00419 ULONG BitNumber;
00420 ULONG Flag;
00421 PKPRCB Prcb;
00422
00423
00424
00425
00426
00427
00428
KeGetCurrentPrcb()->IpiFrozen =
RUNNING;
00429
00430 TargetSet =
KeActiveProcessors & ~(1 <<
KeGetCurrentPrcb()->Number);
00431
while (TargetSet != 0) {
00432 BitNumber =
KeFindFirstSetRightMember(TargetSet);
00433
ClearMember(BitNumber, TargetSet);
00434 Prcb =
KiProcessorBlock[BitNumber];
00435
#if IDBG
00436
00437
00438
00439
00440
00441
if (
FrozenState(Prcb->IpiFrozen) !=
TARGET_FROZEN) {
00442 Prcb->IpiFrozen =
RUNNING;
00443
continue;
00444 }
00445
#endif
00446
00447 Prcb->IpiFrozen =
TARGET_THAW;
00448
while (Prcb->IpiFrozen ==
TARGET_THAW) {
00449 KeYieldProcessor();
00450 }
00451 }
00452
00453
00454
00455
00456
00457 OldIrql =
KiOldIrql;
00458
00459
#if IDBG
00460
00461 Flag =
KiFreezeFlag;
00462
KiFreezeFlag = 0;
00463
00464
if ((Flag &
FREEZE_BACKUP) != 0) {
00465 KiReleaseSpinLock(&
KiFreezeLockBackup);
00466 }
else {
00467 KiReleaseSpinLock(&
KiFreezeExecutionLock);
00468 }
00469
00470
#else
00471
00472
KiFreezeFlag = 0;
00473 KiReleaseSpinLock(&
KiFreezeExecutionLock);
00474
00475
#endif
00476
#endif // !defined (NT_UP)
00477
00478
00479
00480
00481
00482
00483
KeFlushCurrentTb();
00484 KeSweepCurrentIcache();
00485 KeSweepCurrentDcache();
00486
00487
00488
00489
00490
00491
#if !defined(NT_UP)
00492
KeLowerIrql(OldIrql);
00493
#endif
00494
KiRestoreInterrupts(Enable);
00495
return;
00496 }
00497
00498
VOID
00499 KeReturnToFirmware (
00500 IN
FIRMWARE_REENTRY Routine
00501 )
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 {
00527
00528
00529
00530
00531
00532
00533
HalReturnToFirmware(Routine);
00534
00535 }
00536
00537
VOID
00538 KiPollFreezeExecution(
00539 VOID
00540 )
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563 {
00564
00565
00566
00567
00568 PKPRCB Prcb =
KeGetCurrentPrcb();
00569
00570
if ((Prcb->RequestSummary &
IPI_FREEZE) != 0) {
00571
00572
00573
00574
00575
00576 InterlockedExchangeAdd((PLONG)&Prcb->RequestSummary, -(
IPI_FREEZE));
00577
KiFreezeTargetExecution(
NULL,
NULL);
00578
00579 }
else {
00580
00581
00582
00583
00584
00585 KeYieldProcessor();
00586 }
00587 }