REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the UefiCpuPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			276 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			276 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| ACPI CPU Data initialization module
 | |
| 
 | |
| This module initializes the ACPI_CPU_DATA structure and registers the address
 | |
| of this structure in the PcdCpuS3DataAddress PCD.  This is a generic/simple
 | |
| version of this module.  It does not provide a machine check handler or CPU
 | |
| register initialization tables for ACPI S3 resume.  It also only supports the
 | |
| number of CPUs reported by the MP Services Protocol, so this module does not
 | |
| support hot plug CPUs.  This module can be copied into a CPU specific package
 | |
| and customized if these additional features are required.
 | |
| 
 | |
| Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.<BR>
 | |
| Copyright (c) 2015, Red Hat, Inc.
 | |
| 
 | |
| SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <PiDxe.h>
 | |
| 
 | |
| #include <AcpiCpuData.h>
 | |
| 
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/MtrrLib.h>
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| 
 | |
| #include <Protocol/MpService.h>
 | |
| #include <Guid/EventGroup.h>
 | |
| 
 | |
| //
 | |
| // Data structure used to allocate ACPI_CPU_DATA and its supporting structures
 | |
| //
 | |
| typedef struct {
 | |
|   ACPI_CPU_DATA      AcpiCpuData;
 | |
|   MTRR_SETTINGS      MtrrTable;
 | |
|   IA32_DESCRIPTOR    GdtrProfile;
 | |
|   IA32_DESCRIPTOR    IdtrProfile;
 | |
| } ACPI_CPU_DATA_EX;
 | |
| 
 | |
| /**
 | |
|   Allocate EfiACPIMemoryNVS memory.
 | |
| 
 | |
|   @param[in] Size   Size of memory to allocate.
 | |
| 
 | |
|   @return       Allocated address for output.
 | |
| 
 | |
| **/
 | |
| VOID *
 | |
| AllocateAcpiNvsMemory (
 | |
|   IN UINTN  Size
 | |
|   )
 | |
