1 | /** @file
|
---|
2 | Dynamic Platform Info Repository
|
---|
3 |
|
---|
4 | Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
---|
5 | Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
|
---|
6 |
|
---|
7 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
8 |
|
---|
9 | @par Glossary:
|
---|
10 | - Cm or CM - Configuration Manager
|
---|
11 | - Obj or OBJ - Object
|
---|
12 | **/
|
---|
13 |
|
---|
14 | #include <Protocol/ConfigurationManagerProtocol.h>
|
---|
15 | #include <Library/BaseLib.h>
|
---|
16 | #include <Library/BaseMemoryLib.h>
|
---|
17 | #include <Library/DebugLib.h>
|
---|
18 | #include <Library/MemoryAllocationLib.h>
|
---|
19 |
|
---|
20 | #include "CmObjectTokenFixer.h"
|
---|
21 | #include "DynamicPlatRepoInternal.h"
|
---|
22 | #include "TokenGenerator.h"
|
---|
23 |
|
---|
24 | /** Allocate a CM_OBJ_NODE.
|
---|
25 |
|
---|
26 | @param [in] CmObjDesc CmObj to wrap in a node.
|
---|
27 | All the fields of the CmObj (Data field included),
|
---|
28 | are copied.
|
---|
29 | @param [in] Token Token to assign to this CmObj/node.
|
---|
30 | @param [out] ObjNode Allocated ObjNode.
|
---|
31 |
|
---|
32 | @retval EFI_SUCCESS Success.
|
---|
33 | @retval EFI_INVALID_PARAMETER A parameter is invalid.
|
---|
34 | @retval EFI_OUT_OF_RESOURCES An allocation has failed.
|
---|
35 | **/
|
---|
36 | STATIC
|
---|
37 | EFI_STATUS
|
---|
38 | EFIAPI
|
---|
39 | AllocCmObjNode (
|
---|
40 | IN CONST CM_OBJ_DESCRIPTOR *CmObjDesc,
|
---|
41 | IN CM_OBJECT_TOKEN Token,
|
---|
42 | OUT CM_OBJ_NODE **ObjNode
|
---|
43 | )
|
---|
44 | {
|
---|
45 | CM_OBJ_NODE *Node;
|
---|
46 | CM_OBJ_DESCRIPTOR *Desc;
|
---|
47 |
|
---|
48 | if ((CmObjDesc == NULL) || (ObjNode == NULL)) {
|
---|
49 | ASSERT (0);
|
---|
50 | return EFI_INVALID_PARAMETER;
|
---|
51 | }
|
---|
52 |
|
---|
53 | Node = AllocateZeroPool (sizeof (CM_OBJ_NODE));
|
---|
54 | if (Node == NULL) {
|
---|
55 | ASSERT (0);
|
---|
56 | return EFI_OUT_OF_RESOURCES;
|
---|
57 | }
|
---|
58 |
|
---|
59 | // Initialise the list head.
|
---|
60 | InitializeListHead (&Node->Link);
|
---|
61 | Node->Token = Token;
|
---|
62 | Desc = &Node->CmObjDesc;
|
---|
63 | Desc->ObjectId = CmObjDesc->ObjectId;
|
---|
64 | Desc->Size = CmObjDesc->Size;
|
---|
65 | Desc->Count = CmObjDesc->Count;
|
---|
66 |
|
---|
67 | // Allocate and copy the CmObject Data.
|
---|
68 | Desc->Data = AllocateCopyPool (CmObjDesc->Size, CmObjDesc->Data);
|
---|
69 | if (Desc->Data == NULL) {
|
---|
70 | FreePool (Node);
|
---|
71 | ASSERT (0);
|
---|
72 | return EFI_OUT_OF_RESOURCES;
|
---|
73 | }
|
---|
74 |
|
---|
75 | *ObjNode = Node;
|
---|
76 | return EFI_SUCCESS;
|
---|
77 | }
|
---|
78 |
|
---|
79 | /** Free a CM_OBJ_NODE.
|
---|
80 |
|
---|
81 | @param [in] ObjNode ObjNode to free.
|
---|
82 |
|
---|
83 | @retval EFI_SUCCESS Success.
|
---|
84 | @retval EFI_INVALID_PARAMETER A parameter is invalid.
|
---|
85 | **/
|
---|
86 | STATIC
|
---|
87 | EFI_STATUS
|
---|
88 | EFIAPI
|
---|
89 | FreeCmObjNode (
|
---|
90 | IN CM_OBJ_NODE *ObjNode
|
---|
91 | )
|
---|
92 | {
|
---|
93 | CM_OBJ_DESCRIPTOR *Desc;
|
---|
94 |
|
---|
95 | if (ObjNode == NULL) {
|
---|
96 | ASSERT (0);
|
---|
97 | return EFI_INVALID_PARAMETER;
|
---|
98 | }
|
---|
99 |
|
---|
100 | // Unlink Node
|
---|
101 | RemoveEntryList (&ObjNode->Link);
|
---|
102 |
|
---|
103 | Desc = &ObjNode->CmObjDesc;
|
---|
104 | if (Desc->Data != NULL) {
|
---|
105 | FreePool (Desc->Data);
|
---|
106 | }
|
---|
107 |
|
---|
108 | FreePool (ObjNode);
|
---|
109 | return EFI_SUCCESS;
|
---|
110 | }
|
---|
111 |
|
---|
112 | /** Add an object to the dynamic platform repository.
|
---|
113 |
|
---|
114 | @param [in] This This dynamic platform repository.
|
---|
115 | @param [in] CmObjDesc CmObj to add. The data is copied.
|
---|
116 | @param [out] Token If not NULL, token allocated to this CmObj.
|
---|
117 |
|
---|
118 | @retval EFI_SUCCESS Success.
|
---|
119 | @retval EFI_INVALID_PARAMETER A parameter is invalid.
|
---|
120 | @retval EFI_OUT_OF_RESOURCES An allocation has failed.
|
---|
121 | **/
|
---|
122 | EFI_STATUS
|
---|
123 | EFIAPI
|
---|
124 | DynPlatRepoAddObject (
|
---|
125 | IN DYNAMIC_PLATFORM_REPOSITORY_INFO *This,
|
---|
126 | IN CONST CM_OBJ_DESCRIPTOR *CmObjDesc,
|
---|
127 | OUT CM_OBJECT_TOKEN *Token OPTIONAL
|
---|
128 | )
|
---|
129 | {
|
---|
130 | EFI_STATUS Status;
|
---|
131 | CM_OBJ_NODE *ObjNode;
|
---|
132 | CM_OBJECT_ID ArmNamespaceObjId;
|
---|
133 | CM_OBJECT_TOKEN NewToken;
|
---|
134 |
|
---|
135 | // The dynamic repository must be able to receive objects.
|
---|
136 | if ((This == NULL) ||
|
---|
137 | (CmObjDesc == NULL) ||
|
---|
138 | (This->RepoState != DynRepoTransient))
|
---|
139 | {
|
---|
140 | ASSERT (0);
|
---|
141 | return EFI_INVALID_PARAMETER;
|
---|
142 | }
|
---|
143 |
|
---|
144 | // Check the CmObjDesc:
|
---|
145 | // - only Arm objects are supported for now.
|
---|
146 | // - only EArmObjCmRef objects can be added as arrays.
|
---|
147 | ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
|
---|
148 | if ((CmObjDesc->Size == 0) ||
|
---|
149 | (CmObjDesc->Count == 0) ||
|
---|
150 | (ArmNamespaceObjId >= EArmObjMax) ||
|
---|
151 | ((CmObjDesc->Count > 1) && (ArmNamespaceObjId != EArmObjCmRef)) ||
|
---|
152 | (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm))
|
---|
153 | {
|
---|
154 | ASSERT (0);
|
---|
155 | return EFI_INVALID_PARAMETER;
|
---|
156 | }
|
---|
157 |
|
---|
158 | // Generate a token.
|
---|
159 | NewToken = GenerateToken ();
|
---|
160 |
|
---|
161 | // Create an ObjNode.
|
---|
162 | Status = AllocCmObjNode (CmObjDesc, NewToken, &ObjNode);
|
---|
163 | if (EFI_ERROR (Status)) {
|
---|
164 | ASSERT (0);
|
---|
165 | return Status;
|
---|
166 | }
|
---|
167 |
|
---|
168 | // Fixup self-token if necessary.
|
---|
169 | Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken);
|
---|
170 | if (EFI_ERROR (Status)) {
|
---|
171 | FreeCmObjNode (ObjNode);
|
---|
172 | ASSERT (0);
|
---|
173 | return Status;
|
---|
174 | }
|
---|
175 |
|
---|
176 | // Add to link list.
|
---|
177 | InsertTailList (&This->ArmCmObjList[ArmNamespaceObjId], &ObjNode->Link);
|
---|
178 | This->ObjectCount += 1;
|
---|
179 |
|
---|
180 | if (Token != NULL) {
|
---|
181 | *Token = NewToken;
|
---|
182 | }
|
---|
183 |
|
---|
184 | return EFI_SUCCESS;
|
---|
185 | }
|
---|
186 |
|
---|
187 | /** Group lists of CmObjNode from the ArmNameSpace to one array.
|
---|
188 |
|
---|
189 | @param [in] This This dynamic platform repository.
|
---|
190 | @param [in] ArmObjIndex Index in EARM_OBJECT_ID
|
---|
191 | (must be < EArmObjMax).
|
---|
192 |
|
---|
193 | @retval EFI_SUCCESS Success.
|
---|
194 | @retval EFI_INVALID_PARAMETER A parameter is invalid.
|
---|
195 | @retval EFI_BUFFER_TOO_SMALL Buffer too small.
|
---|
196 | @retval EFI_OUT_OF_RESOURCES An allocation has failed.
|
---|
197 | **/
|
---|
198 | STATIC
|
---|
199 | EFI_STATUS
|
---|
200 | EFIAPI
|
---|
201 | GroupCmObjNodes (
|
---|
202 | IN DYNAMIC_PLATFORM_REPOSITORY_INFO *This,
|
---|
203 | IN UINT32 ArmObjIndex
|
---|
204 | )
|
---|
205 | {
|
---|
206 | EFI_STATUS Status;
|
---|
207 | UINTN Count;
|
---|
208 | UINTN Size;
|
---|
209 | UINT32 CmObjId;
|
---|
210 | UINT8 *GroupedData;
|
---|
211 | UINT8 *Data;
|
---|
212 | CM_OBJ_DESCRIPTOR *CmObjDesc;
|
---|
213 | LIST_ENTRY *ListHead;
|
---|
214 | LIST_ENTRY *Link;
|
---|
215 |
|
---|
216 | if ((This == NULL) ||
|
---|
217 | (ArmObjIndex >= EArmObjMax))
|
---|
218 | {
|
---|
219 | ASSERT (0);
|
---|
220 | return EFI_INVALID_PARAMETER;
|
---|
221 | }
|
---|
222 |
|
---|
223 | Count = 0;
|
---|
224 | Size = 0;
|
---|
225 | CmObjId = CREATE_CM_ARM_OBJECT_ID (ArmObjIndex);
|
---|
226 | ListHead = &This->ArmCmObjList[ArmObjIndex];
|
---|
227 | Link = GetFirstNode (ListHead);
|
---|
228 |
|
---|
229 | // Compute the total count and size of the CmObj in the list.
|
---|
230 | while (Link != ListHead) {
|
---|
231 | CmObjDesc = &((CM_OBJ_NODE *)Link)->CmObjDesc;
|
---|
232 |
|
---|
233 | if (CmObjDesc->ObjectId != CmObjId) {
|
---|
234 | ASSERT (0);
|
---|
235 | return EFI_INVALID_PARAMETER;
|
---|
236 | }
|
---|
237 |
|
---|
238 | if ((CmObjDesc->Count != 1) && (ArmObjIndex != EArmObjCmRef)) {
|
---|
239 | // We expect each descriptor to contain an individual object.
|
---|
240 | // EArmObjCmRef objects are counted as groups, so +1 as well.
|
---|
241 | ASSERT (0);
|
---|
242 | return EFI_INVALID_PARAMETER;
|
---|
243 | }
|
---|
244 |
|
---|
245 | Count++;
|
---|
246 | Size += CmObjDesc->Size;
|
---|
247 |
|
---|
248 | // Next Link
|
---|
249 | Link = GetNextNode (ListHead, Link);
|
---|
250 | } // while
|
---|
251 |
|
---|
252 | if (Count == 0) {
|
---|
253 | // No objects found.
|
---|
254 | return EFI_SUCCESS;
|
---|
255 | }
|
---|
256 |
|
---|
257 | GroupedData = AllocateZeroPool (Size);
|
---|
258 | if (GroupedData == NULL) {
|
---|
259 | ASSERT (0);
|
---|
260 | return EFI_OUT_OF_RESOURCES;
|
---|
261 | }
|
---|
262 |
|
---|
263 | // Copy the Object Data and add to the TokenMapper.
|
---|
264 | Data = GroupedData;
|
---|
265 | Link = GetFirstNode (ListHead);
|
---|
266 | while (Link != ListHead) {
|
---|
267 | CmObjDesc = &((CM_OBJ_NODE *)Link)->CmObjDesc;
|
---|
268 | CopyMem (Data, CmObjDesc->Data, CmObjDesc->Size);
|
---|
269 |
|
---|
270 | // Add the object to the Token Mapper.
|
---|
271 | // Note: The CmObject Data field of objects in the Token Mapper point
|
---|
272 | // to the memory in the GroupedData array.
|
---|
273 | Status = TokenMapperAddObject (
|
---|
274 | &This->TokenMapper,
|
---|
275 | ((CM_OBJ_NODE *)Link)->Token,
|
---|
276 | CmObjDesc->ObjectId,
|
---|
277 | CmObjDesc->Size,
|
---|
278 | Data
|
---|
279 | );
|
---|
280 | if (EFI_ERROR (Status)) {
|
---|
281 | FreePool (GroupedData);
|
---|
282 | return Status;
|
---|
283 | }
|
---|
284 |
|
---|
285 | Data += CmObjDesc->Size;
|
---|
286 | Link = GetNextNode (ListHead, Link);
|
---|
287 | } // while
|
---|
288 |
|
---|
289 | CmObjDesc = &This->ArmCmObjArray[ArmObjIndex];
|
---|
290 | CmObjDesc->ObjectId = CmObjId;
|
---|
291 | CmObjDesc->Size = (UINT32)Size;
|
---|
292 | CmObjDesc->Count = (UINT32)Count;
|
---|
293 | CmObjDesc->Data = GroupedData;
|
---|
294 |
|
---|
295 | return Status;
|
---|
296 | }
|
---|
297 |
|
---|
298 | /** Finalise the dynamic repository.
|
---|
299 |
|
---|
300 | Finalising means:
|
---|
301 | - Preventing any further objects from being added.
|
---|
302 | - Allowing to get objects from the dynamic repository
|
---|
303 | (not possible before a call to this function).
|
---|
304 |
|
---|
305 | @param [in] This This dynamic platform repository.
|
---|
306 |
|
---|
307 | @retval EFI_SUCCESS Success.
|
---|
308 | @retval EFI_ALREADY_STARTED Instance already initialised.
|
---|
309 | @retval EFI_INVALID_PARAMETER A parameter is invalid.
|
---|
310 | @retval EFI_BUFFER_TOO_SMALL Buffer too small.
|
---|
311 | @retval EFI_OUT_OF_RESOURCES An allocation has failed.
|
---|
312 | **/
|
---|
313 | EFI_STATUS
|
---|
314 | EFIAPI
|
---|
315 | DynamicPlatRepoFinalise (
|
---|
316 | IN DYNAMIC_PLATFORM_REPOSITORY_INFO *This
|
---|
317 | )
|
---|
318 | {
|
---|
319 | EFI_STATUS Status;
|
---|
320 | UINTN ArmObjIndex;
|
---|
321 |
|
---|
322 | if ((This == NULL) ||
|
---|
323 | (This->RepoState != DynRepoTransient))
|
---|
324 | {
|
---|
325 | ASSERT (0);
|
---|
326 | return EFI_INVALID_PARAMETER;
|
---|
327 | }
|
---|
328 |
|
---|
329 | // Prevent any further objects from being added.
|
---|
330 | This->RepoState = DynRepoFinalized;
|
---|
331 |
|
---|
332 | // Initialise the token mapper.
|
---|
333 | Status = TokenMapperInitialise (&This->TokenMapper, This->ObjectCount);
|
---|
334 | if (EFI_ERROR (Status)) {
|
---|
335 | ASSERT (0);
|
---|
336 | return Status;
|
---|
337 | }
|
---|
338 |
|
---|
339 | // For each CM_OBJECT_ID:
|
---|
340 | // - Convert the list of nodes to an array
|
---|
341 | // (the array is wrapped in a CmObjDesc).
|
---|
342 | // - Add the Token/CmObj binding to the token mapper.
|
---|
343 | for (ArmObjIndex = 0; ArmObjIndex < EArmObjMax; ArmObjIndex++) {
|
---|
344 | Status = GroupCmObjNodes (This, (UINT32)ArmObjIndex);
|
---|
345 | if (EFI_ERROR (Status)) {
|
---|
346 | ASSERT (0);
|
---|
347 | // Free the TokenMapper.
|
---|
348 | // Ignore the returned Status since we already failed.
|
---|
349 | TokenMapperShutdown (&This->TokenMapper);
|
---|
350 | return Status;
|
---|
351 | }
|
---|
352 | } // for
|
---|
353 |
|
---|
354 | return EFI_SUCCESS;
|
---|
355 | }
|
---|
356 |
|
---|
357 | /** Get a CmObj from the dynamic repository.
|
---|
358 |
|
---|
359 | @param [in] This Pointer to the Dynamic Platform Repository.
|
---|
360 | @param [in] CmObjectId The Configuration Manager Object ID.
|
---|
361 | @param [in] Token An optional token identifying the object. If
|
---|
362 | unused this must be CM_NULL_TOKEN.
|
---|
363 | @param [in, out] CmObjDesc Pointer to the Configuration Manager Object
|
---|
364 | descriptor describing the requested Object.
|
---|
365 |
|
---|
366 | @retval EFI_SUCCESS Success.
|
---|
367 | @retval EFI_INVALID_PARAMETER A parameter is invalid.
|
---|
368 | @retval EFI_NOT_FOUND The required object information is not found.
|
---|
369 | **/
|
---|
370 | EFI_STATUS
|
---|
371 | EFIAPI
|
---|
372 | DynamicPlatRepoGetObject (
|
---|
373 | IN DYNAMIC_PLATFORM_REPOSITORY_INFO *This,
|
---|
374 | IN CM_OBJECT_ID CmObjectId,
|
---|
375 | IN CM_OBJECT_TOKEN Token OPTIONAL,
|
---|
376 | IN OUT CM_OBJ_DESCRIPTOR *CmObjDesc
|
---|
377 | )
|
---|
378 | {
|
---|
379 | EFI_STATUS Status;
|
---|
380 | CM_OBJ_DESCRIPTOR *Desc;
|
---|
381 | CM_OBJECT_ID ArmNamespaceObjId;
|
---|
382 |
|
---|
383 | if ((This == NULL) ||
|
---|
384 | (CmObjDesc == NULL) ||
|
---|
385 | (This->RepoState != DynRepoFinalized))
|
---|
386 | {
|
---|
387 | ASSERT (0);
|
---|
388 | return EFI_INVALID_PARAMETER;
|
---|
389 | }
|
---|
390 |
|
---|
391 | ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjectId);
|
---|
392 | if (ArmNamespaceObjId >= EArmObjMax) {
|
---|
393 | ASSERT (0);
|
---|
394 | return EFI_INVALID_PARAMETER;
|
---|
395 | }
|
---|
396 |
|
---|
397 | if (Token != CM_NULL_TOKEN) {
|
---|
398 | // Search in the Token Mapper and return the object.
|
---|
399 | Status = TokenMapperGetObject (
|
---|
400 | &This->TokenMapper,
|
---|
401 | Token,
|
---|
402 | CmObjectId,
|
---|
403 | CmObjDesc
|
---|
404 | );
|
---|
405 | ASSERT_EFI_ERROR (Status);
|
---|
406 | return Status;
|
---|
407 | }
|
---|
408 |
|
---|
409 | if (ArmNamespaceObjId == EArmObjCmRef) {
|
---|
410 | // EArmObjCmRef object must be requested using a valid token.
|
---|
411 | ASSERT (0);
|
---|
412 | return EFI_INVALID_PARAMETER;
|
---|
413 | }
|
---|
414 |
|
---|
415 | Desc = &This->ArmCmObjArray[ArmNamespaceObjId];
|
---|
416 |
|
---|
417 | // Nothing here.
|
---|
418 | if (Desc->Count == 0) {
|
---|
419 | return EFI_NOT_FOUND;
|
---|
420 | } else {
|
---|
421 | // Return the full array.
|
---|
422 | CmObjDesc->ObjectId = Desc->ObjectId;
|
---|
423 | CmObjDesc->Size = Desc->Size;
|
---|
424 | CmObjDesc->Data = Desc->Data;
|
---|
425 | CmObjDesc->Count = Desc->Count;
|
---|
426 | }
|
---|
427 |
|
---|
428 | return EFI_SUCCESS;
|
---|
429 | }
|
---|
430 |
|
---|
431 | /** Initialize the dynamic platform repository.
|
---|
432 |
|
---|
433 | @param [out] DynPlatRepo If success, contains the initialised dynamic
|
---|
434 | platform repository.
|
---|
435 |
|
---|
436 | @retval EFI_SUCCESS Success.
|
---|
437 | @retval EFI_INVALID_PARAMETER A parameter is invalid.
|
---|
438 | @retval EFI_OUT_OF_RESOURCES An allocation has failed.
|
---|
439 | **/
|
---|
440 | EFI_STATUS
|
---|
441 | EFIAPI
|
---|
442 | DynamicPlatRepoInit (
|
---|
443 | OUT DYNAMIC_PLATFORM_REPOSITORY_INFO **DynPlatRepo
|
---|
444 | )
|
---|
445 | {
|
---|
446 | UINTN Index;
|
---|
447 | DYNAMIC_PLATFORM_REPOSITORY_INFO *Repo;
|
---|
448 |
|
---|
449 | if (DynPlatRepo == NULL) {
|
---|
450 | ASSERT (0);
|
---|
451 | return EFI_INVALID_PARAMETER;
|
---|
452 | }
|
---|
453 |
|
---|
454 | Repo = AllocateZeroPool (sizeof (DYNAMIC_PLATFORM_REPOSITORY_INFO));
|
---|
455 | if (Repo == NULL) {
|
---|
456 | ASSERT (0);
|
---|
457 | return EFI_OUT_OF_RESOURCES;
|
---|
458 | }
|
---|
459 |
|
---|
460 | // Initialise the CmObject List.
|
---|
461 | for (Index = 0; Index < EArmObjMax; Index++) {
|
---|
462 | InitializeListHead (&Repo->ArmCmObjList[Index]);
|
---|
463 | }
|
---|
464 |
|
---|
465 | Repo->ObjectCount = 0;
|
---|
466 | Repo->RepoState = DynRepoTransient;
|
---|
467 |
|
---|
468 | *DynPlatRepo = Repo;
|
---|
469 |
|
---|
470 | return EFI_SUCCESS;
|
---|
471 | }
|
---|
472 |
|
---|
473 | /** Shutdown the dynamic platform repository.
|
---|
474 |
|
---|
475 | Free all the memory allocated for the dynamic platform repository.
|
---|
476 |
|
---|
477 | @param [in] DynPlatRepo The dynamic platform repository.
|
---|
478 |
|
---|
479 | @retval EFI_INVALID_PARAMETER A parameter is invalid.
|
---|
480 | @retval EFI_SUCCESS Success.
|
---|
481 | **/
|
---|
482 | EFI_STATUS
|
---|
483 | EFIAPI
|
---|
484 | DynamicPlatRepoShutdown (
|
---|
485 | IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo
|
---|
486 | )
|
---|
487 | {
|
---|
488 | EFI_STATUS Status;
|
---|
489 | UINT32 Index;
|
---|
490 | LIST_ENTRY *ListHead;
|
---|
491 | CM_OBJ_DESCRIPTOR *CmObjDesc;
|
---|
492 | VOID *Data;
|
---|
493 |
|
---|
494 | if (DynPlatRepo == NULL) {
|
---|
495 | ASSERT (0);
|
---|
496 | return EFI_INVALID_PARAMETER;
|
---|
497 | }
|
---|
498 |
|
---|
499 | // Free the list of objects.
|
---|
500 | for (Index = 0; Index < EArmObjMax; Index++) {
|
---|
501 | // Free all the nodes with this object Id.
|
---|
502 | ListHead = &DynPlatRepo->ArmCmObjList[Index];
|
---|
503 | while (!IsListEmpty (ListHead)) {
|
---|
504 | FreeCmObjNode ((CM_OBJ_NODE *)GetFirstNode (ListHead));
|
---|
505 | } // while
|
---|
506 | } // for
|
---|
507 |
|
---|
508 | // Free the arrays.
|
---|
509 | CmObjDesc = DynPlatRepo->ArmCmObjArray;
|
---|
510 | for (Index = 0; Index < EArmObjMax; Index++) {
|
---|
511 | Data = CmObjDesc[Index].Data;
|
---|
512 | if (Data != NULL) {
|
---|
513 | FreePool (Data);
|
---|
514 | }
|
---|
515 | } // for
|
---|
516 |
|
---|
517 | // Free the TokenMapper
|
---|
518 | Status = TokenMapperShutdown (&DynPlatRepo->TokenMapper);
|
---|
519 | ASSERT_EFI_ERROR (Status);
|
---|
520 | FreePool (DynPlatRepo);
|
---|
521 | return Status;
|
---|
522 | }
|
---|