]> git.proxmox.com Git - mirror_edk2.git/blame - DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c
DynamicTablesPkg: Add missing parameter check
[mirror_edk2.git] / DynamicTablesPkg / Library / Common / TableHelperLib / TableHelper.c
CommitLineData
7130bcef
SM
1/** @file\r
2 Table Helper\r
3\r
16136f21 4 Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>\r
f2bd39fb
SM
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7130bcef
SM
7**/\r
8\r
9#include <Protocol/AcpiTable.h>\r
10#include <Library/BaseLib.h>\r
11#include <Library/DebugLib.h>\r
12#include <Library/BaseMemoryLib.h>\r
13\r
14// Module specific include files.\r
15#include <AcpiTableGenerator.h>\r
16#include <ConfigurationManagerObject.h>\r
c1b53091 17#include <Library/TableHelperLib.h>\r
7130bcef
SM
18#include <Protocol/ConfigurationManagerProtocol.h>\r
19\r
20/** The GetCgfMgrInfo function gets the CM_STD_OBJ_CONFIGURATION_MANAGER_INFO\r
21 object from the Configuration Manager.\r
22\r
23 @param [in] CfgMgrProtocol Pointer to the Configuration Manager protocol\r
24 interface.\r
25 @param [out] CfgMfrInfo Pointer to the Configuration Manager Info\r
26 object structure.\r
27\r
28 @retval EFI_SUCCESS The object is returned.\r
29 @retval EFI_INVALID_PARAMETER The Object ID is invalid.\r
30 @retval EFI_NOT_FOUND The requested Object is not found.\r
31 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
32 Manager is less than the Object size.\r
33**/\r
34EFI_STATUS\r
35EFIAPI\r
36GetCgfMgrInfo (\r
37 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,\r
38 OUT CM_STD_OBJ_CONFIGURATION_MANAGER_INFO ** CfgMfrInfo\r
39 )\r
40{\r
41 EFI_STATUS Status;\r
42 CM_OBJ_DESCRIPTOR CmObjectDesc;\r
43\r
44 ASSERT (CfgMgrProtocol != NULL);\r
45 ASSERT (CfgMfrInfo != NULL);\r
46\r
47 *CfgMfrInfo = NULL;\r
48 Status = CfgMgrProtocol->GetObject (\r
49 CfgMgrProtocol,\r
50 CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo),\r
51 CM_NULL_TOKEN,\r
52 &CmObjectDesc\r
53 );\r
54 if (EFI_ERROR (Status)) {\r
55 DEBUG ((\r
56 DEBUG_ERROR,\r
57 "ERROR: Failed to Get Configuration Manager Info. Status = %r\n",\r
58 Status\r
59 ));\r
60 return Status;\r
61 }\r
62\r
63 if (CmObjectDesc.ObjectId != CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo)) {\r
64 DEBUG ((\r
65 DEBUG_ERROR,\r
66 "ERROR: EStdObjCfgMgrInfo: Invalid ObjectId = 0x%x, expected Id = 0x%x\n",\r
67 CmObjectDesc.ObjectId,\r
68 CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo)\r
69 ));\r
70 ASSERT (FALSE);\r
71 return EFI_INVALID_PARAMETER;\r
72 }\r
73\r
74 if (CmObjectDesc.Size <\r
75 (sizeof (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO) * CmObjectDesc.Count)) {\r
76 DEBUG ((\r
77 DEBUG_ERROR,\r
78 "ERROR: EStdObjCfgMgrInfo: Buffer too small, size = 0x%x\n",\r
79 CmObjectDesc.Size\r
80 ));\r
81 ASSERT (FALSE);\r
82 return EFI_BAD_BUFFER_SIZE;\r
83 }\r
84\r
85 *CfgMfrInfo = (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO*)CmObjectDesc.Data;\r
86 return Status;\r
87}\r
88\r
89/** The AddAcpiHeader function updates the ACPI header structure pointed by\r
90 the AcpiHeader. It utilizes the ACPI table Generator and the Configuration\r
91 Manager protocol to obtain any information required for constructing the\r
92 header.\r
93\r
94 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
95 protocol interface.\r
96 @param [in] Generator Pointer to the ACPI table Generator.\r
97 @param [in,out] AcpiHeader Pointer to the ACPI table header to be\r
98 updated.\r
e12bdeb1 99 @param [in] AcpiTableInfo Pointer to the ACPI table info structure.\r
7130bcef
SM
100 @param [in] Length Length of the ACPI table.\r
101\r
102 @retval EFI_SUCCESS The ACPI table is updated successfully.\r
103 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
104 @retval EFI_NOT_FOUND The required object information is not found.\r
105 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
106 Manager is less than the Object size for the\r
107 requested object.\r
108**/\r
109EFI_STATUS\r
110EFIAPI\r
111AddAcpiHeader (\r
112 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,\r
113 IN CONST ACPI_TABLE_GENERATOR * CONST Generator,\r
114 IN OUT EFI_ACPI_DESCRIPTION_HEADER * CONST AcpiHeader,\r
e12bdeb1 115 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,\r
7130bcef
SM
116 IN CONST UINT32 Length\r
117 )\r
118{\r
119 EFI_STATUS Status;\r
120 CM_STD_OBJ_CONFIGURATION_MANAGER_INFO * CfgMfrInfo;\r
121\r
122 ASSERT (CfgMgrProtocol != NULL);\r
123 ASSERT (Generator != NULL);\r
124 ASSERT (AcpiHeader != NULL);\r
25cf58a1 125 ASSERT (AcpiTableInfo != NULL);\r
7130bcef
SM
126 ASSERT (Length >= sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
127\r
128 if ((CfgMgrProtocol == NULL) ||\r
129 (Generator == NULL) ||\r
130 (AcpiHeader == NULL) ||\r
25cf58a1 131 (AcpiTableInfo == NULL) ||\r
7130bcef
SM
132 (Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER))\r
133 ) {\r
134 return EFI_INVALID_PARAMETER;\r
135 }\r
136\r
137 Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo);\r
138 if (EFI_ERROR (Status)) {\r
139 DEBUG ((\r
140 DEBUG_ERROR,\r
141 "ERROR: Failed to get Configuration Manager info. Status = %r\n",\r
142 Status\r
143 ));\r
144 goto error_handler;\r
145 }\r
146\r
147 // UINT32 Signature\r
148 AcpiHeader->Signature = Generator->AcpiTableSignature;\r
149 // UINT32 Length\r
150 AcpiHeader->Length = Length;\r
151 // UINT8 Revision\r
e12bdeb1 152 AcpiHeader->Revision = AcpiTableInfo->AcpiTableRevision;\r
7130bcef
SM
153 // UINT8 Checksum\r
154 AcpiHeader->Checksum = 0;\r
155\r
156 // UINT8 OemId[6]\r
157 CopyMem (AcpiHeader->OemId, CfgMfrInfo->OemId, sizeof (AcpiHeader->OemId));\r
158\r
159 // UINT64 OemTableId\r
e12bdeb1
SM
160 if (AcpiTableInfo->OemTableId != 0) {\r
161 AcpiHeader->OemTableId = AcpiTableInfo->OemTableId;\r
162 } else {\r
163 AcpiHeader->OemTableId = SIGNATURE_32 (\r
164 CfgMfrInfo->OemId[0],\r
165 CfgMfrInfo->OemId[1],\r
166 CfgMfrInfo->OemId[2],\r
167 CfgMfrInfo->OemId[3]\r
168 ) |\r
169 ((UINT64)Generator->AcpiTableSignature << 32);\r
170 }\r
7130bcef
SM
171\r
172 // UINT32 OemRevision\r
e12bdeb1
SM
173 if (AcpiTableInfo->OemRevision != 0) {\r
174 AcpiHeader->OemRevision = AcpiTableInfo->OemRevision;\r
175 } else {\r
176 AcpiHeader->OemRevision = CfgMfrInfo->Revision;\r
177 }\r
7130bcef
SM
178\r
179 // UINT32 CreatorId\r
180 AcpiHeader->CreatorId = Generator->CreatorId;\r
181 // UINT32 CreatorRevision\r
182 AcpiHeader->CreatorRevision = Generator->CreatorRevision;\r
183\r
184error_handler:\r
185 return Status;\r
186}\r
c1b53091
KK
187\r
188/**\r
189 Test and report if a duplicate entry exists in the given array of comparable\r
190 elements.\r
191\r
192 @param [in] Array Array of elements to test for duplicates.\r
193 @param [in] Count Number of elements in Array.\r
194 @param [in] ElementSize Size of an element in bytes\r
195 @param [in] EqualTestFunction The function to call to check if any two\r
196 elements are equal.\r
197\r
198 @retval TRUE A duplicate element was found or one of\r
199 the input arguments is invalid.\r
200 @retval FALSE Every element in Array is unique.\r
201**/\r
202BOOLEAN\r
203EFIAPI\r
204FindDuplicateValue (\r
205 IN CONST VOID * Array,\r
206 IN CONST UINTN Count,\r
207 IN CONST UINTN ElementSize,\r
208 IN PFN_IS_EQUAL EqualTestFunction\r
209 )\r
210{\r
211 UINTN Index1;\r
212 UINTN Index2;\r
213 UINT8 * Element1;\r
214 UINT8 * Element2;\r
215\r
216 if (Array == NULL) {\r
217 DEBUG ((DEBUG_ERROR, "ERROR: FindDuplicateValues: Array is NULL.\n"));\r
218 return TRUE;\r
219 }\r
220\r
221 if (ElementSize == 0) {\r
222 DEBUG ((DEBUG_ERROR, "ERROR: FindDuplicateValues: ElementSize is 0.\n"));\r
223 return TRUE;\r
224 }\r
225\r
226 if (EqualTestFunction == NULL) {\r
227 DEBUG ((\r
228 DEBUG_ERROR,\r
229 "ERROR: FindDuplicateValues: EqualTestFunction is NULL.\n"\r
230 ));\r
231 return TRUE;\r
232 }\r
233\r
234 if (Count < 2) {\r
235 return FALSE;\r
236 }\r
237\r
238 for (Index1 = 0; Index1 < Count - 1; Index1++) {\r
239 for (Index2 = Index1 + 1; Index2 < Count; Index2++) {\r
240 Element1 = (UINT8*)Array + (Index1 * ElementSize);\r
241 Element2 = (UINT8*)Array + (Index2 * ElementSize);\r
242\r
243 if (EqualTestFunction (Element1, Element2, Index1, Index2)) {\r
244 return TRUE;\r
245 }\r
246 }\r
247 }\r
248 return FALSE;\r
249}\r