From: Duke Zhai <duke.z...@amd.com> BZ #:4640 In V3: Improve coding style follow edk2 C coding standard. 1.Remove macro definition extra underscores. 2.Putting some AMD copyright in the right place.
In V2: Improve coding style. 1.Remove the leading underscore and use double underscore at trailing in C header files. 2.Remove old tianocore licenses and redundant license description. 3.Improve coding style. For example: remove space between @param. In V1: Initial Acpi platform dxe drivers. Use firmware volume protocol to update global NVS area for ASL and SMM init code. Signed-off-by: Eric Xing <eric.x...@amd.com> Cc: Ken Yao <ken....@amd.com> Cc: Duke Zhai <duke.z...@amd.com> Cc: Igniculus Fu <igniculus...@amd.com> Cc: Abner Chang <abner.ch...@amd.com> --- .../Universal/AcpiPlatformDxe/AcpiPlatform.c | 336 ++++++++++++++++++ .../AcpiPlatformDxe/AcpiPlatform.uni | 15 + .../AcpiPlatformDxe/AcpiPlatformDxe.inf | 59 +++ .../AcpiPlatformDxe/AcpiPlatformExtra.uni | 13 + .../AcpiPlatformDxe/AcpiPlatformHooks.c | 152 ++++++++ .../AcpiPlatformDxe/AcpiPlatformHooks.h | 48 +++ 6 files changed, 623 insertions(+) create mode 100644 Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatform.c create mode 100644 Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatform.uni create mode 100644 Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformDxe.inf create mode 100644 Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformExtra.uni create mode 100644 Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformHooks.c create mode 100644 Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformHooks.h diff --git a/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatform.c b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatform.c new file mode 100644 index 0000000000..73a022594e --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatform.c @@ -0,0 +1,336 @@ +/** @file + Sample ACPI Platform Driver + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> + Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PiDxe.h> + +#include <Protocol/AcpiTable.h> +#include <Protocol/FirmwareVolume2.h> + +#include <Library/BaseLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> + +#include <IndustryStandard/Acpi.h> + +#include "AcpiPlatformHooks.h" +#include <Protocol/GlobalNvsArea.h> + +EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea; + +/** + Locate the first instance of a protocol. If the protocol requested is an + FV protocol, then it will return the first FV that contains the ACPI table + storage file. + + @param Instance Return pointer to the first instance of the protocol + + @return EFI_SUCCESS The function completed successfully. + @return EFI_NOT_FOUND The protocol could not be located. + @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. + +**/ +EFI_STATUS +LocateFvInstanceWithTables ( + OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EFI_FV_FILETYPE FileType; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN Index; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance; + + FvStatus = 0; + + // + // Locate protocol. + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + // + // Defined errors at this time are not found and out of resources. + // + return Status; + } + + // + // Looking for FV with ACPI storage file + // + + for (Index = 0; Index < NumberOfHandles; Index++) { + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **)&FvInstance + ); + ASSERT_EFI_ERROR (Status); + + // + // See if it has the ACPI storage file + // + Status = FvInstance->ReadFile ( + FvInstance, + (EFI_GUID *)PcdGetPtr (PcdAcpiTableStorageFile), + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + // + // If we found it, then we are done + // + if (Status == EFI_SUCCESS) { + *Instance = FvInstance; + break; + } + } + + // + // Our exit status is determined by the success of the previous operations + // If the protocol was found, Instance already points to it. + // + + // + // Free any allocated buffers + // + gBS->FreePool (HandleBuffer); + + return Status; +} + +/** + This function calculates and updates an UINT8 checksum. + + @param Buffer Pointer to buffer to checksum + @param Size Number of bytes to checksum + +**/ +VOID +AcpiPlatformChecksum ( + IN UINT8 *Buffer, + IN UINTN Size + ) +{ + UINTN ChecksumOffset; + + ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum); + + // + // Set checksum to 0 first + // + Buffer[ChecksumOffset] = 0; + + // + // Update checksum value + // + Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size); +} + +/** + This function will update any runtime platform specific information. + This currently includes: + Setting OEM table values, ID, table ID, creator ID and creator revision. + Enabling the proper processor entries in the APIC tables. + + @param[in] Table The table to update. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +PlatformUpdateTables ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + switch (Table->Signature) { + case EFI_ACPI_5_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: + // + // Patch the memory resource. + // + PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER *)Table); + break; + + case EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: + PatchMadtTable ((EFI_ACPI_DESCRIPTION_HEADER *)Table); + break; + + default: + break; + } + + return EFI_SUCCESS; +} + +/** + Entrypoint of Acpi Platform driver. + + @param ImageHandle + @param SystemTable + + @return EFI_SUCCESS + @return EFI_LOAD_ERROR + @return EFI_OUT_OF_RESOURCES + +**/ +EFI_STATUS +EFIAPI +AcpiPlatformEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_STATUS AcpiStatus; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; + INTN Instance; + EFI_ACPI_COMMON_HEADER *CurrentTable; + UINTN TableHandle; + UINT32 FvStatus; + UINTN TableSize; + UINTN Size; + EFI_HANDLE Handle; + + Instance = 0; + CurrentTable = NULL; + TableHandle = 0; + + // + // Find the AcpiTable protocol + // + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + // + // Allocate and initialize the NVS area for SMM and ASL communication. + // + Status = gBS->AllocatePool ( + EfiACPIMemoryNVS, + sizeof (EFI_GLOBAL_NVS_AREA), + (void **)&mGlobalNvsArea.Area + ); + ASSERT_EFI_ERROR (Status); + gBS->SetMem ( + mGlobalNvsArea.Area, + sizeof (EFI_GLOBAL_NVS_AREA), + 0 + ); + DEBUG ((DEBUG_INFO, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea.Area)); + + // + // Update global NVS area for ASL and SMM init code to use. + // + mGlobalNvsArea.Area->PcieBaseAddress = (UINT32)PcdGet64 (PcdPciExpressBaseAddress); + mGlobalNvsArea.Area->PcieBaseLimit = (UINT32)(PcdGet64 (PcdPciExpressBaseAddress) + (PcdGet32 (PcdPciExpressSize) - 1)); + + if (FeaturePcdGet (PcdNbIoApicSupport)) { + mGlobalNvsArea.Area->NbIoApic = TRUE; + } else { + mGlobalNvsArea.Area->NbIoApic = FALSE; + } + + mGlobalNvsArea.Area->TopOfMem = (UINT32)AsmReadMsr64 (0xC001001A); + + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiGlobalNvsAreaProtocolGuid, + &mGlobalNvsArea, + NULL + ); + + // + // Locate the firmware volume protocol + // + Status = LocateFvInstanceWithTables (&FwVol); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + // + // Read tables from the storage file. + // + while (Status == EFI_SUCCESS) { + Status = FwVol->ReadSection ( + FwVol, + (EFI_GUID *)PcdGetPtr (PcdAcpiTableStorageFile), + EFI_SECTION_RAW, + Instance, + (VOID **)&CurrentTable, + &Size, + &FvStatus + ); + if (!EFI_ERROR (Status)) { + AcpiStatus = PlatformUpdateTables (CurrentTable); + if (!EFI_ERROR (AcpiStatus)) { + // + // Add the table + // + TableHandle = 0; + + TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *)CurrentTable)->Length; + ASSERT (Size >= TableSize); + + // + // Checksum ACPI table + // + AcpiPlatformChecksum ((UINT8 *)CurrentTable, TableSize); + + // + // Install ACPI table + // + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + CurrentTable, + TableSize, + &TableHandle + ); + } + + // + // Free memory allocated by ReadSection + // + gBS->FreePool (CurrentTable); + + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + // + // Increment the instance + // + Instance++; + CurrentTable = NULL; + } + } + + // + // The driver does not require to be kept loaded. + // + return EFI_SUCCESS; +} diff --git a/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatform.uni b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatform.uni new file mode 100644 index 0000000000..2001da520b --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatform.uni @@ -0,0 +1,15 @@ +// /** @file +// Sample ACPI Platform Driver +// +// Sample ACPI Platform Driver +// +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +// Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Sample ACPI Platform Driver" + +#string STR_MODULE_DESCRIPTION #language en-US "Sample ACPI Platform Driver" diff --git a/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformDxe.inf new file mode 100644 index 0000000000..044218ff46 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -0,0 +1,59 @@ +## @file +# Sample ACPI Platform Driver +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = AcpiPlatform + MODULE_UNI_FILE = AcpiPlatform.uni + FILE_GUID = 6A462E1D-7B1A-95BE-DCF1-241320F01646 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = AcpiPlatformEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + AcpiPlatform.c + AcpiPlatformHooks.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + VanGoghCommonPkg/AmdCommonPkg.dec + ChachaniBoardPkg/Project.dec + +[LibraryClasses] + UefiLib + DxeServicesLib + PcdLib + BaseMemoryLib + DebugLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gEfiAcpiTableProtocolGuid ## CONSUMES + gEfiGlobalNvsAreaProtocolGuid + gEfiMpServiceProtocolGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile ## CONSUMES + gPlatformPkgTokenSpaceGuid.PcdNbIoApicSupport + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gPlatformPkgTokenSpaceGuid.PcdPciExpressSize + +[Depex] + gEfiAcpiTableProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + AcpiPlatformExtra.uni diff --git a/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformExtra.uni b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformExtra.uni new file mode 100644 index 0000000000..04a89cf3fb --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformExtra.uni @@ -0,0 +1,13 @@ +// /** @file +// AcpiPlatform Localized Strings and Content +// +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"ACPI Platform Sample DXE Driver" diff --git a/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformHooks.c b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformHooks.c new file mode 100644 index 0000000000..7cf5845772 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformHooks.c @@ -0,0 +1,152 @@ +/** @file + Sample ACPI Platform Driver + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> + Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +// +// Statements that include other files. +// +#include "AcpiPlatformHooks.h" +#include <Protocol/GlobalNvsArea.h> + +extern EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea; + +/** + Update the DSDT table. + + @param TableHeader The table to be set. + + @retval EFI_SUCCESS Update DSDT table sucessfully. + +**/ +EFI_STATUS +PatchDsdtTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader + ) +{ + UINT8 *CurrPtr; + UINT8 *DsdtPointer; + UINT32 *Signature; + UINT8 *Operation; + UINT32 *Address; + UINT16 *Size; + + // + // Loop through the ASL looking for values that we must fix up. + // + CurrPtr = (UINT8 *)TableHeader; + for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *)CurrPtr)->Length); DsdtPointer++) { + Signature = (UINT32 *)DsdtPointer; + + switch (*Signature) { + // + // GNVS operation region. + // + case (SIGNATURE_32 ('G', 'N', 'V', 'S')): + // + // Conditional match. For Region Objects, the Operator will always be the + // byte immediately before the specific name. Therefore, subtract 1 to check + // the Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_OPREGION_OP) { + Address = (UINT32 *)(DsdtPointer + 6); + *Address = (UINT32)(UINTN)mGlobalNvsArea.Area; + Size = (UINT16 *)(DsdtPointer + 11); + *Size = sizeof (EFI_GLOBAL_NVS_AREA); + } + + break; + default: + break; + } + } + + return EFI_SUCCESS; +} + +/** + Update the MADT table. + + @param TableHeader The table to be set. + + @retval EFI_SUCCESS Update MADT table sucessfully. + +**/ +EFI_STATUS +PatchMadtTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpService; + UINTN NumCPUs = 1; + UINTN NumEnabledCPUs; + UINT8 CurrProcessor = 0; + EFI_PROCESSOR_INFORMATION ProcessorInfo; + UINT8 *CurrPtr; + EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_STRUCTURE *ApicPtr = NULL; + EFI_ACPI_5_0_IO_APIC_STRUCTURE *IoApicPtr = NULL; + + // Find the MP Protocol. + Status = gBS->LocateProtocol ( + &gEfiMpServiceProtocolGuid, + NULL, + (VOID **)&MpService + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // Determine the number of processors + MpService->GetNumberOfProcessors ( + MpService, + &NumCPUs, + &NumEnabledCPUs + ); + + CurrPtr = (UINT8 *)TableHeader; + CurrPtr += sizeof (EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER); + while (CurrPtr < ((UINT8 *)TableHeader + ((EFI_ACPI_COMMON_HEADER *)TableHeader)->Length)) { + // Local APIC + ApicPtr = (EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_STRUCTURE *)CurrPtr; + if (ApicPtr->Type == EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC) { + // Disable at first + ApicPtr->Flags = 0; + ApicPtr->ApicId = 0; + + // retrieve processor information + Status = MpService->GetProcessorInfo ( + MpService, + CurrProcessor, + &ProcessorInfo + ); + if (!EFI_ERROR (Status)) { + if (ProcessorInfo.StatusFlag & PROCESSOR_ENABLED_BIT) { + ApicPtr->Flags = EFI_ACPI_5_0_LOCAL_APIC_ENABLED; + } + + ApicPtr->ApicId = (UINT8)(ProcessorInfo.ProcessorId); + } + + // Increment the procesor count + CurrProcessor++; + } + + // IO APIC (IOHUB and FCH) + IoApicPtr = (EFI_ACPI_5_0_IO_APIC_STRUCTURE *)CurrPtr; + if (IoApicPtr->Type == EFI_ACPI_5_0_IO_APIC) { + // IoApicPtr->IoApicId = PcdGet8 (PcdCfgFchIoapicId); + // IoApicPtr->IoApicId = PcdGet8 (PcdCfgGnbIoapicId); + } + + // Go to the next structure in the APIC table + CurrPtr += (ApicPtr->Length); + } + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformHooks.h b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformHooks.h new file mode 100644 index 0000000000..10e724a2ab --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/AcpiPlatformDxe/AcpiPlatformHooks.h @@ -0,0 +1,48 @@ +/** @file + Sample ACPI Platform Driver + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> + Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef ACPI_PLATFORM_HOOKS_H_ +#define ACPI_PLATFORM_HOOKS_H_ + +// +// Statements that include other header files +// +#include <IndustryStandard/Acpi.h> +#include <Protocol/MpService.h> +#include <Library/UefiBootServicesTableLib.h> + +#define AML_OPREGION_OP 0x80 + +/** + Update the DSDT table. + + @param TableHeader The table to be set. + + @retval EFI_SUCCESS Update DSDT table sucessfully. + +**/ +EFI_STATUS +PatchDsdtTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader + ); + +/** + Update the MADT table. + + @param TableHeader The table to be set. + + @retval EFI_SUCCESS Update MADT table successfully. + +**/ +EFI_STATUS +PatchMadtTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader + ); + +#endif -- 2.31.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114599): https://edk2.groups.io/g/devel/message/114599 Mute This Topic: https://groups.io/mt/103975478/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-