2 Multi-Processor support functions implementation.
4 Copyright (c) 2010, 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 // Send fixed IPI to other processors.
114 SendFixedIpiAllExcludingSelf (DEBUG_TIMER_VECTOR
);
119 Get the current processor's index.
121 @return Processor index value.
132 LocalApicID
= (UINT16
) GetApicId ();
134 AcquireMpContextControl ();
136 for (Index
= 0; Index
< mDebugCpuData
.CpuCount
; Index
++) {
137 if (mDebugCpuData
.ApicID
[Index
] == LocalApicID
) {
142 if (Index
== mDebugCpuData
.CpuCount
) {
143 mDebugCpuData
.ApicID
[Index
] = LocalApicID
;
144 mDebugCpuData
.CpuCount
++ ;
147 ReleaseMpContextControl ();
153 Check if the specified processor is BSP or not.
155 @param[in] ProcessorIndex Processor index value.
157 @retval TRUE It is BSP.
158 @retval FALSE It isn't BSP.
163 IN UINT32 ProcessorIndex
166 if (AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE_ADDRESS
, 8, 8) == 1) {
167 if (mDebugMpContext
.BspIndex
!= ProcessorIndex
) {
168 AcquireMpContextControl ();
169 mDebugMpContext
.BspIndex
= ProcessorIndex
;
170 ReleaseMpContextControl ();
179 Set processor stop flag bitmask in MP context.
181 @param[in] ProcessorIndex Processor index value.
182 @param[in] StopFlag TRUE means set stop flag.
183 FALSE means clean break flag.
187 SetCpuStopFlagByIndex (
188 IN UINT32 ProcessorIndex
,
195 AcquireMpContextControl ();
197 Value
= mDebugMpContext
.CpuStopStatusMask
[ProcessorIndex
/ 8];
198 Index
= ProcessorIndex
% 8;
200 Value
= BitFieldWrite8 (Value
, Index
, Index
, 1);
202 Value
= BitFieldWrite8 (Value
, Index
, Index
, 0);
204 mDebugMpContext
.CpuStopStatusMask
[ProcessorIndex
/ 8] = Value
;
206 ReleaseMpContextControl ();
210 Set processor break flag bitmask in MP context.
212 @param[in] ProcessorIndex Processor index value.
213 @param[in] BreakFlag TRUE means set break flag.
214 FALSE means clean break flag.
218 SetCpuBreakFlagByIndex (
219 IN UINT32 ProcessorIndex
,
226 AcquireMpContextControl ();
228 Value
= mDebugMpContext
.CpuBreakMask
[ProcessorIndex
/ 8];
229 Index
= ProcessorIndex
% 8;
231 Value
= BitFieldWrite8 (Value
, Index
, Index
, 1);
233 Value
= BitFieldWrite8 (Value
, Index
, Index
, 0);
235 mDebugMpContext
.CpuBreakMask
[ProcessorIndex
/ 8] = Value
;
237 ReleaseMpContextControl ();
241 Check if processor is stopped already.
243 @param[in] ProcessorIndex Processor index value.
245 @retval TRUE Processor is stopped already.
246 @retval TRUE Processor isn't stopped.
251 IN UINT32 ProcessorIndex
256 CpuMask
= (UINT8
) (1 << (ProcessorIndex
% 8));
258 if ((mDebugMpContext
.CpuStopStatusMask
[ProcessorIndex
/ 8] & CpuMask
) != 0) {
266 Set the run command flag.
268 @param[in] RunningFlag TRUE means run command flag is set.
269 FALSE means run command flag is cleared.
274 IN BOOLEAN RunningFlag
277 AcquireMpContextControl ();
279 mDebugMpContext
.RunCommandSet
= RunningFlag
;
281 ReleaseMpContextControl ();
285 Set the current view point to be debugged.
287 @param[in] ProcessorIndex Processor index value.
292 IN UINT32 ProcessorIndex
295 AcquireMpContextControl ();
297 mDebugMpContext
.ViewPointIndex
= ProcessorIndex
;
299 ReleaseMpContextControl ();
303 Initialize debug timer.
305 @param[in] IpiSentByApFlag TRUE means this IPI is sent by AP.
306 FALSE means this IPI is sent by BSP.
311 IN BOOLEAN IpiSentByApFlag
314 AcquireMpContextControl ();
316 mDebugMpContext
.IpiSentByAp
= IpiSentByApFlag
;
318 ReleaseMpContextControl ();
322 Check if any processor breaks.
324 @retval others There is at least one processor broken, the minimum
325 index number of Processor returned.
326 @retval -1 No any processor broken.
336 for (Index
= 0; Index
< DEBUG_CPU_MAX_COUNT
/ 8; Index
++) {
337 if (mDebugMpContext
.CpuBreakMask
[Index
] != 0) {
338 return (UINT32
) LowBitSet32 (mDebugMpContext
.CpuBreakMask
[Index
]) + Index
* 8;
345 Check if all processors are in running status.
347 @retval TRUE All processors run.
348 @retval FALSE At least one processor does not run.
358 for (Index
= 0; Index
< DEBUG_CPU_MAX_COUNT
/ 8; Index
++) {
359 if (mDebugMpContext
.CpuStopStatusMask
[Index
] != 0) {