| /** @file | |
| The PRM Buffer Context library provides a general abstraction for context buffer management. | |
| Copyright (c) Microsoft Corporation | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include <Library/BaseLib.h> | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Library/PrmContextBufferLib.h> | |
| #include <Library/UefiBootServicesTableLib.h> | |
| #include <Protocol/PrmConfig.h> | |
| #define _DBGMSGID_ "[PRMCONTEXTBUFFERLIB]" | |
| /** | |
| Finds a PRM context buffer for the given PRM handler GUID. | |
| Note: PRM_MODULE_CONTEXT_BUFFERS is at the PRM module level while PRM_CONTEXT_BUFFER is at the PRM handler level. | |
| @param[in] HandlerGuid A pointer to the PRM handler GUID. | |
| @param[in] ModuleContextBuffers A pointer to the PRM context buffers structure for the PRM module. | |
| @param[out] PrmModuleContextBuffer A pointer to a pointer that will be set to the PRM context buffer | |
| if successfully found. | |
| @retval EFI_SUCCESS The PRM context buffer was found. | |
| @retval EFI_INVALID_PARAMETER A required parameter pointer is NULL. | |
| @retval EFI_NOT_FOUND The context buffer for the given PRM handler GUID could not be found. | |
| **/ | |
| EFI_STATUS | |
| FindContextBufferInModuleBuffers ( | |
| IN CONST EFI_GUID *HandlerGuid, | |
| IN CONST PRM_MODULE_CONTEXT_BUFFERS *ModuleContextBuffers, | |
| OUT CONST PRM_CONTEXT_BUFFER **ContextBuffer | |
| ) | |
| { | |
| UINTN Index; | |
| DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __func__)); | |
| if ((HandlerGuid == NULL) || (ModuleContextBuffers == NULL) || (ContextBuffer == NULL)) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| for (Index = 0; Index < ModuleContextBuffers->BufferCount; Index++) { | |
| if (CompareGuid (&ModuleContextBuffers->Buffer[Index].HandlerGuid, HandlerGuid)) { | |
| *ContextBuffer = &ModuleContextBuffers->Buffer[Index]; | |
| return EFI_SUCCESS; | |
| } | |
| } | |
| return EFI_NOT_FOUND; | |
| } | |
| /** | |
| Returns a PRM context buffers structure for the given PRM search type. | |
| This function allows a caller to get the context buffers structure for a PRM module with either the PRM module | |
| GUID or the GUID for a PRM handler in the module. | |
| Note: PRM_MODULE_CONTEXT_BUFFERS is at the PRM module level while PRM_CONTEXT_BUFFER is at the PRM handler level. | |
| @param[in] GuidSearchType The type of GUID passed in the Guid argument. | |
| @param[in] Guid A pointer to the GUID of a PRM module or PRM handler. The actual GUID type | |
| will be interpreted based on the value passed in GuidSearchType. | |
| @param[out] PrmModuleContextBuffers A pointer to a pointer that will be set to the PRM context buffers | |
| structure if successfully found. | |
| @retval EFI_SUCCESS The PRM context buffers structure was found. | |
| @retval EFI_INVALID_PARAMETER A required parameter pointer is NULL. | |
| @retval EFI_NOT_FOUND The context buffers for the given GUID could not be found. | |
| **/ | |
| EFI_STATUS | |
| GetModuleContextBuffers ( | |
| IN PRM_GUID_SEARCH_TYPE GuidSearchType, | |
| IN CONST EFI_GUID *Guid, | |
| OUT CONST PRM_MODULE_CONTEXT_BUFFERS **PrmModuleContextBuffers | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN HandleCount; | |
| UINTN Index; | |
| EFI_HANDLE *HandleBuffer; | |
| PRM_CONFIG_PROTOCOL *PrmConfigProtocol; | |
| CONST PRM_CONTEXT_BUFFER *PrmContextBuffer; | |
| DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __func__)); | |
| if ((Guid == NULL) || (PrmModuleContextBuffers == NULL)) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| *PrmModuleContextBuffers = NULL; | |
| Status = gBS->LocateHandleBuffer ( | |
| ByProtocol, | |
| &gPrmConfigProtocolGuid, | |
| NULL, | |
| &HandleCount, | |
| &HandleBuffer | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| for (Index = 0; Index < HandleCount; Index++) { | |
| Status = gBS->HandleProtocol ( | |
| HandleBuffer[Index], | |
| &gPrmConfigProtocolGuid, | |
| (VOID **)&PrmConfigProtocol | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| if (EFI_ERROR (Status) || (PrmConfigProtocol == NULL)) { | |
| continue; | |
| } | |
| if (GuidSearchType == ByModuleGuid) { | |
| if (CompareGuid (&PrmConfigProtocol->ModuleContextBuffers.ModuleGuid, Guid)) { | |
| DEBUG (( | |
| DEBUG_INFO, | |
| " %a %a: Found a PRM configuration protocol for PRM module %g.\n", | |
| _DBGMSGID_, | |
| __func__, | |
| Guid | |
| )); | |
| *PrmModuleContextBuffers = &PrmConfigProtocol->ModuleContextBuffers; | |
| Status = EFI_SUCCESS; | |
| goto Exit; | |
| } | |
| } else { | |
| Status = FindContextBufferInModuleBuffers (Guid, &PrmConfigProtocol->ModuleContextBuffers, &PrmContextBuffer); | |
| if (!EFI_ERROR (Status)) { | |
| *PrmModuleContextBuffers = &PrmConfigProtocol->ModuleContextBuffers; | |
| Status = EFI_SUCCESS; | |
| goto Exit; | |
| } | |
| } | |
| } | |
| DEBUG (( | |
| DEBUG_INFO, | |
| " %a %a: Could not locate a PRM configuration protocol for PRM handler %g.\n", | |
| _DBGMSGID_, | |
| __func__, | |
| Guid | |
| )); | |
| Status = EFI_NOT_FOUND; | |
| Exit: | |
| gBS->FreePool (HandleBuffer); | |
| return Status; | |
| } | |
| /** | |
| Returns a PRM context buffer for the given PRM handler. | |
| @param[in] PrmHandlerGuid A pointer to the GUID for the PRM handler. | |
| @param[in] PrmModuleContextBuffers A pointer to a PRM_MODULE_CONTEXT_BUFFERS structure. If this optional | |
| parameter is provided, the handler context buffer will be searched for in this | |
| buffer structure which saves time by not performing a global search for the | |
| module buffer structure. | |
| @param[out] PrmContextBuffer A pointer to a pointer that will be set to the PRM context buffer | |
| if successfully found. | |
| @retval EFI_SUCCESS The PRM context buffer was found. | |
| @retval EFI_INVALID_PARAMETER A required parameter pointer is NULL. | |
| @retval EFI_NOT_FOUND The context buffer for the PRM handler could not be found. | |
| **/ | |
| EFI_STATUS | |
| GetContextBuffer ( | |
| IN CONST EFI_GUID *PrmHandlerGuid, | |
| IN CONST PRM_MODULE_CONTEXT_BUFFERS *PrmModuleContextBuffers OPTIONAL, | |
| OUT CONST PRM_CONTEXT_BUFFER **PrmContextBuffer | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| CONST PRM_MODULE_CONTEXT_BUFFERS *ContextBuffers; | |
| DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __func__)); | |
| if ((PrmHandlerGuid == NULL) || (PrmContextBuffer == NULL)) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| *PrmContextBuffer = NULL; | |
| if (PrmModuleContextBuffers == NULL) { | |
| Status = GetModuleContextBuffers (ByHandlerGuid, PrmHandlerGuid, &ContextBuffers); | |
| if (EFI_ERROR (Status)) { | |
| return EFI_NOT_FOUND; | |
| } | |
| } else { | |
| ContextBuffers = PrmModuleContextBuffers; | |
| } | |
| Status = FindContextBufferInModuleBuffers (PrmHandlerGuid, ContextBuffers, PrmContextBuffer); | |
| return Status; | |
| } |