2 Multi-Processor support functions implementation.
4 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "DebugAgent.h"
17 DEBUG_MP_CONTEXT
volatile mDebugMpContext
= {0,0,0,0,0,0,0,0,FALSE
,FALSE
};
19 DEBUG_CPU_DATA
volatile mDebugCpuData
= {0};
22 Acquire access control on debug port.
24 It will block in the function if cannot get the access control.
28 AcquireDebugPortControl (
32 if (!MultiProcessorDebugSupport
) {
37 if (AcquireSpinLockOrFail (&mDebugMpContext
.DebugPortSpinLock
)) {
46 Release access control on debug port.
50 ReleaseDebugPortControl (
54 if (!MultiProcessorDebugSupport
) {
58 ReleaseSpinLock (&mDebugMpContext
.DebugPortSpinLock
);
62 Acquire access control on MP context.
64 It will block in the function if cannot get the access control.
68 AcquireMpContextControl (
73 if (AcquireSpinLockOrFail (&mDebugMpContext
.MpContextSpinLock
)) {
82 Release access control on MP context.
86 ReleaseMpContextControl (
90 ReleaseSpinLock (&mDebugMpContext
.MpContextSpinLock
);
94 Break the other processor by send IPI.
96 @param[in] CurrentProcessorIndex Current processor index value.
100 HaltOtherProcessors (
101 IN UINT32 CurrentProcessorIndex
105 if (!IsBsp (CurrentProcessorIndex
)) {
106 SetIpiSentByApFlag (TRUE
);;
109 mDebugMpContext
.BreakAtCpuIndex
= CurrentProcessorIndex
;
112 // Set the debug viewpoint to the current breaking CPU.
114 SetDebugViewPoint (CurrentProcessorIndex
);
117 // Send fixed IPI to other processors.
119 SendFixedIpiAllExcludingSelf (DEBUG_TIMER_VECTOR
);
124 Get the current processor's index.
126 @return Processor index value.
137 LocalApicID
= (UINT16
) GetApicId ();
139 AcquireMpContextControl ();
141 for (Index
= 0; Index
< mDebugCpuData
.CpuCount
; Index
++) {
142 if (mDebugCpuData
.ApicID
[Index
] == LocalApicID
) {
147 if (Index
== mDebugCpuData
.CpuCount
) {
148 mDebugCpuData
.ApicID
[Index
] = LocalApicID
;
149 mDebugCpuData
.CpuCount
++ ;
152 ReleaseMpContextControl ();
158 Check if the specified processor is BSP or not.
160 @param[in] ProcessorIndex Processor index value.
162 @retval TRUE It is BSP.
163 @retval FALSE It isn't BSP.
168 IN UINT32 ProcessorIndex
171 if (AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE_ADDRESS
, 8, 8) == 1) {
172 if (mDebugMpContext
.BspIndex
!= ProcessorIndex
) {
173 AcquireMpContextControl ();
174 mDebugMpContext
.BspIndex
= ProcessorIndex
;
175 ReleaseMpContextControl ();
184 Set processor stop flag bitmask in MP context.
186 @param[in] ProcessorIndex Processor index value.
187 @param[in] StopFlag TRUE means set stop flag.
188 FALSE means clean break flag.
192 SetCpuStopFlagByIndex (
193 IN UINT32 ProcessorIndex
,
200 AcquireMpContextControl ();
202 Value
= mDebugMpContext
.CpuStopStatusMask
[ProcessorIndex
/ 8];
203 Index
= ProcessorIndex
% 8;
205 Value
= BitFieldWrite8 (Value
, Index
, Index
, 1);
207 Value
= BitFieldWrite8 (Value
, Index
, Index
, 0);
209 mDebugMpContext
.CpuStopStatusMask
[ProcessorIndex
/ 8] = Value
;
211 ReleaseMpContextControl ();
215 Set processor break flag bitmask in MP context.
217 @param[in] ProcessorIndex Processor index value.
218 @param[in] BreakFlag TRUE means set break flag.
219 FALSE means clean break flag.
223 SetCpuBreakFlagByIndex (
224 IN UINT32 ProcessorIndex
,
231 AcquireMpContextControl ();
233 Value
= mDebugMpContext
.CpuBreakMask
[ProcessorIndex
/ 8];
234 Index
= ProcessorIndex
% 8;
236 Value
= BitFieldWrite8 (Value
, Index
, Index
, 1);
238 Value
= BitFieldWrite8 (Value
, Index
, Index
, 0);
240 mDebugMpContext
.CpuBreakMask
[ProcessorIndex
/ 8] = Value
;
242 ReleaseMpContextControl ();
246 Check if processor is stopped already.
248 @param[in] ProcessorIndex Processor index value.
250 @retval TRUE Processor is stopped already.
251 @retval TRUE Processor isn't stopped.
256 IN UINT32 ProcessorIndex
261 CpuMask
= (UINT8
) (1 << (ProcessorIndex
% 8));
263 if ((mDebugMpContext
.CpuStopStatusMask
[ProcessorIndex
/ 8] & CpuMask
) != 0) {
271 Set the run command flag.
273 @param[in] RunningFlag TRUE means run command flag is set.
274 FALSE means run command flag is cleared.
279 IN BOOLEAN RunningFlag
282 AcquireMpContextControl ();
284 mDebugMpContext
.RunCommandSet
= RunningFlag
;
286 ReleaseMpContextControl ();
290 Set the current view point to be debugged.
292 @param[in] ProcessorIndex Processor index value.
297 IN UINT32 ProcessorIndex
300 AcquireMpContextControl ();
302 mDebugMpContext
.ViewPointIndex
= ProcessorIndex
;
304 ReleaseMpContextControl ();
308 Initialize debug timer.
310 @param[in] IpiSentByApFlag TRUE means this IPI is sent by AP.
311 FALSE means this IPI is sent by BSP.
316 IN BOOLEAN IpiSentByApFlag
319 AcquireMpContextControl ();
321 mDebugMpContext
.IpiSentByAp
= IpiSentByApFlag
;
323 ReleaseMpContextControl ();
327 Check if any processor breaks.
329 @retval others There is at least one processor broken, the minimum
330 index number of Processor returned.
331 @retval -1 No any processor broken.
341 for (Index
= 0; Index
< DEBUG_CPU_MAX_COUNT
/ 8; Index
++) {
342 if (mDebugMpContext
.CpuBreakMask
[Index
] != 0) {
343 return (UINT32
) LowBitSet32 (mDebugMpContext
.CpuBreakMask
[Index
]) + Index
* 8;
350 Check if all processors are in running status.
352 @retval TRUE All processors run.
353 @retval FALSE At least one processor does not run.
363 for (Index
= 0; Index
< DEBUG_CPU_MAX_COUNT
/ 8; Index
++) {
364 if (mDebugMpContext
.CpuStopStatusMask
[Index
] != 0) {