4 Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Protocol/AcpiTable.h>
10 #include <Library/BaseLib.h>
11 #include <Library/DebugLib.h>
12 #include <Library/BaseMemoryLib.h>
14 // Module specific include files.
15 #include <AcpiTableGenerator.h>
16 #include <ConfigurationManagerObject.h>
17 #include <Library/TableHelperLib.h>
18 #include <Protocol/ConfigurationManagerProtocol.h>
20 /** The GetCgfMgrInfo function gets the CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
21 object from the Configuration Manager.
23 @param [in] CfgMgrProtocol Pointer to the Configuration Manager protocol
25 @param [out] CfgMfrInfo Pointer to the Configuration Manager Info
28 @retval EFI_SUCCESS The object is returned.
29 @retval EFI_INVALID_PARAMETER The Object ID is invalid.
30 @retval EFI_NOT_FOUND The requested Object is not found.
31 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
32 Manager is less than the Object size.
37 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
*CONST CfgMgrProtocol
,
38 OUT CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
**CfgMfrInfo
42 CM_OBJ_DESCRIPTOR CmObjectDesc
;
44 ASSERT (CfgMgrProtocol
!= NULL
);
45 ASSERT (CfgMfrInfo
!= NULL
);
48 Status
= CfgMgrProtocol
->GetObject (
50 CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo
),
54 if (EFI_ERROR (Status
)) {
57 "ERROR: Failed to Get Configuration Manager Info. Status = %r\n",
63 if (CmObjectDesc
.ObjectId
!= CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo
)) {
66 "ERROR: EStdObjCfgMgrInfo: Invalid ObjectId = 0x%x, expected Id = 0x%x\n",
67 CmObjectDesc
.ObjectId
,
68 CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo
)
71 return EFI_INVALID_PARAMETER
;
74 if (CmObjectDesc
.Size
<
75 (sizeof (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
) * CmObjectDesc
.Count
))
79 "ERROR: EStdObjCfgMgrInfo: Buffer too small, size = 0x%x\n",
83 return EFI_BAD_BUFFER_SIZE
;
86 *CfgMfrInfo
= (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
*)CmObjectDesc
.Data
;
90 /** The AddAcpiHeader function updates the ACPI header structure pointed by
91 the AcpiHeader. It utilizes the ACPI table Generator and the Configuration
92 Manager protocol to obtain any information required for constructing the
95 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
97 @param [in] Generator Pointer to the ACPI table Generator.
98 @param [in,out] AcpiHeader Pointer to the ACPI table header to be
100 @param [in] AcpiTableInfo Pointer to the ACPI table info structure.
101 @param [in] Length Length of the ACPI table.
103 @retval EFI_SUCCESS The ACPI table is updated successfully.
104 @retval EFI_INVALID_PARAMETER A parameter is invalid.
105 @retval EFI_NOT_FOUND The required object information is not found.
106 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
107 Manager is less than the Object size for the
113 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
*CONST CfgMgrProtocol
,
114 IN CONST ACPI_TABLE_GENERATOR
*CONST Generator
,
115 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*CONST AcpiHeader
,
116 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
*CONST AcpiTableInfo
,
117 IN CONST UINT32 Length
121 CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
*CfgMfrInfo
;
123 ASSERT (CfgMgrProtocol
!= NULL
);
124 ASSERT (Generator
!= NULL
);
125 ASSERT (AcpiHeader
!= NULL
);
126 ASSERT (AcpiTableInfo
!= NULL
);
127 ASSERT (Length
>= sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
129 if ((CfgMgrProtocol
== NULL
) ||
130 (Generator
== NULL
) ||
131 (AcpiHeader
== NULL
) ||
132 (AcpiTableInfo
== NULL
) ||
133 (Length
< sizeof (EFI_ACPI_DESCRIPTION_HEADER
))
136 return EFI_INVALID_PARAMETER
;
139 Status
= GetCgfMgrInfo (CfgMgrProtocol
, &CfgMfrInfo
);
140 if (EFI_ERROR (Status
)) {
143 "ERROR: Failed to get Configuration Manager info. Status = %r\n",
150 AcpiHeader
->Signature
= Generator
->AcpiTableSignature
;
152 AcpiHeader
->Length
= Length
;
154 AcpiHeader
->Revision
= AcpiTableInfo
->AcpiTableRevision
;
156 AcpiHeader
->Checksum
= 0;
159 CopyMem (AcpiHeader
->OemId
, CfgMfrInfo
->OemId
, sizeof (AcpiHeader
->OemId
));
162 if (AcpiTableInfo
->OemTableId
!= 0) {
163 AcpiHeader
->OemTableId
= AcpiTableInfo
->OemTableId
;
165 AcpiHeader
->OemTableId
= SIGNATURE_32 (
166 CfgMfrInfo
->OemId
[0],
167 CfgMfrInfo
->OemId
[1],
168 CfgMfrInfo
->OemId
[2],
171 ((UINT64
)Generator
->AcpiTableSignature
<< 32);
174 // UINT32 OemRevision
175 if (AcpiTableInfo
->OemRevision
!= 0) {
176 AcpiHeader
->OemRevision
= AcpiTableInfo
->OemRevision
;
178 AcpiHeader
->OemRevision
= CfgMfrInfo
->Revision
;
182 AcpiHeader
->CreatorId
= Generator
->CreatorId
;
183 // UINT32 CreatorRevision
184 AcpiHeader
->CreatorRevision
= Generator
->CreatorRevision
;
190 /** Build a RootNode containing SSDT ACPI header information using the AmlLib.
192 The function utilizes the ACPI table Generator and the Configuration
193 Manager protocol to obtain any information required for constructing the
194 header. It then creates a RootNode. The SSDT ACPI header is part of the
197 This is essentially a wrapper around AmlCodeGenDefinitionBlock ()
200 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
202 @param [in] Generator Pointer to the ACPI table Generator.
203 @param [in] AcpiTableInfo Pointer to the ACPI table info structure.
204 @param [out] RootNode If success, contains the created RootNode.
205 The SSDT ACPI header is part of the RootNode.
207 @retval EFI_SUCCESS Success.
208 @retval EFI_INVALID_PARAMETER A parameter is invalid.
209 @retval EFI_NOT_FOUND The required object information is not found.
210 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
211 Manager is less than the Object size for the
217 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
*CONST CfgMgrProtocol
,
218 IN CONST ACPI_TABLE_GENERATOR
*CONST Generator
,
219 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
*CONST AcpiTableInfo
,
220 OUT AML_ROOT_NODE_HANDLE
*RootNode
226 CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
*CfgMfrInfo
;
228 ASSERT (CfgMgrProtocol
!= NULL
);
229 ASSERT (Generator
!= NULL
);
230 ASSERT (AcpiTableInfo
!= NULL
);
232 if ((CfgMgrProtocol
== NULL
) ||
233 (Generator
== NULL
) ||
234 (AcpiTableInfo
== NULL
))
236 return EFI_INVALID_PARAMETER
;
239 Status
= GetCgfMgrInfo (CfgMgrProtocol
, &CfgMfrInfo
);
240 if (EFI_ERROR (Status
)) {
243 "ERROR: Failed to get Configuration Manager info. Status = %r\n",
249 if (AcpiTableInfo
->OemTableId
!= 0) {
250 OemTableId
= AcpiTableInfo
->OemTableId
;
252 OemTableId
= SIGNATURE_32 (
253 CfgMfrInfo
->OemId
[0],
254 CfgMfrInfo
->OemId
[1],
255 CfgMfrInfo
->OemId
[2],
258 ((UINT64
)Generator
->AcpiTableSignature
<< 32);
261 if (AcpiTableInfo
->OemRevision
!= 0) {
262 OemRevision
= AcpiTableInfo
->OemRevision
;
264 OemRevision
= CfgMfrInfo
->Revision
;
267 Status
= AmlCodeGenDefinitionBlock (
269 (CONST CHAR8
*)&CfgMfrInfo
->OemId
,
270 (CONST CHAR8
*)&OemTableId
,
274 ASSERT_EFI_ERROR (Status
);
279 Test and report if a duplicate entry exists in the given array of comparable
282 @param [in] Array Array of elements to test for duplicates.
283 @param [in] Count Number of elements in Array.
284 @param [in] ElementSize Size of an element in bytes
285 @param [in] EqualTestFunction The function to call to check if any two
288 @retval TRUE A duplicate element was found or one of
289 the input arguments is invalid.
290 @retval FALSE Every element in Array is unique.
295 IN CONST VOID
*Array
,
296 IN CONST UINTN Count
,
297 IN CONST UINTN ElementSize
,
298 IN PFN_IS_EQUAL EqualTestFunction
307 DEBUG ((DEBUG_ERROR
, "ERROR: FindDuplicateValues: Array is NULL.\n"));
311 if (ElementSize
== 0) {
312 DEBUG ((DEBUG_ERROR
, "ERROR: FindDuplicateValues: ElementSize is 0.\n"));
316 if (EqualTestFunction
== NULL
) {
319 "ERROR: FindDuplicateValues: EqualTestFunction is NULL.\n"
328 for (Index1
= 0; Index1
< Count
- 1; Index1
++) {
329 for (Index2
= Index1
+ 1; Index2
< Count
; Index2
++) {
330 Element1
= (UINT8
*)Array
+ (Index1
* ElementSize
);
331 Element2
= (UINT8
*)Array
+ (Index2
* ElementSize
);
333 if (EqualTestFunction (Element1
, Element2
, Index1
, Index2
)) {