TianoCore EDK2 master
Loading...
Searching...
No Matches
DebugMp.c
Go to the documentation of this file.
1
9#include "DebugAgent.h"
10
11GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_MP_CONTEXT volatile mDebugMpContext = { 0, 0, 0, { 0 }, { 0 }, 0, 0, 0, 0, FALSE, FALSE };
12
13GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_CPU_DATA volatile mDebugCpuData = { 0 };
14
24VOID
26 IN OUT SPIN_LOCK *MpSpinLock
27 )
28{
30 return;
31 }
32
33 while (TRUE) {
34 if (AcquireSpinLockOrFail (MpSpinLock)) {
35 break;
36 }
37
38 CpuPause ();
39 continue;
40 }
41}
42
49VOID
51 IN OUT SPIN_LOCK *MpSpinLock
52 )
53{
55 return;
56 }
57
58 ReleaseSpinLock (MpSpinLock);
59}
60
67VOID
69 IN UINT32 CurrentProcessorIndex
70 )
71{
72 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to halt other processors.\n", CurrentProcessorIndex);
73 if (!DebugAgentIsBsp (CurrentProcessorIndex)) {
75 }
76
77 mDebugMpContext.BreakAtCpuIndex = CurrentProcessorIndex;
78
79 //
80 // Set the debug viewpoint to the current breaking CPU.
81 //
82 SetDebugViewPoint (CurrentProcessorIndex);
83
84 //
85 // Send fixed IPI to other processors.
86 //
87 SendFixedIpiAllExcludingSelf (DEBUG_TIMER_VECTOR);
88}
89
96UINT32
98 VOID
99 )
100{
101 UINT32 Index;
102 UINT16 LocalApicID;
103
104 LocalApicID = (UINT16)GetApicId ();
105
106 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
107
108 for (Index = 0; Index < mDebugCpuData.CpuCount; Index++) {
109 if (mDebugCpuData.ApicID[Index] == LocalApicID) {
110 break;
111 }
112 }
113
114 if (Index == mDebugCpuData.CpuCount) {
115 mDebugCpuData.ApicID[Index] = LocalApicID;
116 mDebugCpuData.CpuCount++;
117 }
118
119 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
120
121 return Index;
122}
123
133BOOLEAN
135 IN UINT32 ProcessorIndex
136 )
137{
138 MSR_IA32_APIC_BASE_REGISTER MsrApicBase;
139
140 //
141 // If there are less than 2 CPUs detected, then the currently executing CPU
142 // must be the BSP. This avoids an access to an MSR that may not be supported
143 // on single core CPUs.
144 //
145 if (mDebugCpuData.CpuCount < 2) {
146 return TRUE;
147 }
148
149 MsrApicBase.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
150 if (MsrApicBase.Bits.BSP == 1) {
151 if (mDebugMpContext.BspIndex != ProcessorIndex) {
152 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
153 mDebugMpContext.BspIndex = ProcessorIndex;
154 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
155 }
156
157 return TRUE;
158 } else {
159 return FALSE;
160 }
161}
162
171VOID
173 IN UINT32 ProcessorIndex,
174 IN BOOLEAN StopFlag
175 )
176{
177 UINT8 Value;
178 UINTN Index;
179
180 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
181
182 Value = mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8];
183 Index = ProcessorIndex % 8;
184 if (StopFlag) {
185 Value = BitFieldWrite8 (Value, Index, Index, 1);
186 } else {
187 Value = BitFieldWrite8 (Value, Index, Index, 0);
188 }
189
190 mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8] = Value;
191
192 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
193}
194
203VOID
205 IN UINT32 ProcessorIndex,
206 IN BOOLEAN BreakFlag
207 )
208{
209 UINT8 Value;
210 UINTN Index;
211
212 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
213
214 Value = mDebugMpContext.CpuBreakMask[ProcessorIndex / 8];
215 Index = ProcessorIndex % 8;
216 if (BreakFlag) {
217 Value = BitFieldWrite8 (Value, Index, Index, 1);
218 } else {
219 Value = BitFieldWrite8 (Value, Index, Index, 0);
220 }
221
222 mDebugMpContext.CpuBreakMask[ProcessorIndex / 8] = Value;
223
224 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
225}
226
236BOOLEAN
238 IN UINT32 ProcessorIndex
239 )
240{
241 UINT8 CpuMask;
242
243 CpuMask = (UINT8)(1 << (ProcessorIndex % 8));
244
245 if ((mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8] & CpuMask) != 0) {
246 return TRUE;
247 } else {
248 return FALSE;
249 }
250}
251
259VOID
261 IN BOOLEAN RunningFlag
262 )
263{
264 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
265 mDebugMpContext.RunCommandSet = RunningFlag;
266 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
267}
268
275VOID
277 IN UINT32 ProcessorIndex
278 )
279{
280 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
281 mDebugMpContext.ViewPointIndex = ProcessorIndex;
282 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
283}
284
292VOID
294 IN BOOLEAN IpiSentByApFlag
295 )
296{
297 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
298 mDebugMpContext.IpiSentByAp = IpiSentByApFlag;
299 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
300}
301
310UINT32
312 VOID
313 )
314{
315 UINT32 Index;
316
317 for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index++) {
318 if (mDebugMpContext.CpuBreakMask[Index] != 0) {
319 return (UINT32)LowBitSet32 (mDebugMpContext.CpuBreakMask[Index]) + Index * 8;
320 }
321 }
322
323 return (UINT32)-1;
324}
325
333BOOLEAN
335 VOID
336 )
337{
338 UINTN Index;
339
340 for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index++) {
341 if (mDebugMpContext.CpuStopStatusMask[Index] != 0) {
342 return FALSE;
343 }
344 }
345
346 return TRUE;
347}
348
360BOOLEAN
362 IN UINT32 ProcessorIndex
363 )
364{
366 if (mDebugMpContext.BreakAtCpuIndex != (UINT32)-1) {
367 //
368 // The current processor is not the first breaking one.
369 //
370 SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);
371 return FALSE;
372 } else {
373 //
374 // If no any processor breaks, try to halt other processors
375 //
376 HaltOtherProcessors (ProcessorIndex);
377 return TRUE;
378 }
379 }
380
381 return TRUE;
382}
UINT64 UINTN
INTN EFIAPI LowBitSet32(IN UINT32 Operand)
Definition: LowBitSet32.c:26
VOID EFIAPI CpuPause(VOID)
UINT8 EFIAPI BitFieldWrite8(IN UINT8 Operand, IN UINTN StartBit, IN UINTN EndBit, IN UINT8 Value)
Definition: BitField.c:179
VOID EFIAPI DebugAgentMsgPrint(IN UINT8 ErrorLevel, IN CHAR8 *Format,...)
Definition: DebugAgent.c:518
BOOLEAN MultiProcessorDebugSupport(VOID)
VOID SetCpuStopFlagByIndex(IN UINT32 ProcessorIndex, IN BOOLEAN StopFlag)
Definition: DebugMp.c:172
VOID SetDebugViewPoint(IN UINT32 ProcessorIndex)
Definition: DebugMp.c:276
UINT32 FindNextPendingBreakCpu(VOID)
Definition: DebugMp.c:311
VOID HaltOtherProcessors(IN UINT32 CurrentProcessorIndex)
Definition: DebugMp.c:68
UINT32 GetProcessorIndex(VOID)
Definition: DebugMp.c:97
BOOLEAN IsFirstBreakProcessor(IN UINT32 ProcessorIndex)
Definition: DebugMp.c:361
BOOLEAN DebugAgentIsBsp(IN UINT32 ProcessorIndex)
Definition: DebugMp.c:134
VOID ReleaseMpSpinLock(IN OUT SPIN_LOCK *MpSpinLock)
Definition: DebugMp.c:50
VOID AcquireMpSpinLock(IN OUT SPIN_LOCK *MpSpinLock)
Definition: DebugMp.c:25
VOID SetCpuRunningFlag(IN BOOLEAN RunningFlag)
Definition: DebugMp.c:260
BOOLEAN IsAllCpuRunning(VOID)
Definition: DebugMp.c:334
VOID SetCpuBreakFlagByIndex(IN UINT32 ProcessorIndex, IN BOOLEAN BreakFlag)
Definition: DebugMp.c:204
BOOLEAN IsCpuStopped(IN UINT32 ProcessorIndex)
Definition: DebugMp.c:237
VOID SetIpiSentByApFlag(IN BOOLEAN IpiSentByApFlag)
Definition: DebugMp.c:293
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
Definition: GccInlinePriv.c:60
VOID EFIAPI SendFixedIpiAllExcludingSelf(IN UINT8 Vector)
Definition: BaseXApicLib.c:404
UINT32 EFIAPI GetApicId(VOID)
Definition: BaseXApicLib.c:337
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define MSR_IA32_APIC_BASE
volatile UINTN SPIN_LOCK
SPIN_LOCK *EFIAPI ReleaseSpinLock(IN OUT SPIN_LOCK *SpinLock)
BOOLEAN EFIAPI AcquireSpinLockOrFail(IN OUT SPIN_LOCK *SpinLock)
UINT16 ApicID[DEBUG_CPU_MAX_COUNT]
Record the local apic id for each processor.
Definition: DebugMp.h:16
UINT32 CpuCount
Processor count.
Definition: DebugMp.h:15
UINT32 ViewPointIndex
Current view point to be debugged.
Definition: DebugMp.h:25
SPIN_LOCK MpContextSpinLock
Lock for writing MP context.
Definition: DebugMp.h:20
BOOLEAN IpiSentByAp
TRUE: IPI is sent by AP. FALSE: IPI is sent by BSP.
Definition: DebugMp.h:29
UINT8 CpuBreakMask[DEBUG_CPU_MAX_COUNT/8]
Bitmask of all breaking CPUs.
Definition: DebugMp.h:23
UINT32 BspIndex
Processor index value of BSP.
Definition: DebugMp.h:26
UINT8 CpuStopStatusMask[DEBUG_CPU_MAX_COUNT/8]
Bitmask of CPU stop status.
Definition: DebugMp.h:24
BOOLEAN RunCommandSet
TRUE: RUN command is executing. FALSE: RUN command has been executed.
Definition: DebugMp.h:30
UINT32 BreakAtCpuIndex
Processor index value of the current breaking CPU.
Definition: DebugMp.h:27
struct MSR_IA32_APIC_BASE_REGISTER::@627 Bits