/** @file This DXE driver configures and supports Intel(R) Dynamic Tuning Technology. @copyright INTEL CONFIDENTIAL Copyright 2013 - 2020 Intel Corporation. The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material may contain trade secrets and proprietary and confidential information of Intel Corporation and its suppliers and licensors, and is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel's prior express written permission. No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing. Unless otherwise agreed by Intel in writing, you may not remove or alter this notice or any other notice embedded in Materials by Intel or Intel's suppliers or licensors in any way. This file contains a 'Sample Driver' and is licensed as such under the terms of your license agreement with Intel or your vendor. This file may be modified by the user, subject to the additional terms of the license agreement. @par Specification Reference: **/ #include "Dptf.h" GLOBAL_REMOVE_IF_UNREFERENCED SETUP_DATA mSetupData; EFI_STATUS EFIAPI InitializeDptf ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /** @brief This procedure does all the Intel(R) Dynamic Tuning Technology 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; UINTN VariableSize; VariableSize = sizeof (SETUP_DATA); Status = gRT->GetVariable ( L"Setup", &gSetupVariableGuid, NULL, &VariableSize, &mSetupData ); ASSERT_EFI_ERROR (Status); /// /// Check if Intel(R) Dynamic Tuning Technology is enabled and load the ACPI SSDT. /// if (mSetupData.EnableDptf == 1) { /// /// Load the SSDT ACPI Tables. /// DEBUG ((DEBUG_INFO, "Intel(R) Dynamic Tuning Technology: LoadAcpiTables\n")); LoadAcpiTables (); } return Status; } EFI_STATUS EFIAPI LoadAcpiTables( VOID ) /** @brief This procedure loads the ACPI SSDT tables. **/ { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; UINTN NumberOfHandles; UINTN Index; EFI_FIRMWARE_VOLUME2_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; BOOLEAN LoadTable; /// /// FwVol = NULL; Table = NULL; /// /// Locate FV protocol. /// Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NumberOfHandles, &HandleBuffer ); if (EFI_ERROR(Status)) { DEBUG ((DEBUG_ERROR, "DPTF: No Efi Firmware Volume Protocol available.\n")); } else { DEBUG ((DEBUG_INFO, "DPTF: Efi Firmware Volume Protocol is loaded.\n")); } 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], &gEfiFirmwareVolume2ProtocolGuid, (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) { DEBUG ((DEBUG_INFO, "DPTF: Intel(R) Dynamic Tuning Technology Acpi Table Storage for RVP is found.\n")); 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 EFI_NOT_FOUND; } /// /// 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)) { /// /// Check the table size is at least as large as an EFI_ACPI_COMMON_HEADER /// if (Size < sizeof (EFI_ACPI_COMMON_HEADER)) { if(Table != NULL) { gBS->FreePool (Table); Table = NULL; } return EFI_BUFFER_TOO_SMALL; } LoadTable = FALSE; TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table; switch (((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)->OemTableId) { case SIGNATURE_64 ('D', 'p', 't', 'f', 'T', 'a', 'b', 'l'): /// /// This is Intel(R) Dynamic Tuning Technology SSDT. Intel(R) Dynamic Tuning Technology should be enabled if we reach here so load the table. /// LoadTable = TRUE; DEBUG ((DEBUG_INFO, "Intel(R) Dynamic Tuning Technology: Found Intel(R) Dynamic Tuning Technology SSDT signature.\n")); break; default: break; } /// /// Add the table /// if (LoadTable) { TableHandle = 0; /// /// Check the length field isn't larger than the size read in section /// if (Table->Length > Size) { gBS->FreePool (Table); Table = NULL; return EFI_BAD_BUFFER_SIZE; } Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, Table->Length, &TableHandle ); } /// /// Increment the instance /// Instance++; gBS->FreePool (Table); Table = NULL; } } return EFI_SUCCESS; }