/** @file Min DSDT Driver Copyright (c) 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include // // Function implementations // /** 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[in] Protocol The protocol to find. @param[in] FfsGuid The FFS that contains the ACPI table. @param[out] Instance Return pointer to the first instance of the protocol. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND The protocol could not be located. @retval EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. **/ EFI_STATUS LocateSupportProtocol ( IN EFI_GUID *Protocol, IN EFI_GUID *FfsGuid, OUT VOID **Instance ) { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; UINTN NumberOfHandles; EFI_FV_FILETYPE FileType; UINT32 FvStatus; EFI_FV_FILE_ATTRIBUTES Attributes; UINTN Size; UINTN Index; // // Locate protocol. // Status = gBS->LocateHandleBuffer ( ByProtocol, Protocol, 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], Protocol, Instance ); ASSERT_EFI_ERROR (Status); // // See if it has the ACPI storage file // Size = 0; FvStatus = 0; Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile ( *Instance, FfsGuid, 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); return Status; } /** Publish ACPI table from FV. @param[in] FfsGuid The FFS that contains the ACPI table. @retval EFI_SUCCESS The function completed successfully. **/ EFI_STATUS PublishAcpiTablesFromFv ( IN EFI_GUID *FfsGuid ) { EFI_STATUS Status; EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; EFI_ACPI_COMMON_HEADER *CurrentTable; UINT32 FvStatus; UINTN Size; UINTN TableHandle; INTN Instance; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; Instance = 0; TableHandle = 0; CurrentTable = NULL; FwVol = NULL; Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable); ASSERT_EFI_ERROR (Status); // // Locate the firmware volume protocol // Status = LocateSupportProtocol ( &gEfiFirmwareVolume2ProtocolGuid, FfsGuid, (VOID **) &FwVol ); ASSERT_EFI_ERROR (Status); // // Read tables from the storage file. // while (Status == EFI_SUCCESS) { Status = FwVol->ReadSection ( FwVol, FfsGuid, EFI_SECTION_RAW, Instance, (VOID **) &CurrentTable, &Size, &FvStatus ); if (!EFI_ERROR (Status)) { // // Add the table // TableHandle = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, CurrentTable, CurrentTable->Length, &TableHandle ); ASSERT_EFI_ERROR (Status); // // Increment the instance // Instance++; CurrentTable = NULL; } } // // Finished // return EFI_SUCCESS; } /** ACPI Platform driver installation function. @param[in] ImageHandle Handle for this drivers loaded image protocol. @param[in] SystemTable EFI system table. @retval EFI_SUCCESS The driver installed without error. @retval EFI_ABORTED The driver encountered an error and could not complete installation of the ACPI tables. **/ EFI_STATUS EFIAPI InstallMinDsdt ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; Status = PublishAcpiTablesFromFv (&gEfiCallerIdGuid); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }