Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

debug.c File Reference

#include "ki.h"

Go to the source code of this file.

Defines

#define IDBG   1
#define FrozenState(a)   (a & 0xF)
#define RUNNING   0x00
#define TARGET_FROZEN   0x02
#define TARGET_THAW   0x03
#define FREEZE_OWNER   0x04
#define FREEZE_ACTIVE   0x20

Functions

BOOLEAN KeFreezeExecution (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
VOID KiFreezeTargetExecution (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
KCONTINUE_STATUS KeSwitchFrozenProcessor (IN ULONG ProcessorNumber)
VOID KeThawExecution (IN BOOLEAN Enable)
VOID KeReturnToFirmware (IN FIRMWARE_REENTRY Routine)
VOID KiPollFreezeExecution (VOID)

Variables

KIRQL KiOldIrql
PKPRCB KiFreezeOwner


Define Documentation

#define FREEZE_ACTIVE   0x20
 

Definition at line 39 of file ke/debug.c.

Referenced by KeFreezeExecution(), KeSwitchFrozenProcessor(), and KiFreezeTargetExecution().

#define FREEZE_OWNER   0x04
 

Definition at line 36 of file ke/debug.c.

Referenced by KeFreezeExecution(), and KeSwitchFrozenProcessor().

#define FrozenState  )     (a & 0xF)
 

Definition at line 30 of file ke/debug.c.

Referenced by KeFreezeExecution(), KeSwitchFrozenProcessor(), KeThawExecution(), and KiFreezeTargetExecution().

#define IDBG   1
 

Definition at line 27 of file ke/debug.c.

#define RUNNING   0x00
 

Definition at line 33 of file ke/debug.c.

Referenced by KeThawExecution(), and KiFreezeTargetExecution().

#define TARGET_FROZEN   0x02
 

Definition at line 34 of file ke/debug.c.

Referenced by KeFreezeExecution(), KeSwitchFrozenProcessor(), KeThawExecution(), and KiFreezeTargetExecution().

#define TARGET_THAW   0x03
 

Definition at line 35 of file ke/debug.c.

Referenced by KeThawExecution().


Function Documentation

BOOLEAN KeFreezeExecution IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame
 

Definition at line 55 of file ke/debug.c.

References ClearMember, Count, FALSE, FREEZE_ACTIVE, FREEZE_BACKUP, FREEZE_FROZEN, FREEZE_OWNER, FREEZE_SKIPPED_PROCESSOR, FrozenState, HIGH_LEVEL, IPI_FREEZE, KeActiveProcessors, KeFindFirstSetRightMember, KeGetCurrentPrcb, KeRaiseIrql(), KeStallExecutionProcessor(), KiDisableInterrupts(), KiFreezeExecutionLock, KiFreezeFlag, KiFreezeLockBackup, KiFreezeOwner, KiIpiSend(), KiIpiServiceRoutine(), KiOldIrql, KiProcessorBlock, KiRestoreInterrupts(), KiTryToAcquireSpinLock(), TARGET_FROZEN, and TRUE.

Referenced by KdEnterDebugger().

00062 : 00063 00064 This function freezes the execution of all other processors in the host 00065 configuration and then returns to the caller. 00066 00067 Arguments: 00068 00069 TrapFrame - Supplies a pointer to a trap frame that describes the 00070 trap. 00071 00072 ExceptionFrame - Supplies a pointer to an exception frame that 00073 describes the trap. 00074 00075 Return Value: 00076 00077 Previous interrupt enable. 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 // Disable interrupts. 00102 // 00103 00104 Enable = KiDisableInterrupts(); 00105 KiFreezeFlag = FREEZE_FROZEN; 00106 00107 #if !defined(NT_UP) 00108 // 00109 // Raise IRQL to HIGH_LEVEL. 00110 // 00111 00112 KeRaiseIrql(HIGH_LEVEL, &OldIrql); 00113 00114 if (FrozenState(KeGetCurrentPrcb()->IpiFrozen) == FREEZE_OWNER) { 00115 // 00116 // This processor already owns the freeze lock. 00117 // Return without trying to re-acquire lock or without 00118 // trying to IPI the other processors again 00119 // 00120 00121 return Enable; 00122 } 00123 00124 00125 // 00126 // Try to acquire the KiFreezeExecutionLock before sending the request. 00127 // To prevent deadlock from occurring, we need to accept and process 00128 // incoming FreexeExecution requests while we are waiting to acquire 00129 // the FreezeExecutionFlag. 00130 // 00131 00132 while (KiTryToAcquireSpinLock (&KiFreezeExecutionLock) == FALSE) { 00133 00134 // 00135 // FreezeExecutionLock is busy. Another processor may be trying 00136 // to IPI us - go service any IPI. 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 // After acquiring the lock flag, we send Freeze request to each processor 00165 // in the system (other than us) and wait for it to become frozen. 00166 // 00167 00168 Prcb = KeGetCurrentPrcb(); // Do this after spinlock is acquired. 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 // Save the old IRQL and return whether interrupts were previous enabled. 00210 // 00211 00212 KiOldIrql = OldIrql; 00213 00214 #endif // !defined(NT_UP) 00215 00216 return Enable; 00217 }

VOID KeReturnToFirmware IN FIRMWARE_REENTRY  Routine  ) 
 

Definition at line 499 of file ke/debug.c.

References FIRMWARE_REENTRY, and HalReturnToFirmware().

Referenced by IoWriteCrashDump().

00505 : 00506 00507 This routine will thaw all other processors in an MP environment to cause 00508 them to return to do a return to firmware with the supplied parameter. 00509 00510 It will then call HalReturnToFirmware itself. 00511 00512 N.B. It is assumed that we are in the environment of the kernel debugger 00513 or a crash dump. 00514 00515 00516 Arguments: 00517 00518 Routine - What to invoke on return to firmware. 00519 00520 Return Value: 00521 00522 None. 00523 00524 --*/ 00525 00526 { 00527 00528 // 00529 // Just get the interface in now. When intel and kenr come up with the 00530 // right stuff we can fill this in. 00531 // 00532 00533 HalReturnToFirmware(Routine); 00534 00535 }

KCONTINUE_STATUS KeSwitchFrozenProcessor IN ULONG  ProcessorNumber  ) 
 

Definition at line 334 of file ke/debug.c.

References ContinueError, ContinueNextProcessor, ContinueProcessorReselected, FREEZE_ACTIVE, FREEZE_OWNER, FrozenState, KeGetCurrentPrcb, KeNumberProcessors, KiProcessorBlock, and TARGET_FROZEN.

Referenced by KdpSendWaitContinue().

00337 { 00338 #if !defined(NT_UP) 00339 PKPRCB TargetPrcb, CurrentPrcb; 00340 00341 // 00342 // If Processor number is out of range, reselect current processor 00343 // 00344 00345 if (ProcessorNumber >= (ULONG) KeNumberProcessors) { 00346 return ContinueProcessorReselected; 00347 } 00348 00349 TargetPrcb = KiProcessorBlock[ProcessorNumber]; 00350 CurrentPrcb = KeGetCurrentPrcb(); 00351 00352 // 00353 // Move active flag to correct processor. 00354 // 00355 00356 CurrentPrcb->IpiFrozen &= ~FREEZE_ACTIVE; 00357 TargetPrcb->IpiFrozen |= FREEZE_ACTIVE; 00358 00359 // 00360 // If this processor is frozen in KiFreezeTargetExecution, return to it 00361 // 00362 00363 if (FrozenState(CurrentPrcb->IpiFrozen) == TARGET_FROZEN) { 00364 return ContinueNextProcessor; 00365 } 00366 00367 // 00368 // This processor must be FREEZE_OWNER, wait to be reselected as the 00369 // active processor 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 // Reselect this processor 00384 // 00385 00386 return ContinueProcessorReselected; 00387 }

VOID KeThawExecution IN BOOLEAN  Enable  ) 
 

Definition at line 391 of file ke/debug.c.

References ClearMember, FREEZE_BACKUP, FrozenState, KeActiveProcessors, KeFindFirstSetRightMember, KeFlushCurrentTb(), KeGetCurrentPrcb, KeLowerIrql(), KiFreezeExecutionLock, KiFreezeFlag, KiFreezeLockBackup, KiOldIrql, KiProcessorBlock, KiRestoreInterrupts(), RUNNING, TARGET_FROZEN, and TARGET_THAW.

Referenced by KdExitDebugger().

00397 : 00398 00399 This function thaws the execution of all other processors in the host 00400 configuration and then returns to the caller. It is intended for use by 00401 the kernel debugger. 00402 00403 Arguments: 00404 00405 Enable - Supplies the previous interrupt enable that is to be restored 00406 after having thawed the execution of all other processors. 00407 00408 Return Value: 00409 00410 None. 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 // Before releasing FreezeExecutionLock clear any all targets IpiFrozen 00425 // flag. 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 // If the target processor was not forzen, then don't wait 00438 // for target to unfreeze. 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 // Capture the previous IRQL before releasing the freeze lock. 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 // Flush the current TB, instruction cache, and data cache. 00481 // 00482 00483 KeFlushCurrentTb(); 00484 KeSweepCurrentIcache(); 00485 KeSweepCurrentDcache(); 00486 00487 // 00488 // Lower IRQL and restore interrupt enable 00489 // 00490 00491 #if !defined(NT_UP) 00492 KeLowerIrql(OldIrql); 00493 #endif 00494 KiRestoreInterrupts(Enable); 00495 return; 00496 }

VOID KiFreezeTargetExecution IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame
 

Definition at line 220 of file ke/debug.c.

References ContinueError, ContinueNextProcessor, FALSE, FREEZE_ACTIVE, FrozenState, HIGH_LEVEL, KCONTINUE_STATUS, KeFlushCurrentTb(), KeGetCurrentPrcb, KeLowerIrql(), KeRaiseIrql(), KiDebugSwitchRoutine, KiDisableInterrupts(), KiFreezeOwner, KiRestoreInterrupts(), KiRestoreProcessorState(), KiSaveProcessorState(), NULL, RUNNING, Status, TARGET_FROZEN, and TRUE.

Referenced by KiIpiServiceRoutine(), and KiPollFreezeExecution().

00227 : 00228 00229 This function freezes the execution of the current running processor. 00230 If a trapframe is supplied to current state is saved into the prcb 00231 for the debugger. 00232 00233 Arguments: 00234 00235 TrapFrame - Supplies a pointer to the trap frame that describes the 00236 trap. 00237 00238 ExceptionFrame - Supplies a pointer to the exception frame that 00239 describes the trap. 00240 00241 Return Value: 00242 00243 None. 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 // Sweep the data cache in case this is a system crash and the bug 00270 // check code is attempting to write a crash dump file. 00271 // 00272 00273 KeSweepCurrentDcache(); 00274 00275 // 00276 // Wait for person requesting us to freeze to 00277 // clear our frozen flag 00278 // 00279 00280 while (FrozenState(Prcb->IpiFrozen) == TARGET_FROZEN) { 00281 if (Prcb->IpiFrozen & FREEZE_ACTIVE) { 00282 00283 // 00284 // This processor has been made the active processor 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 // If status is anything other then, continue with next 00305 // processor then reselect master 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 }

VOID KiPollFreezeExecution VOID   ) 
 

