2 CPU Register Table Library functions.
4 Copyright (c) 2016, 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.
17 #include <Library/HobLib.h>
18 #include <Library/PeiServicesLib.h>
19 #include <Library/PeiServicesTablePointerLib.h>
20 #include <Ppi/MpServices.h>
21 #include "RegisterCpuFeatures.h"
23 #define REGISTER_CPU_FEATURES_GUID \
25 0xa694c467, 0x697a, 0x446b, { 0xb9, 0x29, 0x5b, 0x14, 0xa0, 0xcf, 0x39, 0xf } \
28 EFI_GUID mRegisterCpuFeaturesHobGuid
= REGISTER_CPU_FEATURES_GUID
;
31 Worker function to get CPU_FEATURES_DATA pointer.
33 @return Pointer to CPU_FEATURES_DATA.
40 CPU_FEATURES_DATA
*CpuInitData
;
41 EFI_HOB_GUID_TYPE
*GuidHob
;
46 GuidHob
= GetFirstGuidHob (&mRegisterCpuFeaturesHobGuid
);
47 if (GuidHob
!= NULL
) {
48 DataInHob
= GET_GUID_HOB_DATA (GuidHob
);
49 CpuInitData
= (CPU_FEATURES_DATA
*) (*(UINTN
*) DataInHob
);
50 ASSERT (CpuInitData
!= NULL
);
52 CpuInitData
= AllocateZeroPool (sizeof (CPU_FEATURES_DATA
));
53 ASSERT (CpuInitData
!= NULL
);
55 // Build location of CPU MP DATA buffer in HOB
57 Data64
= (UINT64
) (UINTN
) CpuInitData
;
59 &mRegisterCpuFeaturesHobGuid
,
69 Worker function to get MP PPI service pointer.
71 @return PEI PPI service pointer.
73 EFI_PEI_MP_SERVICES_PPI
*
79 EFI_PEI_MP_SERVICES_PPI
*CpuMpPpi
;
82 // Get MP Services Protocol
84 Status
= PeiServicesLocatePpi (
85 &gEfiPeiMpServicesPpiGuid
,
90 ASSERT_EFI_ERROR (Status
);
95 Worker function to return processor index.
97 @return The processor index.
105 EFI_PEI_MP_SERVICES_PPI
*CpuMpPpi
;
106 UINTN ProcessorIndex
;
108 CpuMpPpi
= GetMpPpi ();
110 Status
= CpuMpPpi
->WhoAmI(GetPeiServicesTablePointer (), CpuMpPpi
, &ProcessorIndex
);
111 ASSERT_EFI_ERROR (Status
);
112 return ProcessorIndex
;
116 Worker function to MP-related information on the requested processor at the
117 instant this call is made.
119 @param[in] ProcessorNumber The handle number of processor.
120 @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
121 the requested processor is deposited.
123 @return Status of MpServices->GetProcessorInfo().
126 GetProcessorInformation (
127 IN UINTN ProcessorNumber
,
128 OUT EFI_PROCESSOR_INFORMATION
*ProcessorInfoBuffer
131 EFI_PEI_MP_SERVICES_PPI
*CpuMpPpi
;
134 CpuMpPpi
= GetMpPpi ();
135 Status
= CpuMpPpi
->GetProcessorInfo (
136 GetPeiServicesTablePointer(),
145 Worker function to execute a caller provided function on all enabled APs.
147 @param[in] Procedure A pointer to the function to be run on
148 enabled APs of the system.
152 IN EFI_AP_PROCEDURE Procedure
156 EFI_PEI_MP_SERVICES_PPI
*CpuMpPpi
;
159 // Get MP Services Protocol
161 Status
= PeiServicesLocatePpi (
162 &gEfiPeiMpServicesPpiGuid
,
167 ASSERT_EFI_ERROR (Status
);
170 // Wakeup all APs for data collection.
172 Status
= CpuMpPpi
->StartupAllAPs (
173 GetPeiServicesTablePointer (),
180 ASSERT_EFI_ERROR (Status
);
184 Worker function to switch the requested AP to be the BSP from that point onward.
186 @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
190 IN UINTN ProcessorNumber
194 EFI_PEI_MP_SERVICES_PPI
*CpuMpPpi
;
197 // Get MP Services Protocol
199 Status
= PeiServicesLocatePpi (
200 &gEfiPeiMpServicesPpiGuid
,
205 ASSERT_EFI_ERROR (Status
);
208 // Wakeup all APs for data collection.
210 Status
= CpuMpPpi
->SwitchBSP (
211 GetPeiServicesTablePointer (),
216 ASSERT_EFI_ERROR (Status
);
220 Worker function to retrieve the number of logical processor in the platform.
222 @param[out] NumberOfCpus Pointer to the total number of logical
223 processors in the system, including the BSP
225 @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
226 processors that exist in system, including
230 GetNumberOfProcessor (
231 OUT UINTN
*NumberOfCpus
,
232 OUT UINTN
*NumberOfEnabledProcessors
236 EFI_PEI_MP_SERVICES_PPI
*CpuMpPpi
;
239 // Get MP Services Protocol
241 Status
= PeiServicesLocatePpi (
242 &gEfiPeiMpServicesPpiGuid
,
247 ASSERT_EFI_ERROR (Status
);
250 // Get the number of CPUs
252 Status
= CpuMpPpi
->GetNumberOfProcessors (
253 GetPeiServicesTablePointer (),
256 NumberOfEnabledProcessors
258 ASSERT_EFI_ERROR (Status
);
262 Allocates ACPI NVS memory to save ACPI_CPU_DATA.
264 @return Pointer to allocated ACPI_CPU_DATA.
267 AllocateAcpiCpuData (
272 EFI_PEI_MP_SERVICES_PPI
*CpuMpPpi
;
274 UINTN NumberOfEnabledProcessors
;
275 ACPI_CPU_DATA
*AcpiCpuData
;
276 EFI_PHYSICAL_ADDRESS Address
;
278 CPU_REGISTER_TABLE
*RegisterTable
;
280 EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer
;
282 Status
= PeiServicesAllocatePages (
284 EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA
)),
287 ASSERT_EFI_ERROR (Status
);
288 AcpiCpuData
= (ACPI_CPU_DATA
*) (UINTN
) Address
;
289 ASSERT (AcpiCpuData
!= NULL
);
292 // Get MP Services Protocol
294 Status
= PeiServicesLocatePpi (
295 &gEfiPeiMpServicesPpiGuid
,
300 ASSERT_EFI_ERROR (Status
);
303 // Get the number of CPUs
305 Status
= CpuMpPpi
->GetNumberOfProcessors (
306 GetPeiServicesTablePointer (),
309 &NumberOfEnabledProcessors
311 ASSERT_EFI_ERROR (Status
);
312 AcpiCpuData
->NumberOfCpus
= (UINT32
)NumberOfCpus
;
315 // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs
317 TableSize
= 2 * NumberOfCpus
* sizeof (CPU_REGISTER_TABLE
);
318 Status
= PeiServicesAllocatePages (
320 EFI_SIZE_TO_PAGES (TableSize
),
323 ASSERT_EFI_ERROR (Status
);
324 RegisterTable
= (CPU_REGISTER_TABLE
*) (UINTN
) Address
;
326 for (Index
= 0; Index
< NumberOfCpus
; Index
++) {
327 Status
= CpuMpPpi
->GetProcessorInfo (
328 GetPeiServicesTablePointer (),
333 ASSERT_EFI_ERROR (Status
);
335 RegisterTable
[Index
].InitialApicId
= (UINT32
)ProcessorInfoBuffer
.ProcessorId
;
336 RegisterTable
[Index
].TableLength
= 0;
337 RegisterTable
[Index
].AllocatedSize
= 0;
338 RegisterTable
[Index
].RegisterTableEntry
= 0;
340 RegisterTable
[NumberOfCpus
+ Index
].InitialApicId
= (UINT32
)ProcessorInfoBuffer
.ProcessorId
;
341 RegisterTable
[NumberOfCpus
+ Index
].TableLength
= 0;
342 RegisterTable
[NumberOfCpus
+ Index
].AllocatedSize
= 0;
343 RegisterTable
[NumberOfCpus
+ Index
].RegisterTableEntry
= 0;
345 AcpiCpuData
->RegisterTable
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)RegisterTable
;
346 AcpiCpuData
->PreSmmInitRegisterTable
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)(RegisterTable
+ NumberOfCpus
);
352 Enlarges CPU register table for each processor.
354 @param[in, out] RegisterTable Pointer processor's CPU register table
357 EnlargeRegisterTable (
358 IN OUT CPU_REGISTER_TABLE
*RegisterTable
362 EFI_PHYSICAL_ADDRESS Address
;
365 AllocatePages
= RegisterTable
->AllocatedSize
/ EFI_PAGE_SIZE
;
366 Status
= PeiServicesAllocatePages (
371 ASSERT_EFI_ERROR (Status
);
374 // If there are records existing in the register table, then copy its contents
375 // to new region and free the old one.
377 if (RegisterTable
->AllocatedSize
> 0) {
379 (VOID
*) (UINTN
) Address
,
380 (VOID
*) (UINTN
) RegisterTable
->RegisterTableEntry
,
381 RegisterTable
->AllocatedSize
386 // Adjust the allocated size and register table base address.
388 RegisterTable
->AllocatedSize
+= EFI_PAGE_SIZE
;
389 RegisterTable
->RegisterTableEntry
= Address
;