2 ACPI Sdt Protocol Driver
4 Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include "AcpiTable.h"
14 GLOBAL_REMOVE_IF_UNREFERENCED
15 EFI_ACPI_SDT_PROTOCOL mAcpiSdtProtocolTemplate
= {
16 EFI_ACPI_TABLE_VERSION_NONE
,
29 This function returns ACPI Table instance.
31 @return AcpiTableInstance
33 EFI_ACPI_TABLE_INSTANCE
*
34 SdtGetAcpiTableInstance (
42 This function finds the table specified by the buffer.
44 @param[in] Buffer Table buffer to find.
46 @return ACPI table list.
53 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
54 LIST_ENTRY
*CurrentLink
;
55 EFI_ACPI_TABLE_LIST
*CurrentTableList
;
56 LIST_ENTRY
*StartLink
;
59 // Get the instance of the ACPI Table
61 AcpiTableInstance
= SdtGetAcpiTableInstance ();
66 StartLink
= &AcpiTableInstance
->TableList
;
67 CurrentLink
= StartLink
->ForwardLink
;
69 while (CurrentLink
!= StartLink
) {
70 CurrentTableList
= EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink
);
71 if (((UINTN
)CurrentTableList
->Table
<= (UINTN
)Buffer
) &&
72 ((UINTN
)CurrentTableList
->Table
+ CurrentTableList
->TableSize
> (UINTN
)Buffer
))
77 return CurrentTableList
;
80 CurrentLink
= CurrentLink
->ForwardLink
;
87 This function updates AML table checksum.
88 It will search the ACPI table installed by ACPI_TABLE protocol.
90 @param[in] Buffer A piece of AML code buffer pointer.
92 @retval EFI_SUCCESS The table holds the AML buffer is found, and checksum is updated.
93 @retval EFI_NOT_FOUND The table holds the AML buffer is not found.
96 SdtUpdateAmlChecksum (
100 EFI_ACPI_TABLE_LIST
*CurrentTableList
;
102 CurrentTableList
= FindTableByBuffer (Buffer
);
103 if (CurrentTableList
== NULL
) {
104 return EFI_NOT_FOUND
;
107 AcpiPlatformChecksum (
108 (VOID
*)CurrentTableList
->Table
,
109 CurrentTableList
->Table
->Length
,
110 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
, Checksum
)
116 This function finds MAX AML buffer size.
117 It will search the ACPI table installed by ACPI_TABLE protocol.
119 @param[in] Buffer A piece of AML code buffer pointer.
120 @param[out] MaxSize On return it holds the MAX size of buffer.
122 @retval EFI_SUCCESS The table holds the AML buffer is found, and MAX size if returned.
123 @retval EFI_NOT_FOUND The table holds the AML buffer is not found.
126 SdtGetMaxAmlBufferSize (
131 EFI_ACPI_TABLE_LIST
*CurrentTableList
;
133 CurrentTableList
= FindTableByBuffer (Buffer
);
134 if (CurrentTableList
== NULL
) {
135 return EFI_NOT_FOUND
;
138 *MaxSize
= (UINTN
)CurrentTableList
->Table
+ CurrentTableList
->Table
->Length
- (UINTN
)Buffer
;
143 This function invokes ACPI notification.
145 @param[in] AcpiTableInstance Instance to AcpiTable
146 @param[in] Version Version(s) to set.
147 @param[in] Handle Handle of the table.
151 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
152 IN EFI_ACPI_TABLE_VERSION Version
,
156 EFI_ACPI_NOTIFY_LIST
*CurrentNotifyList
;
157 LIST_ENTRY
*CurrentLink
;
158 LIST_ENTRY
*StartLink
;
159 EFI_ACPI_TABLE_LIST
*Table
;
163 // We should not use Table buffer, because it is user input buffer.
165 Status
= FindTableByHandle (
167 &AcpiTableInstance
->TableList
,
170 ASSERT_EFI_ERROR (Status
);
175 StartLink
= &AcpiTableInstance
->NotifyList
;
176 CurrentLink
= StartLink
->ForwardLink
;
178 while (CurrentLink
!= StartLink
) {
179 CurrentNotifyList
= EFI_ACPI_NOTIFY_LIST_FROM_LINK (CurrentLink
);
182 // Inovke notification
184 CurrentNotifyList
->Notification ((EFI_ACPI_SDT_HEADER
*)Table
->Table
, Version
, Handle
);
186 CurrentLink
= CurrentLink
->ForwardLink
;
193 Returns a requested ACPI table.
195 The following structures are not considered elements in the list of
197 - Root System Description Pointer (RSD_PTR)
198 - Root System Description Table (RSDT)
199 - Extended System Description Table (XSDT)
200 Version is updated with a bit map containing all the versions of ACPI of which the table is a
201 member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable() interface,
202 the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.
204 @param[in] AcpiTableInstance ACPI table Instance.
205 @param[in] Index The zero-based index of the table to retrieve.
206 @param[out] Table Pointer for returning the table buffer.
207 @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type
208 EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
209 EFI_ACPI_SDT_PROTOCOL.
210 @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.
211 This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
212 The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()
213 to uninstall the table.
214 @retval EFI_SUCCESS The function completed successfully.
215 @retval EFI_NOT_FOUND The requested index is too large and a table was not found.
219 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
221 OUT EFI_ACPI_SDT_HEADER
**Table
,
222 OUT EFI_ACPI_TABLE_VERSION
*Version
,
227 LIST_ENTRY
*CurrentLink
;
228 LIST_ENTRY
*StartLink
;
229 EFI_ACPI_TABLE_LIST
*CurrentTable
;
234 StartLink
= &AcpiTableInstance
->TableList
;
235 CurrentLink
= StartLink
->ForwardLink
;
238 while (CurrentLink
!= StartLink
) {
239 if (TableIndex
== Index
) {
246 CurrentLink
= CurrentLink
->ForwardLink
;
250 if ((TableIndex
!= Index
) || (CurrentLink
== StartLink
)) {
251 return EFI_NOT_FOUND
;
255 // Get handle and version
257 CurrentTable
= EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink
);
258 *TableKey
= CurrentTable
->Handle
;
259 *Version
= CurrentTable
->Version
;
260 *Table
= (EFI_ACPI_SDT_HEADER
*)CurrentTable
->Table
;
266 Returns a requested ACPI table.
268 The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated
269 with the Index that was input. The following structures are not considered elements in the list of
271 - Root System Description Pointer (RSD_PTR)
272 - Root System Description Table (RSDT)
273 - Extended System Description Table (XSDT)
274 Version is updated with a bit map containing all the versions of ACPI of which the table is a
275 member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable() interface,
276 the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.
278 @param[in] Index The zero-based index of the table to retrieve.
279 @param[out] Table Pointer for returning the table buffer.
280 @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type
281 EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
282 EFI_ACPI_SDT_PROTOCOL.
283 @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.
284 This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
285 The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()
286 to uninstall the table.
287 @retval EFI_SUCCESS The function completed successfully.
288 @retval EFI_NOT_FOUND The requested index is too large and a table was not found.
294 OUT EFI_ACPI_SDT_HEADER
**Table
,
295 OUT EFI_ACPI_TABLE_VERSION
*Version
,
299 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
301 ASSERT (Table
!= NULL
);
302 ASSERT (Version
!= NULL
);
303 ASSERT (TableKey
!= NULL
);
306 // Get the instance of the ACPI Table
308 AcpiTableInstance
= SdtGetAcpiTableInstance ();
310 return SdtGetAcpiTable (AcpiTableInstance
, Index
, Table
, Version
, TableKey
);
314 Register a callback when an ACPI table is installed.
316 This function registers a function which will be called whenever a new ACPI table is installed.
318 @param[in] Notification Points to the callback function to be registered
322 IN EFI_ACPI_NOTIFICATION_FN Notification
325 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
326 EFI_ACPI_NOTIFY_LIST
*CurrentNotifyList
;
329 // Get the instance of the ACPI Table
331 AcpiTableInstance
= SdtGetAcpiTableInstance ();
334 // Create a new list entry
336 CurrentNotifyList
= AllocatePool (sizeof (EFI_ACPI_NOTIFY_LIST
));
337 ASSERT (CurrentNotifyList
!= NULL
);
340 // Initialize the table contents
342 CurrentNotifyList
->Signature
= EFI_ACPI_NOTIFY_LIST_SIGNATURE
;
343 CurrentNotifyList
->Notification
= Notification
;
346 // Add the table to the current list of tables
348 InsertTailList (&AcpiTableInstance
->NotifyList
, &CurrentNotifyList
->Link
);
354 Unregister a callback when an ACPI table is installed.
356 This function unregisters a function which will be called whenever a new ACPI table is installed.
358 @param[in] Notification Points to the callback function to be unregistered.
360 @retval EFI_SUCCESS Callback successfully unregistered.
361 @retval EFI_INVALID_PARAMETER Notification does not match a known registration function.
364 SdtUnregisterNotify (
365 IN EFI_ACPI_NOTIFICATION_FN Notification
368 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
369 EFI_ACPI_NOTIFY_LIST
*CurrentNotifyList
;
370 LIST_ENTRY
*CurrentLink
;
371 LIST_ENTRY
*StartLink
;
374 // Get the instance of the ACPI Table
376 AcpiTableInstance
= SdtGetAcpiTableInstance ();
381 StartLink
= &AcpiTableInstance
->NotifyList
;
382 CurrentLink
= StartLink
->ForwardLink
;
384 while (CurrentLink
!= StartLink
) {
385 CurrentNotifyList
= EFI_ACPI_NOTIFY_LIST_FROM_LINK (CurrentLink
);
386 if (CurrentNotifyList
->Notification
== Notification
) {
388 // Good! Found notification.
390 // Remove it from list and free the node.
392 RemoveEntryList (&(CurrentNotifyList
->Link
));
393 FreePool (CurrentNotifyList
);
397 CurrentLink
= CurrentLink
->ForwardLink
;
403 return EFI_INVALID_PARAMETER
;
407 Register or unregister a callback when an ACPI table is installed.
409 This function registers or unregisters a function which will be called whenever a new ACPI table is
412 @param[in] Register If TRUE, then the specified function will be registered. If FALSE, then the specified
413 function will be unregistered.
414 @param[in] Notification Points to the callback function to be registered or unregistered.
416 @retval EFI_SUCCESS Callback successfully registered or unregistered.
417 @retval EFI_INVALID_PARAMETER Notification is NULL
418 @retval EFI_INVALID_PARAMETER Register is FALSE and Notification does not match a known registration function.
424 IN EFI_ACPI_NOTIFICATION_FN Notification
428 // Check for invalid input parameters
430 if (Notification
== NULL
) {
431 return EFI_INVALID_PARAMETER
;
436 // Register a new notify
438 SdtRegisterNotify (Notification
);
442 // Unregister an old notify
444 return SdtUnregisterNotify (Notification
);
449 Create a handle for the first ACPI opcode in an ACPI system description table.
451 @param[in] TableKey The table key for the ACPI table, as returned by GetTable().
452 @param[out] Handle On return, points to the newly created ACPI handle.
454 @retval EFI_SUCCESS Handle created successfully.
455 @retval EFI_NOT_FOUND TableKey does not refer to a valid ACPI table.
460 OUT EFI_ACPI_HANDLE
*Handle
463 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
465 EFI_ACPI_TABLE_LIST
*Table
;
466 EFI_AML_HANDLE
*AmlHandle
;
469 // Get the instance of the ACPI Table
471 AcpiTableInstance
= SdtGetAcpiTableInstance ();
476 Status
= FindTableByHandle (
478 &AcpiTableInstance
->TableList
,
481 if (EFI_ERROR (Status
)) {
482 return EFI_NOT_FOUND
;
485 AmlHandle
= AllocatePool (sizeof (*AmlHandle
));
486 ASSERT (AmlHandle
!= NULL
);
487 AmlHandle
->Signature
= EFI_AML_ROOT_HANDLE_SIGNATURE
;
488 AmlHandle
->Buffer
= (VOID
*)((UINTN
)Table
->Table
+ sizeof (EFI_ACPI_SDT_HEADER
));
489 AmlHandle
->Size
= Table
->Table
->Length
- sizeof (EFI_ACPI_SDT_HEADER
);
490 AmlHandle
->AmlByteEncoding
= NULL
;
491 AmlHandle
->Modified
= FALSE
;
494 // return the ACPI handle
496 *Handle
= (EFI_ACPI_HANDLE
)AmlHandle
;
502 Create a handle for the first ACPI opcode in an ACPI system description table.
504 @param[in] TableKey The table key for the ACPI table, as returned by GetTable().
505 @param[out] Handle On return, points to the newly created ACPI handle.
507 @retval EFI_SUCCESS Handle created successfully.
508 @retval EFI_NOT_FOUND TableKey does not refer to a valid ACPI table.
514 OUT EFI_ACPI_HANDLE
*Handle
517 if (Handle
== NULL
) {
518 return EFI_INVALID_PARAMETER
;
521 return SdtOpenSdtTable (TableKey
, Handle
);
525 Create a handle from an ACPI opcode
527 @param[in] Buffer Points to the ACPI opcode.
528 @param[in] BufferSize Max buffer size.
529 @param[out] Handle Upon return, holds the handle.
531 @retval EFI_SUCCESS Success
532 @retval EFI_INVALID_PARAMETER Buffer is NULL or Handle is NULL or Buffer points to an
540 OUT EFI_ACPI_HANDLE
*Handle
543 AML_BYTE_ENCODING
*AmlByteEncoding
;
544 EFI_AML_HANDLE
*AmlHandle
;
546 AmlByteEncoding
= AmlSearchByOpByte (Buffer
);
547 if (AmlByteEncoding
== NULL
) {
548 return EFI_INVALID_PARAMETER
;
552 // Do not open NameString as handle
554 if ((AmlByteEncoding
->Attribute
& AML_IS_NAME_CHAR
) != 0) {
555 return EFI_INVALID_PARAMETER
;
561 AmlHandle
= AllocatePool (sizeof (*AmlHandle
));
562 ASSERT (AmlHandle
!= NULL
);
564 AmlHandle
->Signature
= EFI_AML_HANDLE_SIGNATURE
;
565 AmlHandle
->Buffer
= Buffer
;
566 AmlHandle
->AmlByteEncoding
= AmlByteEncoding
;
567 AmlHandle
->Modified
= FALSE
;
569 AmlHandle
->Size
= AmlGetObjectSize (AmlByteEncoding
, Buffer
, BufferSize
);
570 if (AmlHandle
->Size
== 0) {
571 FreePool (AmlHandle
);
572 return EFI_INVALID_PARAMETER
;
575 *Handle
= (EFI_ACPI_HANDLE
)AmlHandle
;
581 Create a handle from an ACPI opcode
583 @param[in] Buffer Points to the ACPI opcode.
584 @param[out] Handle Upon return, holds the handle.
586 @retval EFI_SUCCESS Success
587 @retval EFI_INVALID_PARAMETER Buffer is NULL or Handle is NULL or Buffer points to an
595 OUT EFI_ACPI_HANDLE
*Handle
604 // Check for invalid input parameters
606 if ((Buffer
== NULL
) || (Handle
== NULL
)) {
607 return EFI_INVALID_PARAMETER
;
610 Status
= SdtGetMaxAmlBufferSize (Buffer
, &MaxSize
);
611 if (EFI_ERROR (Status
)) {
612 return EFI_INVALID_PARAMETER
;
615 return SdtOpenEx (Buffer
, MaxSize
, Handle
);
619 Close an ACPI handle.
621 @param[in] Handle Returns the handle.
623 @retval EFI_SUCCESS Success
624 @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
629 IN EFI_ACPI_HANDLE Handle
632 EFI_AML_HANDLE
*AmlHandle
;
636 // Check for invalid input parameters
638 if (Handle
== NULL
) {
639 return EFI_INVALID_PARAMETER
;
642 AmlHandle
= (EFI_AML_HANDLE
*)Handle
;
643 if ((AmlHandle
->Signature
!= EFI_AML_ROOT_HANDLE_SIGNATURE
) &&
644 (AmlHandle
->Signature
!= EFI_AML_HANDLE_SIGNATURE
))
646 return EFI_INVALID_PARAMETER
;
650 // Update Checksum only if modified
652 if (AmlHandle
->Modified
) {
653 Status
= SdtUpdateAmlChecksum (AmlHandle
->Buffer
);
654 if (EFI_ERROR (Status
)) {
655 return EFI_INVALID_PARAMETER
;
659 FreePool (AmlHandle
);
665 Retrieve information about an ACPI object.
667 @param[in] Handle ACPI object handle.
668 @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
669 in the ACPI encoding, with index 0 always being the ACPI opcode.
670 @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
671 for the specified index.
672 @param[out] Data Upon return, points to the pointer to the data.
673 @param[out] DataSize Upon return, points to the size of Data.
675 @retval EFI_SUCCESS Success.
676 @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
681 IN EFI_ACPI_HANDLE Handle
,
683 OUT EFI_ACPI_DATA_TYPE
*DataType
,
684 OUT CONST VOID
**Data
,
688 EFI_AML_HANDLE
*AmlHandle
;
689 AML_BYTE_ENCODING
*AmlByteEncoding
;
692 ASSERT (DataType
!= NULL
);
693 ASSERT (Data
!= NULL
);
694 ASSERT (DataSize
!= NULL
);
697 // Check for invalid input parameters
699 if (Handle
== NULL
) {
700 return EFI_INVALID_PARAMETER
;
703 AmlHandle
= (EFI_AML_HANDLE
*)Handle
;
705 // Do not check EFI_AML_ROOT_HANDLE_SIGNATURE because there is no option for Root handle
707 if (AmlHandle
->Signature
!= EFI_AML_HANDLE_SIGNATURE
) {
708 return EFI_INVALID_PARAMETER
;
711 AmlByteEncoding
= AmlHandle
->AmlByteEncoding
;
712 if (Index
> AmlByteEncoding
->MaxIndex
) {
713 *DataType
= EFI_ACPI_DATA_TYPE_NONE
;
720 Status
= AmlParseOptionHandleCommon (AmlHandle
, (AML_OP_PARSE_INDEX
)Index
, DataType
, (VOID
**)Data
, DataSize
);
721 if (EFI_ERROR (Status
)) {
722 return EFI_INVALID_PARAMETER
;
729 Change information about an ACPI object.
731 @param[in] Handle ACPI object handle.
732 @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
733 in the ACPI encoding, with index 0 always being the ACPI opcode.
734 @param[in] Data Points to the data.
735 @param[in] DataSize The size of the Data.
737 @retval EFI_SUCCESS Success
738 @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
739 @retval EFI_BAD_BUFFER_SIZE Data cannot be accommodated in the space occupied by
746 IN EFI_ACPI_HANDLE Handle
,
752 EFI_AML_HANDLE
*AmlHandle
;
753 AML_BYTE_ENCODING
*AmlByteEncoding
;
755 EFI_ACPI_DATA_TYPE DataType
;
759 ASSERT (Data
!= NULL
);
762 // Check for invalid input parameters
764 if (Handle
== NULL
) {
765 return EFI_INVALID_PARAMETER
;
768 AmlHandle
= (EFI_AML_HANDLE
*)Handle
;
770 // Do not check EFI_AML_ROOT_HANDLE_SIGNATURE because there is no option for Root handle
772 if (AmlHandle
->Signature
!= EFI_AML_HANDLE_SIGNATURE
) {
773 return EFI_INVALID_PARAMETER
;
776 AmlByteEncoding
= AmlHandle
->AmlByteEncoding
;
778 if (Index
> AmlByteEncoding
->MaxIndex
) {
779 return EFI_INVALID_PARAMETER
;
785 Status
= AmlParseOptionHandleCommon (AmlHandle
, (AML_OP_PARSE_INDEX
)Index
, &DataType
, &OrgData
, &OrgDataSize
);
786 if (EFI_ERROR (Status
)) {
787 return EFI_INVALID_PARAMETER
;
790 if (DataType
== EFI_ACPI_DATA_TYPE_NONE
) {
791 return EFI_INVALID_PARAMETER
;
794 if (DataSize
> OrgDataSize
) {
795 return EFI_BAD_BUFFER_SIZE
;
801 CopyMem (OrgData
, Data
, DataSize
);
802 AmlHandle
->Modified
= TRUE
;
808 Return the child ACPI objects.
810 @param[in] ParentHandle Parent handle.
811 @param[in, out] Handle On entry, points to the previously returned handle or NULL to start with the first
812 handle. On return, points to the next returned ACPI handle or NULL if there are no
815 @retval EFI_SUCCESS Success
816 @retval EFI_INVALID_PARAMETER ParentHandle is NULL or does not refer to a valid ACPI object.
821 IN EFI_ACPI_HANDLE ParentHandle
,
822 IN OUT EFI_ACPI_HANDLE
*Handle
825 EFI_AML_HANDLE
*AmlParentHandle
;
826 EFI_AML_HANDLE
*AmlHandle
;
830 ASSERT (Handle
!= NULL
);
833 // Check for invalid input parameters
835 if (ParentHandle
== NULL
) {
836 return EFI_INVALID_PARAMETER
;
840 if ((AmlHandle
!= NULL
) && (AmlHandle
->Signature
!= EFI_AML_HANDLE_SIGNATURE
)) {
841 return EFI_INVALID_PARAMETER
;
844 AmlParentHandle
= (EFI_AML_HANDLE
*)ParentHandle
;
845 if (AmlParentHandle
->Signature
== EFI_AML_ROOT_HANDLE_SIGNATURE
) {
849 Status
= AmlGetChildFromRoot (AmlParentHandle
, AmlHandle
, &Buffer
);
850 } else if (AmlParentHandle
->Signature
== EFI_AML_HANDLE_SIGNATURE
) {
854 Status
= AmlGetChildFromNonRoot (AmlParentHandle
, AmlHandle
, &Buffer
);
859 return EFI_INVALID_PARAMETER
;
862 if (EFI_ERROR (Status
)) {
863 return EFI_INVALID_PARAMETER
;
866 if (Buffer
== NULL
) {
871 return SdtOpenEx (Buffer
, (UINTN
)AmlParentHandle
->Buffer
+ AmlParentHandle
->Size
- (UINTN
)Buffer
, Handle
);
875 Returns the handle of the ACPI object representing the specified ACPI path
877 @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
878 @param[in] AmlPath Points to the AML path.
879 @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
882 @retval EFI_SUCCESS Success
883 @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
886 SdtFindPathFromNonRoot (
887 IN EFI_ACPI_HANDLE HandleIn
,
889 OUT EFI_ACPI_HANDLE
*HandleOut
892 EFI_AML_HANDLE
*AmlHandle
;
897 AmlHandle
= (EFI_AML_HANDLE
*)HandleIn
;
900 // For non-root handle, we need search from THIS node instead of ROOT.
902 Status
= AmlFindPath (AmlHandle
, AmlPath
, &Buffer
, FALSE
);
903 if (EFI_ERROR (Status
)) {
904 return EFI_INVALID_PARAMETER
;
907 if (Buffer
== NULL
) {
912 return SdtOpenEx (Buffer
, (UINTN
)AmlHandle
->Buffer
+ AmlHandle
->Size
- (UINTN
)Buffer
, HandleOut
);
916 Duplicate AML handle.
918 @param[in] AmlHandle Handle to be duplicated.
920 @return Duplicated AML handle.
924 IN EFI_AML_HANDLE
*AmlHandle
927 EFI_AML_HANDLE
*DstAmlHandle
;
929 DstAmlHandle
= AllocatePool (sizeof (*DstAmlHandle
));
930 ASSERT (DstAmlHandle
!= NULL
);
931 CopyMem (DstAmlHandle
, (VOID
*)AmlHandle
, sizeof (*DstAmlHandle
));
937 Returns the handle of the ACPI object representing the specified ACPI path
939 @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
940 @param[in] AmlPath Points to the AML path.
941 @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
944 @retval EFI_SUCCESS Success
945 @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
948 SdtFindPathFromRoot (
949 IN EFI_ACPI_HANDLE HandleIn
,
951 OUT EFI_ACPI_HANDLE
*HandleOut
954 EFI_ACPI_HANDLE ChildHandle
;
955 EFI_AML_HANDLE
*AmlHandle
;
960 AmlHandle
= (EFI_AML_HANDLE
*)HandleIn
;
963 // Handle case that AcpiPath is Root
965 if (AmlIsRootPath (AmlPath
)) {
967 // Duplicate RootHandle
969 *HandleOut
= (EFI_ACPI_HANDLE
)SdtDuplicateHandle (AmlHandle
);
974 // Let children find it.
978 Status
= GetChild (HandleIn
, &ChildHandle
);
979 if (EFI_ERROR (Status
)) {
980 return EFI_INVALID_PARAMETER
;
983 if (ChildHandle
== NULL
) {
994 AmlHandle
= (EFI_AML_HANDLE
*)ChildHandle
;
995 Status
= AmlFindPath (AmlHandle
, AmlPath
, &Buffer
, TRUE
);
996 if (EFI_ERROR (Status
)) {
997 return EFI_INVALID_PARAMETER
;
1000 if (Buffer
!= NULL
) {
1002 // Great! Find it, open
1004 Status
= SdtOpenEx (Buffer
, (UINTN
)AmlHandle
->Buffer
+ AmlHandle
->Size
- (UINTN
)Buffer
, HandleOut
);
1005 if (!EFI_ERROR (Status
)) {
1010 // Not success, try next one
1016 // Should not run here
1021 Returns the handle of the ACPI object representing the specified ACPI path
1023 @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
1024 @param[in] AcpiPath Points to the ACPI path, which conforms to the ACPI encoded path format.
1025 @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
1028 @retval EFI_SUCCESS Success
1029 @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
1034 IN EFI_ACPI_HANDLE HandleIn
,
1036 OUT EFI_ACPI_HANDLE
*HandleOut
1039 EFI_AML_HANDLE
*AmlHandle
;
1044 // Check for invalid input parameters
1046 if (HandleIn
== NULL
) {
1047 return EFI_INVALID_PARAMETER
;
1050 AmlHandle
= (EFI_AML_HANDLE
*)HandleIn
;
1053 // Convert ASL path to AML path
1055 AmlPath
= AmlNameFromAslName (AcpiPath
);
1056 if (AmlPath
== NULL
) {
1057 return EFI_INVALID_PARAMETER
;
1060 DEBUG_CODE_BEGIN ();
1061 DEBUG ((DEBUG_ERROR
, "AcpiSdt: FindPath - "));
1062 AmlPrintNameString (AmlPath
);
1063 DEBUG ((DEBUG_ERROR
, "\n"));
1066 if (AmlHandle
->Signature
== EFI_AML_ROOT_HANDLE_SIGNATURE
) {
1070 Status
= SdtFindPathFromRoot (HandleIn
, AmlPath
, HandleOut
);
1071 } else if (AmlHandle
->Signature
== EFI_AML_HANDLE_SIGNATURE
) {
1075 Status
= SdtFindPathFromNonRoot (HandleIn
, AmlPath
, HandleOut
);
1077 Status
= EFI_INVALID_PARAMETER
;
1086 This function initializes AcpiSdt protocol in ACPI table instance.
1088 @param[in] AcpiTableInstance Instance to construct
1091 SdtAcpiTableAcpiSdtConstructor (
1092 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
1095 InitializeListHead (&AcpiTableInstance
->NotifyList
);
1096 CopyMem (&AcpiTableInstance
->AcpiSdtProtocol
, &mAcpiSdtProtocolTemplate
, sizeof (mAcpiSdtProtocolTemplate
));
1097 AcpiTableInstance
->AcpiSdtProtocol
.AcpiVersion
= (EFI_ACPI_TABLE_VERSION
)PcdGet32 (PcdAcpiExposedTableVersions
);