2 ACPI Sdt Protocol Driver
4 Copyright (c) 2010, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "AcpiTable.h"
20 GLOBAL_REMOVE_IF_UNREFERENCED
21 EFI_ACPI_SDT_PROTOCOL mAcpiSdtProtocolTemplate
= {
22 EFI_ACPI_TABLE_VERSION_NONE
| EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
| EFI_ACPI_TABLE_VERSION_4_0
,
35 This function returns ACPI Table instance.
37 @return AcpiTableInstance
39 EFI_ACPI_TABLE_INSTANCE
*
40 SdtGetAcpiTableInstance (
48 This function finds the table specified by the buffer.
50 @param[in] Buffer Table buffer to find.
52 @return ACPI table list.
59 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
60 LIST_ENTRY
*CurrentLink
;
61 EFI_ACPI_TABLE_LIST
*CurrentTableList
;
62 LIST_ENTRY
*StartLink
;
65 // Get the instance of the ACPI Table
67 AcpiTableInstance
= SdtGetAcpiTableInstance ();
72 StartLink
= &AcpiTableInstance
->TableList
;
73 CurrentLink
= StartLink
->ForwardLink
;
75 while (CurrentLink
!= StartLink
) {
76 CurrentTableList
= EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink
);
77 if (((UINTN
)CurrentTableList
->PageAddress
<= (UINTN
)Buffer
) &&
78 ((UINTN
)CurrentTableList
->PageAddress
+ EFI_PAGES_TO_SIZE(CurrentTableList
->NumberOfPages
) > (UINTN
)Buffer
)) {
82 return CurrentTableList
;
85 CurrentLink
= CurrentLink
->ForwardLink
;
92 This function updates AML table checksum.
93 It will search the ACPI table installed by ACPI_TABLE protocol.
95 @param[in] Buffer A piece of AML code buffer pointer.
97 @retval EFI_SUCCESS The table holds the AML buffer is found, and checksum is updated.
98 @retval EFI_NOT_FOUND The table holds the AML buffer is not found.
101 SdtUpdateAmlChecksum (
105 EFI_ACPI_TABLE_LIST
*CurrentTableList
;
107 CurrentTableList
= FindTableByBuffer (Buffer
);
108 if (CurrentTableList
== NULL
) {
109 return EFI_NOT_FOUND
;
112 AcpiPlatformChecksum (
113 (VOID
*)CurrentTableList
->Table
,
114 CurrentTableList
->Table
->Length
,
115 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
, Checksum
)
121 This function finds MAX AML buffer size.
122 It will search the ACPI table installed by ACPI_TABLE protocol.
124 @param[in] Buffer A piece of AML code buffer pointer.
125 @param[out] MaxSize On return it holds the MAX size of buffer.
127 @retval EFI_SUCCESS The table holds the AML buffer is found, and MAX size if returned.
128 @retval EFI_NOT_FOUND The table holds the AML buffer is not found.
131 SdtGetMaxAmlBufferSize (
136 EFI_ACPI_TABLE_LIST
*CurrentTableList
;
138 CurrentTableList
= FindTableByBuffer (Buffer
);
139 if (CurrentTableList
== NULL
) {
140 return EFI_NOT_FOUND
;
143 *MaxSize
= (UINTN
)CurrentTableList
->Table
+ CurrentTableList
->Table
->Length
- (UINTN
)Buffer
;
148 This function invokes ACPI notification.
150 @param[in] AcpiTableInstance Instance to AcpiTable
151 @param[in] Version Version(s) to set.
152 @param[in] Handle Handle of the table.
156 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
157 IN EFI_ACPI_TABLE_VERSION Version
,
161 EFI_ACPI_NOTIFY_LIST
*CurrentNotifyList
;
162 LIST_ENTRY
*CurrentLink
;
163 LIST_ENTRY
*StartLink
;
164 EFI_ACPI_TABLE_LIST
*Table
;
168 // We should not use Table buffer, because it is user input buffer.
170 Status
= FindTableByHandle (
172 &AcpiTableInstance
->TableList
,
175 ASSERT_EFI_ERROR (Status
);
180 StartLink
= &AcpiTableInstance
->NotifyList
;
181 CurrentLink
= StartLink
->ForwardLink
;
183 while (CurrentLink
!= StartLink
) {
184 CurrentNotifyList
= EFI_ACPI_NOTIFY_LIST_FROM_LINK (CurrentLink
);
187 // Inovke notification
189 CurrentNotifyList
->Notification ((EFI_ACPI_SDT_HEADER
*)Table
->Table
, Version
, Handle
);
191 CurrentLink
= CurrentLink
->ForwardLink
;
198 Returns a requested ACPI table.
200 The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated
201 with the Index that was input. The following structures are not considered elements in the list of
203 - Root System Description Pointer (RSD_PTR)
204 - Root System Description Table (RSDT)
205 - Extended System Description Table (XSDT)
206 Version is updated with a bit map containing all the versions of ACPI of which the table is a
209 @param[in] Index The zero-based index of the table to retrieve.
210 @param[out] Table Pointer for returning the table buffer.
211 @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type
212 EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
213 EFI_ACPI_SDT_PROTOCOL.
214 @param[out] TableKey On return, points to the table key for the specified ACPI system definition table. This
215 is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
217 @retval EFI_SUCCESS The function completed successfully.
218 @retval EFI_NOT_FOUND The requested index is too large and a table was not found.
224 OUT EFI_ACPI_SDT_HEADER
**Table
,
225 OUT EFI_ACPI_TABLE_VERSION
*Version
,
229 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
231 LIST_ENTRY
*CurrentLink
;
232 LIST_ENTRY
*StartLink
;
233 EFI_ACPI_TABLE_LIST
*CurrentTable
;
235 ASSERT (Table
!= NULL
);
236 ASSERT (Version
!= NULL
);
237 ASSERT (TableKey
!= NULL
);
240 // Get the instance of the ACPI Table
242 AcpiTableInstance
= SdtGetAcpiTableInstance ();
247 StartLink
= &AcpiTableInstance
->TableList
;
248 CurrentLink
= StartLink
->ForwardLink
;
251 while (CurrentLink
!= StartLink
) {
252 if (TableIndex
== Index
) {
258 CurrentLink
= CurrentLink
->ForwardLink
;
262 if ((TableIndex
!= Index
) || (CurrentLink
== StartLink
)) {
263 return EFI_NOT_FOUND
;
267 // Get handle and version
269 CurrentTable
= EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink
);
270 *TableKey
= CurrentTable
->Handle
;
271 *Version
= CurrentTable
->Version
;
272 *Table
= (EFI_ACPI_SDT_HEADER
*)CurrentTable
->Table
;
278 Register a callback when an ACPI table is installed.
280 This function registers a function which will be called whenever a new ACPI table is installed.
282 @param[in] Notification Points to the callback function to be registered
286 IN EFI_ACPI_NOTIFICATION_FN Notification
289 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
290 EFI_ACPI_NOTIFY_LIST
*CurrentNotifyList
;
293 // Get the instance of the ACPI Table
295 AcpiTableInstance
= SdtGetAcpiTableInstance ();
298 // Create a new list entry
300 CurrentNotifyList
= AllocatePool (sizeof (EFI_ACPI_NOTIFY_LIST
));
301 ASSERT (CurrentNotifyList
!= NULL
);
304 // Initialize the table contents
306 CurrentNotifyList
->Signature
= EFI_ACPI_NOTIFY_LIST_SIGNATURE
;
307 CurrentNotifyList
->Notification
= Notification
;
310 // Add the table to the current list of tables
312 InsertTailList (&AcpiTableInstance
->NotifyList
, &CurrentNotifyList
->Link
);
318 Unregister a callback when an ACPI table is installed.
320 This function unregisters a function which will be called whenever a new ACPI table is installed.
322 @param[in] Notification Points to the callback function to be unregistered.
324 @retval EFI_SUCCESS Callback successfully unregistered.
325 @retval EFI_INVALID_PARAMETER Notification does not match a known registration function.
328 SdtUnregisterNotify (
329 IN EFI_ACPI_NOTIFICATION_FN Notification
332 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
333 EFI_ACPI_NOTIFY_LIST
*CurrentNotifyList
;
334 LIST_ENTRY
*CurrentLink
;
335 LIST_ENTRY
*StartLink
;
338 // Get the instance of the ACPI Table
340 AcpiTableInstance
= SdtGetAcpiTableInstance ();
345 StartLink
= &AcpiTableInstance
->NotifyList
;
346 CurrentLink
= StartLink
->ForwardLink
;
348 while (CurrentLink
!= StartLink
) {
349 CurrentNotifyList
= EFI_ACPI_NOTIFY_LIST_FROM_LINK (CurrentLink
);
350 if (CurrentNotifyList
->Notification
== Notification
) {
352 // Good! Found notification.
354 // Remove it from list and free the node.
356 RemoveEntryList (&(CurrentNotifyList
->Link
));
357 FreePool (CurrentNotifyList
);
361 CurrentLink
= CurrentLink
->ForwardLink
;
367 return EFI_INVALID_PARAMETER
;
371 Register or unregister a callback when an ACPI table is installed.
373 This function registers or unregisters a function which will be called whenever a new ACPI table is
376 @param[in] Register If TRUE, then the specified function will be registered. If FALSE, then the specified
377 function will be unregistered.
378 @param[in] Notification Points to the callback function to be registered or unregistered.
380 @retval EFI_SUCCESS Callback successfully registered or unregistered.
381 @retval EFI_INVALID_PARAMETER Notification is NULL
382 @retval EFI_INVALID_PARAMETER Register is FALSE and Notification does not match a known registration function.
388 IN EFI_ACPI_NOTIFICATION_FN Notification
392 // Check for invalid input parameters
394 if (Notification
== NULL
) {
395 return EFI_INVALID_PARAMETER
;
400 // Register a new notify
402 SdtRegisterNotify (Notification
);
406 // Unregister an old notify
408 return SdtUnregisterNotify (Notification
);
413 Create a handle for the first ACPI opcode in an ACPI system description table.
415 @param[in] TableKey The table key for the ACPI table, as returned by GetTable().
416 @param[out] Handle On return, points to the newly created ACPI handle.
418 @retval EFI_SUCCESS Handle created successfully.
419 @retval EFI_NOT_FOUND TableKey does not refer to a valid ACPI table.
424 OUT EFI_ACPI_HANDLE
*Handle
427 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
429 EFI_ACPI_TABLE_LIST
*Table
;
430 EFI_AML_HANDLE
*AmlHandle
;
433 // Get the instance of the ACPI Table
435 AcpiTableInstance
= SdtGetAcpiTableInstance ();
440 Status
= FindTableByHandle (
442 &AcpiTableInstance
->TableList
,
445 if (EFI_ERROR (Status
)) {
446 return EFI_NOT_FOUND
;
449 AmlHandle
= AllocatePool (sizeof(*AmlHandle
));
450 ASSERT (AmlHandle
!= NULL
);
451 AmlHandle
->Signature
= EFI_AML_ROOT_HANDLE_SIGNATURE
;
452 AmlHandle
->Buffer
= (VOID
*)((UINTN
)Table
->Table
+ sizeof(EFI_ACPI_SDT_HEADER
));
453 AmlHandle
->Size
= Table
->Table
->Length
- sizeof(EFI_ACPI_SDT_HEADER
);
454 AmlHandle
->AmlByteEncoding
= NULL
;
455 AmlHandle
->Modified
= FALSE
;
458 // return the ACPI handle
460 *Handle
= (EFI_ACPI_HANDLE
)AmlHandle
;
466 Create a handle for the first ACPI opcode in an ACPI system description table.
468 @param[in] TableKey The table key for the ACPI table, as returned by GetTable().
469 @param[out] Handle On return, points to the newly created ACPI handle.
471 @retval EFI_SUCCESS Handle created successfully.
472 @retval EFI_NOT_FOUND TableKey does not refer to a valid ACPI table.
478 OUT EFI_ACPI_HANDLE
*Handle
481 if (Handle
== NULL
) {
482 return EFI_INVALID_PARAMETER
;
485 return SdtOpenSdtTable (TableKey
, Handle
);
489 Create a handle from an ACPI opcode
491 @param[in] Buffer Points to the ACPI opcode.
492 @param[in] BufferSize Max buffer size.
493 @param[out] Handle Upon return, holds the handle.
495 @retval EFI_SUCCESS Success
496 @retval EFI_INVALID_PARAMETER Buffer is NULL or Handle is NULL or Buffer points to an
504 OUT EFI_ACPI_HANDLE
*Handle
507 AML_BYTE_ENCODING
*AmlByteEncoding
;
508 EFI_AML_HANDLE
*AmlHandle
;
510 AmlByteEncoding
= AmlSearchByOpByte (Buffer
);
511 if (AmlByteEncoding
== NULL
) {
512 return EFI_INVALID_PARAMETER
;
516 // Do not open NameString as handle
518 if ((AmlByteEncoding
->Attribute
& AML_IS_NAME_CHAR
) != 0) {
519 return EFI_INVALID_PARAMETER
;
525 AmlHandle
= AllocatePool (sizeof(*AmlHandle
));
526 ASSERT (AmlHandle
!= NULL
);
528 AmlHandle
->Signature
= EFI_AML_HANDLE_SIGNATURE
;
529 AmlHandle
->Buffer
= Buffer
;
530 AmlHandle
->AmlByteEncoding
= AmlByteEncoding
;
531 AmlHandle
->Modified
= FALSE
;
533 AmlHandle
->Size
= AmlGetObjectSize (AmlByteEncoding
, Buffer
, BufferSize
);
534 if (AmlHandle
->Size
== 0) {
535 FreePool (AmlHandle
);
536 return EFI_INVALID_PARAMETER
;
539 *Handle
= (EFI_ACPI_HANDLE
)AmlHandle
;
545 Create a handle from an ACPI opcode
547 @param[in] Buffer Points to the ACPI opcode.
548 @param[out] Handle Upon return, holds the handle.
550 @retval EFI_SUCCESS Success
551 @retval EFI_INVALID_PARAMETER Buffer is NULL or Handle is NULL or Buffer points to an
559 OUT EFI_ACPI_HANDLE
*Handle
566 // Check for invalid input parameters
568 if (Buffer
== NULL
|| Handle
== NULL
) {
569 return EFI_INVALID_PARAMETER
;
572 Status
= SdtGetMaxAmlBufferSize (Buffer
, &MaxSize
);
573 if (EFI_ERROR (Status
)) {
574 return EFI_INVALID_PARAMETER
;
577 return SdtOpenEx (Buffer
, MaxSize
, Handle
);
581 Close an ACPI handle.
583 @param[in] Handle Returns the handle.
585 @retval EFI_SUCCESS Success
586 @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
591 IN EFI_ACPI_HANDLE Handle
594 EFI_AML_HANDLE
*AmlHandle
;
598 // Check for invalid input parameters
600 if (Handle
== NULL
) {
601 return EFI_INVALID_PARAMETER
;
604 AmlHandle
= (EFI_AML_HANDLE
*)Handle
;
605 if ((AmlHandle
->Signature
!= EFI_AML_ROOT_HANDLE_SIGNATURE
) &&
606 (AmlHandle
->Signature
!= EFI_AML_HANDLE_SIGNATURE
)) {
607 return EFI_INVALID_PARAMETER
;
611 // Update Checksum only if modified
613 if (AmlHandle
->Modified
) {
614 Status
= SdtUpdateAmlChecksum (AmlHandle
->Buffer
);
615 if (EFI_ERROR (Status
)) {
616 return EFI_INVALID_PARAMETER
;
620 FreePool (AmlHandle
);
626 Retrieve information about an ACPI object.
628 @param[in] Handle ACPI object handle.
629 @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
630 in the ACPI encoding, with index 0 always being the ACPI opcode.
631 @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
632 for the specified index.
633 @param[out] Data Upon return, points to the pointer to the data.
634 @param[out] DataSize Upon return, points to the size of Data.
636 @retval EFI_SUCCESS Success.
637 @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
642 IN EFI_ACPI_HANDLE Handle
,
644 OUT EFI_ACPI_DATA_TYPE
*DataType
,
645 OUT CONST VOID
**Data
,
649 EFI_AML_HANDLE
*AmlHandle
;
650 AML_BYTE_ENCODING
*AmlByteEncoding
;
653 ASSERT (DataType
!= NULL
);
654 ASSERT (Data
!= NULL
);
655 ASSERT (DataSize
!= NULL
);
658 // Check for invalid input parameters
660 if (Handle
== NULL
) {
661 return EFI_INVALID_PARAMETER
;
664 AmlHandle
= (EFI_AML_HANDLE
*)Handle
;
666 // Do not check EFI_AML_ROOT_HANDLE_SIGNATURE because there is no option for Root handle
668 if (AmlHandle
->Signature
!= EFI_AML_HANDLE_SIGNATURE
) {
669 return EFI_INVALID_PARAMETER
;
672 AmlByteEncoding
= AmlHandle
->AmlByteEncoding
;
673 if (Index
> AmlByteEncoding
->MaxIndex
) {
674 *DataType
= EFI_ACPI_DATA_TYPE_NONE
;
681 Status
= AmlParseOptionHandleCommon (AmlHandle
, (AML_OP_PARSE_INDEX
)Index
, DataType
, (VOID
**)Data
, DataSize
);
682 if (EFI_ERROR (Status
)) {
683 return EFI_INVALID_PARAMETER
;
690 Change information about an ACPI object.
692 @param[in] Handle ACPI object handle.
693 @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
694 in the ACPI encoding, with index 0 always being the ACPI opcode.
695 @param[in] Data Points to the data.
696 @param[in] DataSize The size of the Data.
698 @retval EFI_SUCCESS Success
699 @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
700 @retval EFI_BAD_BUFFER_SIZE Data cannot be accommodated in the space occupied by
707 IN EFI_ACPI_HANDLE Handle
,
713 EFI_AML_HANDLE
*AmlHandle
;
714 AML_BYTE_ENCODING
*AmlByteEncoding
;
716 EFI_ACPI_DATA_TYPE DataType
;
720 ASSERT (Data
!= NULL
);
723 // Check for invalid input parameters
725 if (Handle
== NULL
) {
726 return EFI_INVALID_PARAMETER
;
729 AmlHandle
= (EFI_AML_HANDLE
*)Handle
;
731 // Do not check EFI_AML_ROOT_HANDLE_SIGNATURE because there is no option for Root handle
733 if (AmlHandle
->Signature
!= EFI_AML_HANDLE_SIGNATURE
) {
734 return EFI_INVALID_PARAMETER
;
736 AmlByteEncoding
= AmlHandle
->AmlByteEncoding
;
738 if (Index
> AmlByteEncoding
->MaxIndex
) {
739 return EFI_INVALID_PARAMETER
;
745 Status
= AmlParseOptionHandleCommon (AmlHandle
, (AML_OP_PARSE_INDEX
)Index
, &DataType
, &OrgData
, &OrgDataSize
);
746 if (EFI_ERROR (Status
)) {
747 return EFI_INVALID_PARAMETER
;
749 if (DataType
== EFI_ACPI_DATA_TYPE_NONE
) {
750 return EFI_INVALID_PARAMETER
;
753 if (DataSize
> OrgDataSize
) {
754 return EFI_BAD_BUFFER_SIZE
;
760 CopyMem (OrgData
, Data
, DataSize
);
761 AmlHandle
->Modified
= TRUE
;
767 Return the child ACPI objects.
769 @param[in] ParentHandle Parent handle.
770 @param[in, out] Handle On entry, points to the previously returned handle or NULL to start with the first
771 handle. On return, points to the next returned ACPI handle or NULL if there are no
774 @retval EFI_SUCCESS Success
775 @retval EFI_INVALID_PARAMETER ParentHandle is NULL or does not refer to a valid ACPI object.
780 IN EFI_ACPI_HANDLE ParentHandle
,
781 IN OUT EFI_ACPI_HANDLE
*Handle
784 EFI_AML_HANDLE
*AmlParentHandle
;
785 EFI_AML_HANDLE
*AmlHandle
;
789 ASSERT (Handle
!= NULL
);
792 // Check for invalid input parameters
794 if (ParentHandle
== NULL
) {
795 return EFI_INVALID_PARAMETER
;
799 if ((AmlHandle
!= NULL
) && (AmlHandle
->Signature
!= EFI_AML_HANDLE_SIGNATURE
)) {
800 return EFI_INVALID_PARAMETER
;
803 AmlParentHandle
= (EFI_AML_HANDLE
*)ParentHandle
;
804 if (AmlParentHandle
->Signature
== EFI_AML_ROOT_HANDLE_SIGNATURE
) {
808 Status
= AmlGetChildFromRoot (AmlParentHandle
, AmlHandle
, &Buffer
);
809 } else if (AmlParentHandle
->Signature
== EFI_AML_HANDLE_SIGNATURE
) {
813 Status
= AmlGetChildFromNonRoot (AmlParentHandle
, AmlHandle
, &Buffer
);
818 return EFI_INVALID_PARAMETER
;
821 if (EFI_ERROR (Status
)) {
822 return EFI_INVALID_PARAMETER
;
824 if (Buffer
== NULL
) {
828 return SdtOpenEx (Buffer
, (UINTN
)AmlParentHandle
->Buffer
+ AmlParentHandle
->Size
- (UINTN
)Buffer
, Handle
);
832 Returns the handle of the ACPI object representing the specified ACPI path
834 @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
835 @param[in] AmlPath Points to the AML path.
836 @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
839 @retval EFI_SUCCESS Success
840 @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
843 SdtFindPathFromNonRoot (
844 IN EFI_ACPI_HANDLE HandleIn
,
846 OUT EFI_ACPI_HANDLE
*HandleOut
849 EFI_AML_HANDLE
*AmlHandle
;
853 AmlHandle
= (EFI_AML_HANDLE
*)HandleIn
;
856 // For non-root handle, we need search from THIS node instead of ROOT.
858 Status
= AmlFindPath (AmlHandle
, AmlPath
, &Buffer
, FALSE
);
859 if (EFI_ERROR (Status
)) {
860 return EFI_INVALID_PARAMETER
;
862 if (Buffer
== NULL
) {
866 return SdtOpenEx (Buffer
, (UINTN
)AmlHandle
->Buffer
+ AmlHandle
->Size
- (UINTN
)Buffer
, HandleOut
);
870 Duplicate AML handle.
872 @param[in] AmlHandle Handle to be duplicated.
874 @return Duplicated AML handle.
878 IN EFI_AML_HANDLE
*AmlHandle
881 EFI_AML_HANDLE
*DstAmlHandle
;
883 DstAmlHandle
= AllocatePool (sizeof(*DstAmlHandle
));
884 ASSERT (DstAmlHandle
!= NULL
);
885 CopyMem (DstAmlHandle
, (VOID
*)AmlHandle
, sizeof(*DstAmlHandle
));
891 Returns the handle of the ACPI object representing the specified ACPI path
893 @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
894 @param[in] AmlPath Points to the AML path.
895 @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
898 @retval EFI_SUCCESS Success
899 @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
902 SdtFindPathFromRoot (
903 IN EFI_ACPI_HANDLE HandleIn
,
905 OUT EFI_ACPI_HANDLE
*HandleOut
908 EFI_ACPI_HANDLE ChildHandle
;
909 EFI_AML_HANDLE
*AmlHandle
;
913 AmlHandle
= (EFI_AML_HANDLE
*)HandleIn
;
916 // Handle case that AcpiPath is Root
918 if (AmlIsRootPath (AmlPath
)) {
920 // Duplicate RootHandle
922 *HandleOut
= (EFI_ACPI_HANDLE
)SdtDuplicateHandle (AmlHandle
);
927 // Let children find it.
931 Status
= GetChild (HandleIn
, &ChildHandle
);
932 if (EFI_ERROR (Status
)) {
933 return EFI_INVALID_PARAMETER
;
936 if (ChildHandle
== NULL
) {
947 AmlHandle
= (EFI_AML_HANDLE
*)ChildHandle
;
948 Status
= AmlFindPath (AmlHandle
, AmlPath
, &Buffer
, TRUE
);
949 if (EFI_ERROR (Status
)) {
950 return EFI_INVALID_PARAMETER
;
953 if (Buffer
!= NULL
) {
955 // Great! Find it, open
957 Status
= SdtOpenEx (Buffer
, (UINTN
)AmlHandle
->Buffer
+ AmlHandle
->Size
- (UINTN
)Buffer
, HandleOut
);
958 if (!EFI_ERROR (Status
)) {
962 // Not success, try next one
968 // Should not run here
973 Returns the handle of the ACPI object representing the specified ACPI path
975 @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
976 @param[in] AcpiPath Points to the ACPI path, which conforms to the ACPI encoded path format.
977 @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
980 @retval EFI_SUCCESS Success
981 @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
986 IN EFI_ACPI_HANDLE HandleIn
,
988 OUT EFI_ACPI_HANDLE
*HandleOut
991 EFI_AML_HANDLE
*AmlHandle
;
996 // Check for invalid input parameters
998 if (HandleIn
== NULL
) {
999 return EFI_INVALID_PARAMETER
;
1002 AmlHandle
= (EFI_AML_HANDLE
*)HandleIn
;
1005 // Convert ASL path to AML path
1007 AmlPath
= AmlNameFromAslName (AcpiPath
);
1008 if (AmlPath
== NULL
) {
1009 return EFI_INVALID_PARAMETER
;
1012 DEBUG_CODE_BEGIN ();
1013 DEBUG ((EFI_D_ERROR
, "AcpiSdt: FindPath - "));
1014 AmlPrintNameString (AmlPath
);
1015 DEBUG ((EFI_D_ERROR
, "\n"));
1018 if (AmlHandle
->Signature
== EFI_AML_ROOT_HANDLE_SIGNATURE
) {
1022 Status
= SdtFindPathFromRoot (HandleIn
, AmlPath
, HandleOut
);
1023 } else if (AmlHandle
->Signature
== EFI_AML_HANDLE_SIGNATURE
) {
1027 Status
= SdtFindPathFromNonRoot (HandleIn
, AmlPath
, HandleOut
);
1029 Status
= EFI_INVALID_PARAMETER
;
1038 ExitPmAuth Protocol notification event handler.
1040 @param[in] Event Event whose notification function is being invoked.
1041 @param[in] Context Pointer to the notification function's context.
1045 ExitPmAuthNotification (
1051 VOID
*DxeSmmReadyToLock
;
1054 // Add more check to locate protocol after got event, because
1055 // the library will signal this event immediately once it is register
1056 // just in case it is already installed.
1058 Status
= gBS
->LocateProtocol (
1059 &gEfiDxeSmmReadyToLockProtocolGuid
,
1063 if (EFI_ERROR (Status
)) {
1068 // Uninstall ACPI SDT protocol, so that we can make sure no one update ACPI table from API level.
1070 Status
= gBS
->UninstallProtocolInterface (
1072 &gEfiAcpiSdtProtocolGuid
,
1073 &mPrivateData
->AcpiSdtProtocol
1075 ASSERT_EFI_ERROR (Status
);
1078 // Close event, so it will not be invoked again.
1080 gBS
->CloseEvent (Event
);
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
1097 InitializeListHead (&AcpiTableInstance
->NotifyList
);
1098 CopyMem (&AcpiTableInstance
->AcpiSdtProtocol
, &mAcpiSdtProtocolTemplate
, sizeof(mAcpiSdtProtocolTemplate
));
1101 // Register event for ExitPmAuth, so that we can uninstall ACPI SDT protocol after ExitPmAuth.
1103 EfiCreateProtocolNotifyEvent (
1104 &gEfiDxeSmmReadyToLockProtocolGuid
,
1106 ExitPmAuthNotification
,