]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg/MpInitLib: Initialize CPU_AP_DATA for CPU APs
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.c
CommitLineData
3e8ad6bd
JF
1/** @file\r
2 CPU MP Initialize Library common functions.\r
3\r
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "MpLib.h"\r
16\r
03a1a925
JF
17/**\r
18 Get the Application Processors state.\r
19\r
20 @param[in] CpuData The pointer to CPU_AP_DATA of specified AP\r
21\r
22 @return The AP status\r
23**/\r
24CPU_STATE\r
25GetApState (\r
26 IN CPU_AP_DATA *CpuData\r
27 )\r
28{\r
29 return CpuData->State;\r
30}\r
31\r
32/**\r
33 Set the Application Processors state.\r
34\r
35 @param[in] CpuData The pointer to CPU_AP_DATA of specified AP\r
36 @param[in] State The AP status\r
37**/\r
38VOID\r
39SetApState (\r
40 IN CPU_AP_DATA *CpuData,\r
41 IN CPU_STATE State\r
42 )\r
43{\r
44 AcquireSpinLock (&CpuData->ApLock);\r
45 CpuData->State = State;\r
46 ReleaseSpinLock (&CpuData->ApLock);\r
47}\r
3e8ad6bd 48\r
9ebcf0f4
JF
49/**\r
50 Detect whether Mwait-monitor feature is supported.\r
51\r
52 @retval TRUE Mwait-monitor feature is supported.\r
53 @retval FALSE Mwait-monitor feature is not supported.\r
54**/\r
55BOOLEAN\r
56IsMwaitSupport (\r
57 VOID\r
58 )\r
59{\r
60 CPUID_VERSION_INFO_ECX VersionInfoEcx;\r
61\r
62 AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &VersionInfoEcx.Uint32, NULL);\r
63 return (VersionInfoEcx.Bits.MONITOR == 1) ? TRUE : FALSE;\r
64}\r
65\r
66/**\r
67 Get AP loop mode.\r
68\r
69 @param[out] MonitorFilterSize Returns the largest monitor-line size in bytes.\r
70\r
71 @return The AP loop mode.\r
72**/\r
73UINT8\r
74GetApLoopMode (\r
75 OUT UINT32 *MonitorFilterSize\r
76 )\r
77{\r
78 UINT8 ApLoopMode;\r
79 CPUID_MONITOR_MWAIT_EBX MonitorMwaitEbx;\r
80\r
81 ASSERT (MonitorFilterSize != NULL);\r
82\r
83 ApLoopMode = PcdGet8 (PcdCpuApLoopMode);\r
84 ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop);\r
85 if (ApLoopMode == ApInMwaitLoop) {\r
86 if (!IsMwaitSupport ()) {\r
87 //\r
88 // If processor does not support MONITOR/MWAIT feature,\r
89 // force AP in Hlt-loop mode\r
90 //\r
91 ApLoopMode = ApInHltLoop;\r
92 }\r
93 }\r
94\r
95 if (ApLoopMode != ApInMwaitLoop) {\r
96 *MonitorFilterSize = sizeof (UINT32);\r
97 } else {\r
98 //\r
99 // CPUID.[EAX=05H]:EBX.BIT0-15: Largest monitor-line size in bytes\r
100 // CPUID.[EAX=05H].EDX: C-states supported using MWAIT\r
101 //\r
102 AsmCpuid (CPUID_MONITOR_MWAIT, NULL, &MonitorMwaitEbx.Uint32, NULL, NULL);\r
103 *MonitorFilterSize = MonitorMwaitEbx.Bits.LargestMonitorLineSize;\r
104 }\r
105\r
106 return ApLoopMode;\r
107}\r
03a1a925
JF
108/*\r
109 Initialize CPU AP Data when AP is wakeup at the first time.\r
110\r
111 @param[in, out] CpuMpData Pointer to PEI CPU MP Data\r
112 @param[in] ProcessorNumber The handle number of processor\r
113 @param[in] BistData Processor BIST data\r
114\r
115**/\r
116VOID\r
117InitializeApData (\r
118 IN OUT CPU_MP_DATA *CpuMpData,\r
119 IN UINTN ProcessorNumber,\r
120 IN UINT32 BistData\r
121 )\r
122{\r
123 CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;\r
124 CpuMpData->CpuData[ProcessorNumber].Health = BistData;\r
125 CpuMpData->CpuData[ProcessorNumber].CpuHealthy = (BistData == 0) ? TRUE : FALSE;\r
126 CpuMpData->CpuData[ProcessorNumber].ApicId = GetApicId ();\r
127 CpuMpData->CpuData[ProcessorNumber].InitialApicId = GetInitialApicId ();\r
128 if (CpuMpData->CpuData[ProcessorNumber].InitialApicId >= 0xFF) {\r
129 //\r
130 // Set x2APIC mode if there are any logical processor reporting\r
131 // an Initial APIC ID of 255 or greater.\r
132 //\r
133 AcquireSpinLock(&CpuMpData->MpLock);\r
134 CpuMpData->X2ApicEnable = TRUE;\r
135 ReleaseSpinLock(&CpuMpData->MpLock);\r
136 }\r
137\r
138 InitializeSpinLock(&CpuMpData->CpuData[ProcessorNumber].ApLock);\r
139 SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);\r
140}\r
141\r
3e8ad6bd
JF
142/**\r
143 MP Initialize Library initialization.\r
144\r
145 This service will allocate AP reset vector and wakeup all APs to do APs\r
146 initialization.\r
147\r
148 This service must be invoked before all other MP Initialize Library\r
149 service are invoked.\r
150\r
151 @retval EFI_SUCCESS MP initialization succeeds.\r
152 @retval Others MP initialization fails.\r
153\r
154**/\r
155EFI_STATUS\r
156EFIAPI\r
157MpInitLibInitialize (\r
158 VOID\r
159 )\r
160{\r
e59f8f6b
JF
161 UINT32 MaxLogicalProcessorNumber;\r
162 UINT32 ApStackSize;\r
f7f85d83 163 MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
e59f8f6b 164 UINTN BufferSize;\r
9ebcf0f4 165 UINT32 MonitorFilterSize;\r
e59f8f6b
JF
166 VOID *MpBuffer;\r
167 UINTN Buffer;\r
168 CPU_MP_DATA *CpuMpData;\r
9ebcf0f4 169 UINT8 ApLoopMode;\r
e59f8f6b 170 UINT8 *MonitorBuffer;\r
03a1a925 171 UINTN Index;\r
f7f85d83 172 UINTN ApResetVectorSize;\r
e59f8f6b
JF
173 UINTN BackupBufferAddr;\r
174 MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber);\r
f7f85d83
JF
175\r
176 AsmGetAddressMap (&AddressMap);\r
177 ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);\r
e59f8f6b 178 ApStackSize = PcdGet32(PcdCpuApStackSize);\r
9ebcf0f4
JF
179 ApLoopMode = GetApLoopMode (&MonitorFilterSize);\r
180\r
e59f8f6b
JF
181 BufferSize = ApStackSize * MaxLogicalProcessorNumber;\r
182 BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber;\r
183 BufferSize += sizeof (CPU_MP_DATA);\r
184 BufferSize += ApResetVectorSize;\r
185 BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* MaxLogicalProcessorNumber;\r
186 MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));\r
187 ASSERT (MpBuffer != NULL);\r
188 ZeroMem (MpBuffer, BufferSize);\r
189 Buffer = (UINTN) MpBuffer;\r
190\r
191 MonitorBuffer = (UINT8 *) (Buffer + ApStackSize * MaxLogicalProcessorNumber);\r
192 BackupBufferAddr = (UINTN) MonitorBuffer + MonitorFilterSize * MaxLogicalProcessorNumber;\r
193 CpuMpData = (CPU_MP_DATA *) (BackupBufferAddr + ApResetVectorSize);\r
194 CpuMpData->Buffer = Buffer;\r
195 CpuMpData->CpuApStackSize = ApStackSize;\r
196 CpuMpData->BackupBuffer = BackupBufferAddr;\r
197 CpuMpData->BackupBufferSize = ApResetVectorSize;\r
198 CpuMpData->EndOfPeiFlag = FALSE;\r
199 CpuMpData->WakeupBuffer = (UINTN) -1;\r
200 CpuMpData->CpuCount = 1;\r
201 CpuMpData->BspNumber = 0;\r
202 CpuMpData->WaitEvent = NULL;\r
203 CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1);\r
204 CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);\r
205 InitializeSpinLock(&CpuMpData->MpLock);\r
206 //\r
03a1a925
JF
207 // Set BSP basic information\r
208 //\r
209 InitializeApData (CpuMpData, 0, 0);\r
210 //\r
e59f8f6b
JF
211 // Save assembly code information\r
212 //\r
213 CopyMem (&CpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP));\r
214 //\r
215 // Finally set AP loop mode\r
216 //\r
217 CpuMpData->ApLoopMode = ApLoopMode;\r
218 DEBUG ((DEBUG_INFO, "AP Loop Mode is %d\n", CpuMpData->ApLoopMode));\r
219 //\r
03a1a925
JF
220 // Set up APs wakeup signal buffer\r
221 //\r
222 for (Index = 0; Index < MaxLogicalProcessorNumber; Index++) {\r
223 CpuMpData->CpuData[Index].StartupApSignal =\r
224 (UINT32 *)(MonitorBuffer + MonitorFilterSize * Index);\r
225 }\r
e59f8f6b
JF
226 // Store BSP's MTRR setting\r
227 //\r
228 MtrrGetAllMtrrs (&CpuMpData->MtrrTable);\r
229\r
f7f85d83 230 return EFI_SUCCESS;\r
3e8ad6bd
JF
231}\r
232\r
233/**\r
234 Gets detailed MP-related information on the requested processor at the\r
235 instant this call is made. This service may only be called from the BSP.\r
236\r
237 @param[in] ProcessorNumber The handle number of processor.\r
238 @param[out] ProcessorInfoBuffer A pointer to the buffer where information for\r
239 the requested processor is deposited.\r
240 @param[out] HealthData Return processor health data.\r
241\r
242 @retval EFI_SUCCESS Processor information was returned.\r
243 @retval EFI_DEVICE_ERROR The calling processor is an AP.\r
244 @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.\r
245 @retval EFI_NOT_FOUND The processor with the handle specified by\r
246 ProcessorNumber does not exist in the platform.\r
247 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
248\r
249**/\r
250EFI_STATUS\r
251EFIAPI\r
252MpInitLibGetProcessorInfo (\r
253 IN UINTN ProcessorNumber,\r
254 OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer,\r
255 OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL\r
256 )\r
257{\r
258 return EFI_UNSUPPORTED;\r
259}\r
260/**\r
261 This return the handle number for the calling processor. This service may be\r
262 called from the BSP and APs.\r
263\r
264 @param[out] ProcessorNumber Pointer to the handle number of AP.\r
265 The range is from 0 to the total number of\r
266 logical processors minus 1. The total number of\r
267 logical processors can be retrieved by\r
268 MpInitLibGetNumberOfProcessors().\r
269\r
270 @retval EFI_SUCCESS The current processor handle number was returned\r
271 in ProcessorNumber.\r
272 @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.\r
273 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
274\r
275**/\r
276EFI_STATUS\r
277EFIAPI\r
278MpInitLibWhoAmI (\r
279 OUT UINTN *ProcessorNumber\r
280 )\r
281{\r
282 return EFI_UNSUPPORTED;\r
283}\r
284/**\r
285 Retrieves the number of logical processor in the platform and the number of\r
286 those logical processors that are enabled on this boot. This service may only\r
287 be called from the BSP.\r
288\r
289 @param[out] NumberOfProcessors Pointer to the total number of logical\r
290 processors in the system, including the BSP\r
291 and disabled APs.\r
292 @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical\r
293 processors that exist in system, including\r
294 the BSP.\r
295\r
296 @retval EFI_SUCCESS The number of logical processors and enabled\r
297 logical processors was retrieved.\r
298 @retval EFI_DEVICE_ERROR The calling processor is an AP.\r
299 @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors\r
300 is NULL.\r
301 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
302\r
303**/\r
304EFI_STATUS\r
305EFIAPI\r
306MpInitLibGetNumberOfProcessors (\r
307 OUT UINTN *NumberOfProcessors, OPTIONAL\r
308 OUT UINTN *NumberOfEnabledProcessors OPTIONAL\r
309 )\r
310{\r
311 return EFI_UNSUPPORTED;\r
312}\r