summaryrefslogtreecommitdiffstats
path: root/PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
blob: 3036aa503ec858a8c7d1ab9f4deaa347badd2622 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/** @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_, __FUNCTION__));

  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_, __FUNCTION__));

  if ((Guid == NULL) || (PrmModuleContextBuffers == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *PrmModuleContextBuffers = NULL;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gPrmConfigProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (!EFI_ERROR (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_,
            __FUNCTION__,
            Guid
            ));

          *PrmModuleContextBuffers = &PrmConfigProtocol->ModuleContextBuffers;
          return EFI_SUCCESS;
        }
      } else {
        Status = FindContextBufferInModuleBuffers (Guid, &PrmConfigProtocol->ModuleContextBuffers, &PrmContextBuffer);
        if (!EFI_ERROR (Status)) {
          *PrmModuleContextBuffers = &PrmConfigProtocol->ModuleContextBuffers;
          return EFI_SUCCESS;
        }
      }
    }
  }

  DEBUG ((
    DEBUG_INFO,
    "      %a %a: Could not locate a PRM configuration protocol for PRM handler %g.\n",
    _DBGMSGID_,
    __FUNCTION__,
    Guid
    ));

  return EFI_NOT_FOUND;
}

/**
  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_, __FUNCTION__));

  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;
}