| {
 | |
|   EFI_PHYSICAL_ADDRESS  Address;
 | |
|   EFI_STATUS            Status;
 | |
|   VOID                  *Buffer;
 | |
| 
 | |
|   Status = gBS->AllocatePages (
 | |
|                   AllocateAnyPages,
 | |
|                   EfiACPIMemoryNVS,
 | |
|                   EFI_SIZE_TO_PAGES (Size),
 | |
|                   &Address
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   Buffer = (VOID *)(UINTN)Address;
 | |
|   ZeroMem (Buffer, Size);
 | |
| 
 | |
|   return Buffer;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Allocate memory and clean it with zero.
 | |
| 
 | |
|   @param[in] Size   Size of memory to allocate.
 | |
| 
 | |
|   @return       Allocated address for output.
 | |
| 
 | |
| **/
 | |
| VOID *
 | |
| AllocateZeroPages (
 | |
|   IN UINTN  Size
 | |
|   )
 | |
| {
 | |
|   VOID  *Buffer;
 | |
| 
 | |
|   Buffer = AllocatePages (EFI_SIZE_TO_PAGES (Size));
 | |
|   if (Buffer != NULL) {
 | |
|     ZeroMem (Buffer, Size);
 | |
|   }
 | |
| 
 | |
|   return Buffer;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Callback function executed when the EndOfDxe event group is signaled.
 | |
| 
 | |
|   We delay allocating StartupVector and saving the MTRR settings until BDS signals EndOfDxe.
 | |
| 
 | |
|   @param[in]  Event    Event whose notification function is being invoked.
 | |
|   @param[out] Context  Pointer to the MTRR_SETTINGS buffer to fill in.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| CpuS3DataOnEndOfDxe (
 | |
|   IN  EFI_EVENT  Event,
 | |
|   OUT VOID       *Context
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS        Status;
 | |
|   ACPI_CPU_DATA_EX  *AcpiCpuDataEx;
 | |
| 
 | |
|   AcpiCpuDataEx = (ACPI_CPU_DATA_EX *)Context;
 | |
|   //
 | |
|   // Allocate a 4KB reserved page below 1MB
 | |
|   //
 | |
|   AcpiCpuDataEx->AcpiCpuData.StartupVector = BASE_1MB - 1;
 | |
|   Status                                   = gBS->AllocatePages (
 | |
|                                                     AllocateMaxAddress,
 | |
|                                                     EfiReservedMemoryType,
 | |
|                                                     1,
 | |
|                                                     &AcpiCpuDataEx->AcpiCpuData.StartupVector
 | |
|                                                     );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   DEBUG ((DEBUG_VERBOSE, "%a\n", __FUNCTION__));
 | |
|   MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable);
 | |
| 
 | |
|   //
 | |
|   // Close event, so it will not be invoked again.
 | |
|   //
 | |
|   gBS->CloseEvent (Event);
 | |
| }
 | |
| 
 | |
| /**
 | |
|    The entry function of the CpuS3Data driver.
 | |
| 
 | |
|    Allocate and initialize all fields of the ACPI_CPU_DATA structure except the
 | |
|    MTRR settings.  Register an event notification on gEfiEndOfDxeEventGroupGuid
 | |
|    to capture the ACPI_CPU_DATA MTRR settings.  The PcdCpuS3DataAddress is set
 | |
|    to the address that ACPI_CPU_DATA is allocated at.
 | |
| 
 | |
|    @param[in] ImageHandle  The firmware allocated handle for the EFI image.
 | |
|    @param[in] SystemTable  A pointer to the EFI System Table.
 | |
| 
 | |
|    @retval EFI_SUCCESS     The entry point is executed successfully.
 | |
|    @retval EFI_UNSUPPORTED Do not support ACPI S3.
 | |
|    @retval other           Some error occurs when executing this entry point.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| CpuS3DataInitialize (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                Status;
 | |
|   ACPI_CPU_DATA_EX          *AcpiCpuDataEx;
 | |
|   ACPI_CPU_DATA             *AcpiCpuData;
 | |
|   EFI_MP_SERVICES_PROTOCOL  *MpServices;
 | |
|   UINTN                     NumberOfCpus;
 | |
|   UINTN                     NumberOfEnabledProcessors;
 | |
|   VOID                      *Stack;
 | |
|   UINTN                     GdtSize;
 | |
|   UINTN                     IdtSize;
 | |
|   VOID                      *Gdt;
 | |
|   VOID                      *Idt;
 | |
|   EFI_EVENT                 Event;
 | |
|   ACPI_CPU_DATA             *OldAcpiCpuData;
 | |
| 
 | |
|   if (!PcdGetBool (PcdAcpiS3Enable)) {
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure
 | |
|   //
 | |
|   OldAcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress);
 | |
| 
 | |
|   AcpiCpuDataEx = AllocateZeroPages (sizeof (ACPI_CPU_DATA_EX));
 | |
|   ASSERT (AcpiCpuDataEx != NULL);
 | |
|   AcpiCpuData = &AcpiCpuDataEx->AcpiCpuData;
 | |
| 
 | |
|   //
 | |
|   // Get MP Services Protocol
 | |
|   //
 | |
|   Status = gBS->LocateProtocol (
 | |
|                   &gEfiMpServiceProtocolGuid,
 | |
|                   NULL,
 | |
|                   (VOID **)&MpServices
 | |
|                   );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   //
 | |
|   // Get the number of CPUs
 | |
|   //
 | |
|   Status = MpServices->GetNumberOfProcessors (
 | |
|                          MpServices,
 | |
|                          &NumberOfCpus,
 | |
|                          &NumberOfEnabledProcessors
 | |
|                          );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
|   AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;
 | |
| 
 | |
|   //
 | |
|   // Initialize ACPI_CPU_DATA fields
 | |
|   //
 | |
|   AcpiCpuData->StackSize                 = PcdGet32 (PcdCpuApStackSize);
 | |
|   AcpiCpuData->ApMachineCheckHandlerBase = 0;
 | |
|   AcpiCpuData->ApMachineCheckHandlerSize = 0;
 | |
|   AcpiCpuData->GdtrProfile               = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->GdtrProfile;
 | |
|   AcpiCpuData->IdtrProfile               = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->IdtrProfile;
 | |
|   AcpiCpuData->MtrrTable                 = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->MtrrTable;
 | |
| 
 | |
|   //
 | |
|   // Allocate stack space for all CPUs.
 | |
|   // Use ACPI NVS memory type because this data will be directly used by APs
 | |
|   // in S3 resume phase in long mode. Also during S3 resume, the stack buffer
 | |
|   // will only be used as scratch space. i.e. we won't read anything from it
 | |
|   // before we write to it, in PiSmmCpuDxeSmm.
 | |
|   //
 | |
|   Stack = AllocateAcpiNvsMemory (NumberOfCpus * AcpiCpuData->StackSize);
 | |
|   ASSERT (Stack != NULL);
 | |
|   AcpiCpuData->StackAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Stack;
 | |
| 
 | |
|   //
 | |
|   // Get the boot processor's GDT and IDT
 | |
|   //
 | |
|   AsmReadGdtr (&AcpiCpuDataEx->GdtrProfile);
 | |
|   AsmReadIdtr (&AcpiCpuDataEx->IdtrProfile);
 | |
| 
 | |
|   //
 | |
|   // Allocate GDT and IDT and copy current GDT and IDT contents
 | |
|   //
 | |
|   GdtSize = AcpiCpuDataEx->GdtrProfile.Limit + 1;
 | |
|   IdtSize = AcpiCpuDataEx->IdtrProfile.Limit + 1;
 | |
|   Gdt     = AllocateZeroPages (GdtSize + IdtSize);
 | |
|   ASSERT (Gdt != NULL);
 | |
|   Idt = (VOID *)((UINTN)Gdt + GdtSize);
 | |
|   CopyMem (Gdt, (VOID *)AcpiCpuDataEx->GdtrProfile.Base, GdtSize);
 | |
|   CopyMem (Idt, (VOID *)AcpiCpuDataEx->IdtrProfile.Base, IdtSize);
 | |
|   AcpiCpuDataEx->GdtrProfile.Base = (UINTN)Gdt;
 | |
|   AcpiCpuDataEx->IdtrProfile.Base = (UINTN)Idt;
 | |
| 
 | |
|   if (OldAcpiCpuData != NULL) {
 | |
|     CopyMem (&AcpiCpuData->CpuFeatureInitData, &OldAcpiCpuData->CpuFeatureInitData, sizeof (CPU_FEATURE_INIT_DATA));
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure
 | |
|   //
 | |
|   Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   //
 | |
|   // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event.
 | |
|   // The notification function allocates StartupVector and saves MTRRs for ACPI_CPU_DATA
 | |
|   //
 | |
|   Status = gBS->CreateEventEx (
 | |
|                   EVT_NOTIFY_SIGNAL,
 | |
|                   TPL_CALLBACK,
 | |
|                   CpuS3DataOnEndOfDxe,
 | |
|                   AcpiCpuData,
 | |
|                   &gEfiEndOfDxeEventGroupGuid,
 | |
|                   &Event
 | |
|                   );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |