/** @file Library functions for SetupLib. This library instance provides methods to access Setup option. @copyright Copyright 2019 - 2021 Intel Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include #include /** Gets the data and size of a variable. Read the EFI variable (VendorGuid/Name) and return a dynamically allocated buffer, and the size of the buffer. If failure return NULL. @param Name String part of EFI variable name @param VendorGuid GUID part of EFI variable name @param VariableSize Returns the size of the EFI variable that was read @return Dynamically allocated memory that contains a copy of the EFI variable. Caller is responsible freeing the buffer via FreePages. @retval NULL Variable was not read **/ VOID * EFIAPI GetVariableAndSize ( IN CHAR16 *Name, IN EFI_GUID *Guid, IN UINTN BufferSize ) { EFI_STATUS Status; VOID *Buffer = NULL; EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVariable; CONST EFI_PEI_SERVICES **PeiServices; PeiServices = GetPeiServicesTablePointer (); (**PeiServices).LocatePpi ( PeiServices, &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, &PeiVariable ); Buffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize)); if (Buffer == NULL) { return NULL; } // // Read variable into the allocated buffer. // Status = PeiVariable->GetVariable (PeiVariable, Name, Guid, NULL, &BufferSize, Buffer); ASSERT_EFI_ERROR (Status); return Buffer; } /** Retrieves the specified group space. @param[in] Guid Pointer to a 128-bit unique value that designates which namespace to set a value from. @reture GroupInfo The found group space. NULL will return if not found. **/ UINTN InternalGetGroupInfo ( IN EFI_GUID *Guid ) { UINTN Index; if (Guid == NULL) { return MAX_ADDRESS; } // // Find the matched GUID space. // for (Index = 0; mSetupInfo[Index].GuidValue != NULL; Index ++) { if (CompareGuid (mSetupInfo[Index].GuidValue, Guid)) { break; } } // // No matched GUID space // if (mSetupInfo[Index].GuidValue == NULL) { return MAX_ADDRESS; } return Index; } /** This function provides a means by which to retrieve a value for a given option. Returns the data, data type and data size specified by OptionNumber and Guid. @param[in] Guid Pointer to a 128-bit unique value that designates which namespace to retrieve a value from. @param[in] OptionNumber The option number to retrieve a current value for. @param[out] DataType A pointer to basic data type of the retrieved data. It is optional. It could be NULL. @param[in, out] Data A pointer to the buffer to be retrieved. @param[in, out] DataSize The size, in bytes, of Buffer. @retval EFI_SUCCESS Data is successfully reterieved. @retval EFI_INVALID_PARAMETER Guid is NULL or DataSize is NULL or OptionNumber is invalid. @retval EFI_BUFFER_TOO_SMALL Input data buffer is not enough. @retval EFI_NOT_FOUND The given option is not found. **/ EFI_STATUS EFIAPI GetOptionData ( IN EFI_GUID *Guid, IN UINTN OptionNumber, IN OUT VOID *Data, IN UINTN DataSize ) { UINTN GroupIndex; VOID *Variable = NULL; if (Guid == NULL || DataSize == 0) { return EFI_INVALID_PARAMETER; } GroupIndex = InternalGetGroupInfo (Guid); if (GroupIndex == MAX_ADDRESS) { return EFI_NOT_FOUND; } Variable = GetVariableAndSize ( mSetupInfo[GroupIndex].SetupName, Guid, mSetupInfo[GroupIndex].VariableSize ); if (Variable == NULL) { return EFI_NOT_FOUND; } CopyMem (Data, (UINT8 *)Variable + OptionNumber, DataSize); return EFI_SUCCESS; } /** Get all data in the setup @retval EFI_SUCCESS Data is committed successfully. @retval EFI_INVALID_PARAMETER Guid is NULL. @retval EFI_NOT_FOUND Guid is not found. @retval EFI_DEVICE_ERROR Data can't be committed. **/ EFI_STATUS EFIAPI GetEntireConfig ( IN OUT SETUP_DATA *SetupData ) { VOID *Variable; UINTN Index; UINT8 *SetupDataPtr; if (SetupData == NULL) { return EFI_INVALID_PARAMETER; } SetupDataPtr = (UINT8 *)SetupData; ZeroMem (SetupDataPtr, sizeof (SETUP_DATA)); for (Index = 0; mSetupInfo[Index].GuidValue != NULL; Index ++) { Variable = NULL; Variable = GetVariableAndSize ( mSetupInfo[Index].SetupName, mSetupInfo[Index].GuidValue, mSetupInfo[Index].VariableSize ); ASSERT (Variable != NULL); if (Variable == NULL) { return EFI_NOT_FOUND; } CopyMem (SetupDataPtr, Variable, mSetupInfo[Index].VariableSize); SetupDataPtr = SetupDataPtr + mSetupInfo[Index].VariableSize; FreePages (Variable, EFI_SIZE_TO_PAGES (mSetupInfo[Index].VariableSize)); } return EFI_SUCCESS; } /** This function provides a means by which to retrieve a value for a given option. Returns the data, data type and data size specified by OptionNumber and Guid. @param[in] Guid Pointer to a 128-bit unique value that designates which namespace to retrieve a value from. @param[in] Variable Pointer to data location where variable is stored. @retval EFI_SUCCESS Data is successfully reterieved. @retval EFI_INVALID_PARAMETER Guid is NULL or DataSize is NULL or OptionNumber is invalid. @retval EFI_BUFFER_TOO_SMALL Input data buffer is not enough. @retval EFI_NOT_FOUND The given option is not found. **/ EFI_STATUS EFIAPI GetSpecificConfigGuid ( IN EFI_GUID *Guid, OUT VOID *Variable ) { EFI_STATUS Status; UINTN GroupIndex; EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVariable; CONST EFI_PEI_SERVICES **PeiServices; if ((Guid == NULL) || (Variable == NULL)) { return EFI_INVALID_PARAMETER; } GroupIndex = InternalGetGroupInfo (Guid); if (GroupIndex == MAX_ADDRESS) { return EFI_NOT_FOUND; } PeiServices = GetPeiServicesTablePointer (); (**PeiServices).LocatePpi ( PeiServices, &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, &PeiVariable ); Status = PeiVariable->GetVariable (PeiVariable, mSetupInfo[GroupIndex].SetupName, mSetupInfo[GroupIndex].GuidValue, NULL, &mSetupInfo[GroupIndex].VariableSize, Variable); return Status; }