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
)) {
78 "ERROR: EStdObjCfgMgrInfo: Buffer too small, size = 0x%x\n",
82 return EFI_BAD_BUFFER_SIZE
;
85 *CfgMfrInfo
= (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
*)CmObjectDesc
.Data
;
89 /** The AddAcpiHeader function updates the ACPI header structure pointed by
90 the AcpiHeader. It utilizes the ACPI table Generator and the Configuration
91 Manager protocol to obtain any information required for constructing the
94 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
96 @param [in] Generator Pointer to the ACPI table Generator.
97 @param [in,out] AcpiHeader Pointer to the ACPI table header to be
99 @param [in] AcpiTableInfo Pointer to the ACPI table info structure.
100 @param [in] Length Length of the ACPI table.
102 @retval EFI_SUCCESS The ACPI table is updated successfully.
103 @retval EFI_INVALID_PARAMETER A parameter is invalid.
104 @retval EFI_NOT_FOUND The required object information is not found.
105 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
106 Manager is less than the Object size for the
112 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
113 IN CONST ACPI_TABLE_GENERATOR
* CONST Generator
,
114 IN OUT EFI_ACPI_DESCRIPTION_HEADER
* CONST AcpiHeader
,
115 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
* CONST AcpiTableInfo
,
116 IN CONST UINT32 Length
120 CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
* CfgMfrInfo
;
122 ASSERT (CfgMgrProtocol
!= NULL
);
123 ASSERT (Generator
!= NULL
);
124 ASSERT (AcpiHeader
!= NULL
);
125 ASSERT (AcpiTableInfo
!= NULL
);
126 ASSERT (Length
>= sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
128 if ((CfgMgrProtocol
== NULL
) ||
129 (Generator
== NULL
) ||
130 (AcpiHeader
== NULL
) ||
131 (AcpiTableInfo
== NULL
) ||
132 (Length
< sizeof (EFI_ACPI_DESCRIPTION_HEADER
))
134 return EFI_INVALID_PARAMETER
;
137 Status
= GetCgfMgrInfo (CfgMgrProtocol
, &CfgMfrInfo
);
138 if (EFI_ERROR (Status
)) {
141 "ERROR: Failed to get Configuration Manager info. Status = %r\n",
148 AcpiHeader
->Signature
= Generator
->AcpiTableSignature
;
150 AcpiHeader
->Length
= Length
;
152 AcpiHeader
->Revision
= AcpiTableInfo
->AcpiTableRevision
;
154 AcpiHeader
->Checksum
= 0;
157 CopyMem (AcpiHeader
->OemId
, CfgMfrInfo
->OemId
, sizeof (AcpiHeader
->OemId
));
160 if (AcpiTableInfo
->OemTableId
!= 0) {
161 AcpiHeader
->OemTableId
= AcpiTableInfo
->OemTableId
;
163 AcpiHeader
->OemTableId
= SIGNATURE_32 (
164 CfgMfrInfo
->OemId
[0],
165 CfgMfrInfo
->OemId
[1],
166 CfgMfrInfo
->OemId
[2],
169 ((UINT64
)Generator
->AcpiTableSignature
<< 32);
172 // UINT32 OemRevision
173 if (AcpiTableInfo
->OemRevision
!= 0) {
174 AcpiHeader
->OemRevision
= AcpiTableInfo
->OemRevision
;
176 AcpiHeader
->OemRevision
= CfgMfrInfo
->Revision
;
180 AcpiHeader
->CreatorId
= Generator
->CreatorId
;
181 // UINT32 CreatorRevision
182 AcpiHeader
->CreatorRevision
= Generator
->CreatorRevision
;
188 /** Build a RootNode containing SSDT ACPI header information using the AmlLib.
190 The function utilizes the ACPI table Generator and the Configuration
191 Manager protocol to obtain any information required for constructing the
192 header. It then creates a RootNode. The SSDT ACPI header is part of the
195 This is essentially a wrapper around AmlCodeGenDefinitionBlock ()
198 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
200 @param [in] Generator Pointer to the ACPI table Generator.
201 @param [in] AcpiTableInfo Pointer to the ACPI table info structure.
202 @param [out] RootNode If success, contains the created RootNode.
203 The SSDT ACPI header is part of the RootNode.
205 @retval EFI_SUCCESS Success.
206 @retval EFI_INVALID_PARAMETER A parameter is invalid.
207 @retval EFI_NOT_FOUND The required object information is not found.
208 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
209 Manager is less than the Object size for the
215 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
216 IN CONST ACPI_TABLE_GENERATOR
* CONST Generator
,
217 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
* CONST AcpiTableInfo
,
218 OUT AML_ROOT_NODE_HANDLE
* RootNode
224 CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
* CfgMfrInfo
;
226 ASSERT (CfgMgrProtocol
!= NULL
);
227 ASSERT (Generator
!= NULL
);
228 ASSERT (AcpiTableInfo
!= NULL
);
230 if ((CfgMgrProtocol
== NULL
) ||
231 (Generator
== NULL
) ||
232 (AcpiTableInfo
== NULL
)) {
233 return EFI_INVALID_PARAMETER
;
236 Status
= GetCgfMgrInfo (CfgMgrProtocol
, &CfgMfrInfo
);
237 if (EFI_ERROR (Status
)) {
240 "ERROR: Failed to get Configuration Manager info. Status = %r\n",
246 if (AcpiTableInfo
->OemTableId
!= 0) {
247 OemTableId
= AcpiTableInfo
->OemTableId
;
249 OemTableId
= SIGNATURE_32 (
250 CfgMfrInfo
->OemId
[0],
251 CfgMfrInfo
->OemId
[1],
252 CfgMfrInfo
->OemId
[2],
255 ((UINT64
)Generator
->AcpiTableSignature
<< 32);
258 if (AcpiTableInfo
->OemRevision
!= 0) {
259 OemRevision
= AcpiTableInfo
->OemRevision
;
261 OemRevision
= CfgMfrInfo
->Revision
;
264 Status
= AmlCodeGenDefinitionBlock (
266 (CONST CHAR8
*)&CfgMfrInfo
->OemId
,
267 (CONST CHAR8
*)&OemTableId
,
271 ASSERT_EFI_ERROR (Status
);
276 Test and report if a duplicate entry exists in the given array of comparable
279 @param [in] Array Array of elements to test for duplicates.
280 @param [in] Count Number of elements in Array.
281 @param [in] ElementSize Size of an element in bytes
282 @param [in] EqualTestFunction The function to call to check if any two
285 @retval TRUE A duplicate element was found or one of
286 the input arguments is invalid.
287 @retval FALSE Every element in Array is unique.
292 IN CONST VOID
* Array
,
293 IN CONST UINTN Count
,
294 IN CONST UINTN ElementSize
,
295 IN PFN_IS_EQUAL EqualTestFunction
304 DEBUG ((DEBUG_ERROR
, "ERROR: FindDuplicateValues: Array is NULL.\n"));
308 if (ElementSize
== 0) {
309 DEBUG ((DEBUG_ERROR
, "ERROR: FindDuplicateValues: ElementSize is 0.\n"));
313 if (EqualTestFunction
== NULL
) {
316 "ERROR: FindDuplicateValues: EqualTestFunction is NULL.\n"
325 for (Index1
= 0; Index1
< Count
- 1; Index1
++) {
326 for (Index2
= Index1
+ 1; Index2
< Count
; Index2
++) {
327 Element1
= (UINT8
*)Array
+ (Index1
* ElementSize
);
328 Element2
= (UINT8
*)Array
+ (Index2
* ElementSize
);
330 if (EqualTestFunction (Element1
, Element2
, Index1
, Index2
)) {