]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.c
UefiCpuPkg/MpInitLib: fix 32-bit build error
[mirror_edk2.git] / UefiCpuPkg / Library / RegisterCpuFeaturesLib / DxeRegisterCpuFeaturesLib.c
CommitLineData
80c4b236
JF
1/** @file\r
2 CPU Register Table Library functions.\r
3\r
4 Copyright (c) 2017, 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 <PiDxe.h>\r
16\r
17#include <Library/UefiBootServicesTableLib.h>\r
18\r
19#include "RegisterCpuFeatures.h"\r
20\r
21CPU_FEATURES_DATA mCpuFeaturesData = {0};\r
22EFI_MP_SERVICES_PROTOCOL *mCpuFeaturesMpServices = NULL;\r
23\r
24/**\r
25 Worker function to get CPU_FEATURES_DATA pointer.\r
26\r
27 @return Pointer to CPU_FEATURES_DATA.\r
28**/\r
29CPU_FEATURES_DATA *\r
30GetCpuFeaturesData (\r
31 VOID\r
32 )\r
33{\r
34 return &mCpuFeaturesData;\r
35}\r
36\r
37/**\r
38 Worker function to get EFI_MP_SERVICES_PROTOCOL pointer.\r
39\r
40 @return Pointer to EFI_MP_SERVICES_PROTOCOL.\r
41**/\r
42EFI_MP_SERVICES_PROTOCOL *\r
43GetMpProtocol (\r
44 VOID\r
45 )\r
46{\r
47 EFI_STATUS Status;\r
48\r
49 if (mCpuFeaturesMpServices == NULL) {\r
50 //\r
51 // Get MP Services Protocol\r
52 //\r
53 Status = gBS->LocateProtocol (\r
54 &gEfiMpServiceProtocolGuid,\r
55 NULL,\r
56 (VOID **)&mCpuFeaturesMpServices\r
57 );\r
58 ASSERT_EFI_ERROR (Status);\r
59 }\r
60\r
61 ASSERT (mCpuFeaturesMpServices != NULL);\r
62 return mCpuFeaturesMpServices;\r
63}\r
64\r
65/**\r
66 Worker function to return processor index.\r
67\r
68 @return The processor index.\r
69**/\r
70UINTN\r
71GetProcessorIndex (\r
72 VOID\r
73 )\r
74{\r
75 EFI_STATUS Status;\r
76 UINTN ProcessorIndex;\r
77 EFI_MP_SERVICES_PROTOCOL *MpServices;\r
78\r
79 MpServices = GetMpProtocol ();\r
80 Status = MpServices->WhoAmI(MpServices, &ProcessorIndex);\r
81 ASSERT_EFI_ERROR (Status);\r
82 return ProcessorIndex;\r
83}\r
84\r
85/**\r
86 Gets detailed MP-related information on the requested processor at the\r
87 instant this call is made.\r
88\r
89 @param[in] ProcessorNumber The handle number of processor.\r
90 @param[out] ProcessorInfoBuffer A pointer to the buffer where information for\r
91 the requested processor is deposited.\r
92\r
93 @return Status of MpServices->GetProcessorInfo().\r
94**/\r
95EFI_STATUS\r
96GetProcessorInformation (\r
97 IN UINTN ProcessorNumber,\r
98 OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer\r
99 )\r
100{\r
101 EFI_STATUS Status;\r
102 EFI_MP_SERVICES_PROTOCOL *MpServices;\r
103\r
104 MpServices = GetMpProtocol ();\r
105 Status = MpServices->GetProcessorInfo (\r
106 MpServices,\r
107 ProcessorNumber,\r
108 ProcessorInfoBuffer\r
109 );\r
110 return Status;\r
111}\r
112\r
113/**\r
114 Worker function to execute a caller provided function on all enabled APs.\r
115\r
116 @param[in] Procedure A pointer to the function to be run on\r
117 enabled APs of the system.\r
118**/\r
119VOID\r
120StartupAPsWorker (\r
121 IN EFI_AP_PROCEDURE Procedure\r
122 )\r
123{\r
124 EFI_STATUS Status;\r
125 EFI_MP_SERVICES_PROTOCOL *MpServices;\r
126\r
127 MpServices = GetMpProtocol ();\r
128 //\r
129 // Wakeup all APs\r
130 //\r
131 Status = MpServices->StartupAllAPs (\r
132 MpServices,\r
133 Procedure,\r
134 FALSE,\r
135 NULL,\r
136 0,\r
137 NULL,\r
138 NULL\r
139 );\r
140 ASSERT_EFI_ERROR (Status);\r
141}\r
142\r
143/**\r
144 Worker function to switch the requested AP to be the BSP from that point onward.\r
145\r
146 @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.\r
147**/\r
148VOID\r
149SwitchNewBsp (\r
150 IN UINTN ProcessorNumber\r
151 )\r
152{\r
153 EFI_STATUS Status;\r
154 EFI_MP_SERVICES_PROTOCOL *MpServices;\r
155\r
156 MpServices = GetMpProtocol ();\r
157 //\r
158 // Wakeup all APs\r
159 //\r
160 Status = MpServices->SwitchBSP (\r
161 MpServices,\r
162 ProcessorNumber,\r
163 TRUE\r
164 );\r
165 ASSERT_EFI_ERROR (Status);\r
166}\r
167\r
168/**\r
169 Worker function to retrieve the number of logical processor in the platform.\r
170\r
171 @param[out] NumberOfCpus Pointer to the total number of logical\r
172 processors in the system, including the BSP\r
173 and disabled APs.\r
174 @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical\r
175 processors that exist in system, including\r
176 the BSP.\r
177**/\r
178VOID\r
179GetNumberOfProcessor (\r
180 OUT UINTN *NumberOfCpus,\r
181 OUT UINTN *NumberOfEnabledProcessors\r
182 )\r
183{\r
184 EFI_STATUS Status;\r
185 EFI_MP_SERVICES_PROTOCOL *MpServices;\r
186\r
187 MpServices = GetMpProtocol ();\r
188\r
189 //\r
190 // Get the number of CPUs\r
191 //\r
192 Status = MpServices->GetNumberOfProcessors (\r
193 MpServices,\r
194 NumberOfCpus,\r
195 NumberOfEnabledProcessors\r
196 );\r
197 ASSERT_EFI_ERROR (Status);\r
198}\r
199\r
200/**\r
201 Allocates ACPI NVS memory to save ACPI_CPU_DATA.\r
202\r
203 @return Pointer to allocated ACPI_CPU_DATA.\r
204**/\r
205ACPI_CPU_DATA *\r
206AllocateAcpiCpuData (\r
207 VOID\r
208 )\r
209{\r
210 //\r
211 // CpuS3DataDxe will do it.\r
212 //\r
213 ASSERT (FALSE);\r
214 return NULL;\r
215}\r
216\r
217/**\r
218 Enlarges CPU register table for each processor.\r
219\r
220 @param[in, out] RegisterTable Pointer processor's CPU register table\r
221**/\r
222VOID\r
223EnlargeRegisterTable (\r
224 IN OUT CPU_REGISTER_TABLE *RegisterTable\r
225 )\r
226{\r
227 EFI_STATUS Status;\r
228 EFI_PHYSICAL_ADDRESS Address;\r
229 UINTN AllocatePages;\r
230\r
231 Address = BASE_4GB - 1;\r
232 AllocatePages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;\r
233 Status = gBS->AllocatePages (\r
234 AllocateMaxAddress,\r
235 EfiACPIMemoryNVS,\r
236 AllocatePages + 1,\r
237 &Address\r
238 );\r
239 ASSERT_EFI_ERROR (Status);\r
240\r
241 //\r
242 // If there are records existing in the register table, then copy its contents\r
243 // to new region and free the old one.\r
244 //\r
245 if (RegisterTable->AllocatedSize > 0) {\r
246 CopyMem (\r
247 (VOID *) (UINTN) Address,\r
248 (VOID *) (UINTN) RegisterTable->RegisterTableEntry,\r
249 RegisterTable->AllocatedSize\r
250 );\r
251 //\r
252 // RegisterTableEntry is allocated by gBS->AllocatePages() service.\r
253 // So, gBS->FreePages() service is used to free it.\r
254 //\r
255 gBS->FreePages (\r
256 RegisterTable->RegisterTableEntry,\r
257 AllocatePages\r
258 );\r
259 }\r
260\r
261 //\r
262 // Adjust the allocated size and register table base address.\r
263 //\r
264 RegisterTable->AllocatedSize += EFI_PAGE_SIZE;\r
265 RegisterTable->RegisterTableEntry = Address;\r
266}\r