4 Copyright (c) 2008 - 2014, 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.
18 UINTN gMaxLogicalProcessorNumber
;
21 MP_SYSTEM_DATA mMpSystemData
;
23 VOID
*mCommonStack
= 0;
24 VOID
*mTopOfApCommonStack
= 0;
25 VOID
*mApStackStart
= 0;
27 EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate
= {
28 NULL
, // GetNumberOfProcessors,
29 NULL
, // GetProcessorInfo,
30 NULL
, // StartupAllAPs,
31 NULL
, // StartupThisAP,
33 NULL
, // EnableDisableAP,
38 This return the handle number for the calling processor. This service may be
39 called from the BSP and APs.
41 This service returns the processor handle number for the calling processor.
42 The returned value is in the range from 0 to the total number of logical
43 processors minus 1. The total number of logical processors can be retrieved
44 with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
45 called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
46 is returned. Otherwise, the current processors handle number is returned in
47 ProcessorNumber, and EFI_SUCCESS is returned.
49 @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
50 @param[out] ProcessorNumber The handle number of AP that is to become the new
51 BSP. The range is from 0 to the total number of
52 logical processors minus 1. The total number of
53 logical processors can be retrieved by
54 EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
56 @retval EFI_SUCCESS The current processor handle number was returned
58 @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
64 IN EFI_MP_SERVICES_PROTOCOL
*This
,
65 OUT UINTN
*ProcessorNumber
71 if (ProcessorNumber
== NULL
) {
72 return EFI_INVALID_PARAMETER
;
75 ProcessorId
= GetApicId ();
76 for (Index
= 0; Index
< mMpSystemData
.NumberOfProcessors
; Index
++) {
77 if (mMpSystemData
.CpuDatas
[Index
].Info
.ProcessorId
== ProcessorId
) {
82 *ProcessorNumber
= Index
;
87 Application Processors do loop routine
88 after switch to its own stack.
90 @param Context1 A pointer to the context to pass into the function.
91 @param Context2 A pointer to the context to pass into the function.
95 ProcessorToIdleState (
96 IN VOID
*Context1
, OPTIONAL
97 IN VOID
*Context2 OPTIONAL
100 DEBUG ((DEBUG_INFO
, "Ap apicid is %d\n", GetApicId ()));
102 AsmApDoneWithCommonStack ();
109 Application Processor C code entry point.
120 FillInProcessorInformation (FALSE
, mMpSystemData
.NumberOfProcessors
);
121 TopOfApStack
= (UINT8
*)mApStackStart
+ gApStackSize
;
122 mApStackStart
= TopOfApStack
;
124 mMpSystemData
.NumberOfProcessors
++;
127 (SWITCH_STACK_ENTRY_POINT
)(UINTN
)ProcessorToIdleState
,
134 This function is called by all processors (both BSP and AP) once and collects MP related data.
136 @param Bsp TRUE if the CPU is BSP
137 @param ProcessorNumber The specific processor number
139 @retval EFI_SUCCESS Data for the processor collected and filled in
143 FillInProcessorInformation (
145 IN UINTN ProcessorNumber
148 CPU_DATA_BLOCK
*CpuData
;
151 CpuData
= &mMpSystemData
.CpuDatas
[ProcessorNumber
];
152 ProcessorId
= GetApicId ();
153 CpuData
->Info
.ProcessorId
= ProcessorId
;
154 CpuData
->Info
.StatusFlag
= PROCESSOR_ENABLED_BIT
| PROCESSOR_HEALTH_STATUS_BIT
;
156 CpuData
->Info
.StatusFlag
|= PROCESSOR_AS_BSP_BIT
;
158 CpuData
->Info
.Location
.Package
= ProcessorId
;
159 CpuData
->Info
.Location
.Core
= 0;
160 CpuData
->Info
.Location
.Thread
= 0;
161 CpuData
->State
= Bsp
? CpuStateBuzy
: CpuStateIdle
;
163 CpuData
->Procedure
= NULL
;
164 CpuData
->Parameter
= NULL
;
165 InitializeSpinLock (&CpuData
->CpuDataLock
);
171 Prepare the System Data.
173 @retval EFI_SUCCESS the System Data finished initilization.
181 ZeroMem (&mMpSystemData
, sizeof (MP_SYSTEM_DATA
));
183 mMpSystemData
.NumberOfProcessors
= 1;
184 mMpSystemData
.NumberOfEnabledProcessors
= 1;
186 mMpSystemData
.CpuDatas
= AllocateZeroPool (sizeof (CPU_DATA_BLOCK
) * gMaxLogicalProcessorNumber
);
187 ASSERT(mMpSystemData
.CpuDatas
!= NULL
);
192 FillInProcessorInformation (TRUE
, 0);
198 Initialize Multi-processor support.
202 InitializeMpSupport (
206 gMaxLogicalProcessorNumber
= (UINTN
) PcdGet32 (PcdCpuMaxLogicalProcessorNumber
);
207 if (gMaxLogicalProcessorNumber
< 1) {
208 DEBUG ((DEBUG_ERROR
, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));
212 if (gMaxLogicalProcessorNumber
== 1) {
216 gApStackSize
= (UINTN
) PcdGet32 (PcdCpuApStackSize
);
217 ASSERT ((gApStackSize
& (SIZE_4KB
- 1)) == 0);
219 mApStackStart
= AllocatePages (EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber
* gApStackSize
));
220 ASSERT (mApStackStart
!= NULL
);
223 // the first buffer of stack size used for common stack, when the amount of AP
224 // more than 1, we should never free the common stack which maybe used for AP reset.
226 mCommonStack
= mApStackStart
;
227 mTopOfApCommonStack
= (UINT8
*) mApStackStart
+ gApStackSize
;
228 mApStackStart
= mTopOfApCommonStack
;
232 if (mMpSystemData
.NumberOfProcessors
== 1) {
233 FreePages (mCommonStack
, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber
* gApStackSize
));
237 if (mMpSystemData
.NumberOfProcessors
< gMaxLogicalProcessorNumber
) {
238 FreePages (mApStackStart
, EFI_SIZE_TO_PAGES (
239 (gMaxLogicalProcessorNumber
- mMpSystemData
.NumberOfProcessors
) *