diff options
Diffstat (limited to 'ReferenceCode/AcpiTables/Dptf/Dxe/Dptf.c')
-rw-r--r-- | ReferenceCode/AcpiTables/Dptf/Dxe/Dptf.c | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/ReferenceCode/AcpiTables/Dptf/Dxe/Dptf.c b/ReferenceCode/AcpiTables/Dptf/Dxe/Dptf.c new file mode 100644 index 0000000..caee0a7 --- /dev/null +++ b/ReferenceCode/AcpiTables/Dptf/Dxe/Dptf.c @@ -0,0 +1,440 @@ +/** @file + This DXE driver configures and supports Dptf. + +@copyright + Copyright (c) 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#include "Dptf.h" + +ACPI_PLATFORM_POLICY_PROTOCOL *mAcpiPlatformPolicyProtocol; + +EFI_RUNTIME_SERVICES *gRT; + +/// +/// Driver entry point +/// +EFI_DRIVER_ENTRY_POINT (InitializeDptf) + +EFI_STATUS +InitializeDptf ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/** +@brief + This procedure does all the DPTF initialization and loads the ACPI tables. + + @param[in] ImageHandle - The firmware allocated handle to the Driver Image + @param[in] SystemTable - Pointer to the EFI System Table + + @retval EFI_SUCCESS - The driver installed/initialized correctly. +**/ +{ + EFI_STATUS Status; + + gRT = SystemTable->RuntimeServices; + + /// + /// Initialize the EFI Runtime Library + /// + DxeInitializeDriverLib (ImageHandle, SystemTable); + + /// + /// S3 boot script + /// + INITIALIZE_SCRIPT (ImageHandle, SystemTable); + + /// + /// Locate platform configuration information and copy it to a global variable. + /// + Status = gBS->LocateProtocol ( + &gAcpiPlatformPolicyProtocolGuid, + NULL, + (VOID**) &mAcpiPlatformPolicyProtocol + ); + if (EFI_ERROR(Status)) { + DEBUG ((EFI_D_ERROR, "No ACPI Platform Policy Protocol available.")); + } else { + DEBUG ((EFI_D_INFO, "ACPI Platform Policy Protocol is loaded.")); + } + ASSERT_EFI_ERROR(Status); + + /// + /// Check if Dptf is enabled and load the ACPI SSDT. + /// + if (mAcpiPlatformPolicyProtocol->EnableDptf == 1) { + /// + /// Load the SSDT ACPI Tables. + /// + switch (mAcpiPlatformPolicyProtocol->BoardId) { + case 0x30: // BoardId for Ffrd + LoadAcpiTablesFfrd (); + break; + default: + LoadAcpiTables (); + } + } + + return EFI_SUCCESS; +} + +VOID +LoadAcpiTables( + VOID + ) +/** +@brief + This procedure loads the ACPI SSDT tables. + + @param[in] None + + @retval None + +**/ +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + UINTN Index; + EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + INTN Instance; + EFI_ACPI_COMMON_HEADER *Table; + UINTN Size; + EFI_FV_FILETYPE FileType; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINT32 FvStatus; + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + UINTN TableHandle; + EFI_ACPI_TABLE_VERSION Version; + BOOLEAN LoadTable; + + FwVol = NULL; + Table = NULL; + + /// + /// Locate FV protocol. + /// + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Look 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], + &gEfiFirmwareVolumeProtocolGuid, + (VOID **) &FwVol + ); + ASSERT_EFI_ERROR (Status); + + if ((Status == EFI_SUCCESS) && (FwVol != NULL)) { + /// + /// See if it has the ACPI storage file + /// + Size = 0; + FvStatus = 0; + Status = FwVol->ReadFile ( + FwVol, + &gDptfAcpiTableStorageGuid, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + /// + /// If we found it, then we are done + /// + if (Status == EFI_SUCCESS) { + 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 + /// + FreePool (HandleBuffer); + + /// + /// Sanity check that we found our data file + /// + ASSERT (FwVol); + if (FwVol == NULL) { + return; + } + + /// + /// By default, a table belongs in all ACPI table versions published. + /// + Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0; + + /// + /// Find the Table protocol + /// + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); + + /// + /// Read tables from the storage file. + /// + Instance = 0; + + while (Status == EFI_SUCCESS) { + /// + /// Read the ACPI tables + /// + Status = FwVol->ReadSection ( + FwVol, + &gDptfAcpiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + (VOID **) &Table, + &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + + LoadTable = FALSE; + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table; + + switch (((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)->OemTableId) { + + case EFI_SIGNATURE_64 ('D', 'p', 't', 'f', 'T', 'a', 'b', 'l'): + /// + /// This is Dptf SSDT. Dptf should be enabled if we reach here so load the table. + /// + LoadTable = TRUE; + DEBUG ((EFI_D_INFO, "Found Dptf SSDT signature.")); + break; + + default: + break; + } + + /// + /// Add the table + /// + if (LoadTable) { + TableHandle = 0; + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + Table, + Table->Length, + &TableHandle + ); + } + + /// + /// Increment the instance + /// + Instance++; + Table = NULL; + } + } +} + +VOID +LoadAcpiTablesFfrd( + VOID + ) +/** +@brief + This procedure loads the ACPI SSDT tables. + + @param[in] None + + @retval None + +**/ +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + UINTN Index; + EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + INTN Instance; + EFI_ACPI_COMMON_HEADER *Table; + UINTN Size; + EFI_FV_FILETYPE FileType; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINT32 FvStatus; + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + UINTN TableHandle; + EFI_ACPI_TABLE_VERSION Version; + BOOLEAN LoadTable; + + FwVol = NULL; + Table = NULL; + + /// + /// Locate FV protocol. + /// + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Look 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], + &gEfiFirmwareVolumeProtocolGuid, + (VOID **) &FwVol + ); + ASSERT_EFI_ERROR (Status); + + if ((Status == EFI_SUCCESS) && (FwVol != NULL)) { + /// + /// See if it has the ACPI storage file + /// + Size = 0; + FvStatus = 0; + Status = FwVol->ReadFile ( + FwVol, + &gDptfAcpiTableStorageGuidFfrd, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + /// + /// If we found it, then we are done + /// + if (Status == EFI_SUCCESS) { + 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 + /// + FreePool (HandleBuffer); + + /// + /// Sanity check that we found our data file + /// + ASSERT (FwVol); + if (FwVol == NULL) { + return; + } + + /// + /// By default, a table belongs in all ACPI table versions published. + /// + Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0; + + /// + /// Find the Table protocol + /// + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); + + /// + /// Read tables from the storage file. + /// + Instance = 0; + + while (Status == EFI_SUCCESS) { + /// + /// Read the ACPI tables + /// + Status = FwVol->ReadSection ( + FwVol, + &gDptfAcpiTableStorageGuidFfrd, + EFI_SECTION_RAW, + Instance, + (VOID **) &Table, + &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + + LoadTable = FALSE; + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table; + + switch (((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)->OemTableId) { + + case EFI_SIGNATURE_64 ('D', 'p', 't', 'f', 'F', 'f', 'r', 'd'): + /// + /// This is Dptf SSDT. Dptf should be enabled if we reach here so load the table. + /// + LoadTable = TRUE; + DEBUG ((EFI_D_INFO, "Found Dptf SSDT signature.")); + break; + + default: + break; + } + + /// + /// Add the table + /// + if (LoadTable) { + TableHandle = 0; + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + Table, + Table->Length, + &TableHandle + ); + } + + /// + /// Increment the instance + /// + Instance++; + Table = NULL; + } + } +} |