Definition at line 538 of file ke/debug.c.

References IPI_FREEZE, KeGetCurrentPrcb, KiFreezeTargetExecution(), and NULL.

Referenced by KiCalibrateTimeAdjustment().

00544 : 00545 00546 This routine is called from code that is spinning with interrupts 00547 disabled, waiting for something to happen, when there is some 00548 (possibly extremely small) chance that that thing will not happen 00549 because a system freeze has been initiated. 00550 00551 N.B. Interrupts are disabled. 00552 00553 Arguments: 00554 00555 None. 00556 00557 Return Value: 00558 00559 None. 00560 00561 --*/ 00562 00563 { 00564 // 00565 // Check to see if a freeze is pending for this processor. 00566 // 00567 00568 PKPRCB Prcb = KeGetCurrentPrcb(); 00569 00570 if ((Prcb->RequestSummary & IPI_FREEZE) != 0) { 00571 00572 // 00573 // Clear the freeze request and freeze this processor. 00574 // 00575 00576 InterlockedExchangeAdd((PLONG)&Prcb->RequestSummary, -(IPI_FREEZE)); 00577 KiFreezeTargetExecution(NULL, NULL); 00578 00579 } else { 00580 00581 // 00582 // No freeze pending, assume this processor is spinning. 00583 // 00584 00585 KeYieldProcessor(); 00586 } 00587 } }


Variable Documentation

PKPRCB KiFreezeOwner
 

Definition at line 49 of file ke/debug.c.

Referenced by KeFreezeExecution(), and KiFreezeTargetExecution().

KIRQL KiOldIrql
 

Definition at line 46 of file ke/debug.c.

Referenced by KeFreezeExecution(), and KeThawExecution().


Generated on Sat May 15 19:43:25 2004 for test by doxygen 1.3.7