TianoCore EDK2 master
Loading...
Searching...
No Matches
HardwareInfoDxe.c
1/*/@file
2 Hardware info parsing functions.
3 Binary data is expected as a consecutive series of header - object pairs.
4 Complete library providing list-like interface to dynamically manipulate
5 hardware info objects and parsing from a generic blob.
6
7 Copyright 2021 - 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11
12#include <Uefi/UefiBaseType.h>
13#include <Uefi/UefiSpec.h>
14#include <Library/DebugLib.h>
17#include <Library/BaseLib.h>
18#include <Library/UefiLib.h>
19
20#include <Library/HardwareInfoLib.h>
21
23CreateHardwareInfoList (
24 IN UINT8 *Blob,
25 IN UINTN BlobSize,
26 IN HARDWARE_INFO_TYPE TypeFilter,
27 OUT LIST_ENTRY *ListHead
28 )
29{
30 UINT8 *Index;
31 UINT8 *BlobEnd;
32 HARDWARE_INFO *HwComponent;
33
34 if ((Blob == NULL) || (BlobSize <= 0) ||
35 (ListHead == NULL))
36 {
37 return EFI_INVALID_PARAMETER;
38 }
39
40 Index = Blob;
41 BlobEnd = Blob + BlobSize;
42 while (Index < BlobEnd) {
43 HwComponent = AllocateZeroPool (sizeof (HARDWARE_INFO));
44
45 if (HwComponent == NULL) {
46 goto FailedAllocate;
47 }
48
49 HwComponent->Header.Type.Uint64 = *((UINT64 *)Index);
50 Index += sizeof (HwComponent->Header.Type);
51 HwComponent->Header.Size = *((UINT64 *)(Index));
52 Index += sizeof (HwComponent->Header.Size);
53
54 if ((HwComponent->Header.Size > MAX_UINTN) || (Index < Blob) || ((Index + HwComponent->Header.Size) > BlobEnd)) {
55 goto FreeResources;
56 }
57
58 //
59 // Check if optional TypeFilter is set, skip if the current
60 // object is of a different type and release the partially
61 // allocated object
62 //
63 if ((TypeFilter != HardwareInfoTypeUndefined) &&
64 (HwComponent->Header.Type.Value != TypeFilter))
65 {
66 FreePool (HwComponent);
67 Index += HwComponent->Header.Size;
68 continue;
69 }
70
71 HwComponent->Data.Raw = AllocateZeroPool ((UINTN)HwComponent->Header.Size);
72 if (HwComponent->Data.Raw == NULL) {
73 goto FreeResources;
74 }
75
76 CopyMem (HwComponent->Data.Raw, Index, (UINTN)HwComponent->Header.Size);
77 Index += HwComponent->Header.Size;
78
79 InsertTailList (ListHead, &HwComponent->Link);
80 }
81
82 return EFI_SUCCESS;
83
84FreeResources:
85 //
86 // Clean the resources allocated in the incomplete cycle
87 //
88 FreePool (HwComponent);
89
90FailedAllocate:
91 DEBUG ((
92 DEBUG_ERROR,
93 "%a: Failed to allocate memory for hardware info\n",
94 __func__
95 ));
96
97 return EFI_OUT_OF_RESOURCES;
98}
99
100VOID
101FreeHardwareInfoList (
102 IN OUT LIST_ENTRY *ListHead
103 )
104{
105 LIST_ENTRY *CurrentLink;
106 HARDWARE_INFO *HwComponent;
107
108 if (IsListEmpty (ListHead)) {
109 return;
110 }
111
112 CurrentLink = ListHead->ForwardLink;
113 while (CurrentLink != NULL && CurrentLink != ListHead) {
114 HwComponent = HARDWARE_INFO_FROM_LINK (CurrentLink);
115
116 //
117 // Remove item from list before invalidating the pointers
118 //
119 CurrentLink = RemoveEntryList (CurrentLink);
120
121 FreePool (HwComponent->Data.Raw);
122 FreePool (HwComponent);
123 }
124}
125
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112