2 ACPI Sdt Protocol Driver
4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 Retrieve option term according to AmlByteEncoding and Buffer.
14 @param[in] AmlByteEncoding AML Byte Encoding.
15 @param[in] Buffer AML buffer.
16 @param[in] MaxBufferSize AML buffer MAX size. The parser can not parse any data exceed this region.
17 @param[in] TermIndex Index of the data to retrieve from the object.
18 @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
19 for the specified index.
20 @param[out] Data Upon return, points to the pointer to the data.
21 @param[out] DataSize Upon return, points to the size of Data.
23 @retval EFI_SUCCESS Success.
24 @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid ACPI object.
28 IN AML_BYTE_ENCODING
*AmlByteEncoding
,
30 IN UINTN MaxBufferSize
,
31 IN AML_OP_PARSE_INDEX TermIndex
,
32 OUT EFI_ACPI_DATA_TYPE
*DataType
,
37 AML_BYTE_ENCODING
*ChildAmlByteEncoding
;
40 if (DataType
!= NULL
) {
41 *DataType
= AmlTypeToAcpiType (AmlByteEncoding
->Format
[TermIndex
- 1]);
47 // Parse term according to AML type
49 switch (AmlByteEncoding
->Format
[TermIndex
- 1]) {
51 *DataSize
= sizeof(UINT8
);
54 *DataSize
= sizeof(UINT16
);
57 *DataSize
= sizeof(UINT32
);
60 *DataSize
= sizeof(UINT64
);
63 *DataSize
= AsciiStrSize((CHAR8
*)Buffer
);
66 Status
= AmlGetNameStringSize (Buffer
, DataSize
);
67 if (EFI_ERROR (Status
)) {
68 return EFI_INVALID_PARAMETER
;
72 ChildAmlByteEncoding
= AmlSearchByOpByte (Buffer
);
73 if (ChildAmlByteEncoding
== NULL
) {
74 return EFI_INVALID_PARAMETER
;
78 // NOTE: We need override DataType here, if there is a case the AML_OBJECT is AML_NAME.
79 // We need convert type from EFI_ACPI_DATA_TYPE_CHILD to EFI_ACPI_DATA_TYPE_NAME_STRING.
80 // We should not return CHILD because there is NO OpCode for NameString.
82 if ((ChildAmlByteEncoding
->Attribute
& AML_IS_NAME_CHAR
) != 0) {
83 if (DataType
!= NULL
) {
84 *DataType
= AmlTypeToAcpiType (AML_NAME
);
86 Status
= AmlGetNameStringSize (Buffer
, DataSize
);
87 if (EFI_ERROR (Status
)) {
88 return EFI_INVALID_PARAMETER
;
94 // It is real AML_OBJECT
96 *DataSize
= AmlGetObjectSize (
101 if (*DataSize
== 0) {
102 return EFI_INVALID_PARAMETER
;
112 return EFI_INVALID_PARAMETER
;
114 if (*DataSize
> MaxBufferSize
) {
115 return EFI_INVALID_PARAMETER
;
121 Retrieve information according to AmlByteEncoding and Buffer.
123 @param[in] AmlByteEncoding AML Byte Encoding.
124 @param[in] Buffer AML buffer.
125 @param[in] MaxBufferSize AML buffer MAX size. The parser can not parse any data exceed this region.
126 @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
127 in the ACPI encoding, with index 0 always being the ACPI opcode.
128 @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
129 for the specified index.
130 @param[out] Data Upon return, points to the pointer to the data.
131 @param[out] DataSize Upon return, points to the size of Data.
133 @retval EFI_SUCCESS Success.
134 @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid ACPI object.
137 AmlParseOptionCommon (
138 IN AML_BYTE_ENCODING
*AmlByteEncoding
,
140 IN UINTN MaxBufferSize
,
141 IN AML_OP_PARSE_INDEX Index
,
142 OUT EFI_ACPI_DATA_TYPE
*DataType
,
147 UINT8
*CurrentBuffer
;
151 AML_OP_PARSE_INDEX TermIndex
;
154 ASSERT ((Index
<= AmlByteEncoding
->MaxIndex
) || (Index
== AML_OP_PARSE_INDEX_GET_SIZE
));
157 // 0. Check if this is NAME string.
159 if ((AmlByteEncoding
->Attribute
& AML_IS_NAME_CHAR
) != 0) {
161 // Only allow GET_SIZE
163 if (Index
!= AML_OP_PARSE_INDEX_GET_SIZE
) {
164 return EFI_INVALID_PARAMETER
;
167 // return NameString size
169 Status
= AmlGetNameStringSize (Buffer
, DataSize
);
170 if (EFI_ERROR (Status
)) {
171 return EFI_INVALID_PARAMETER
;
173 if (*DataSize
> MaxBufferSize
) {
174 return EFI_INVALID_PARAMETER
;
180 // Not NAME string, start parsing
182 CurrentBuffer
= Buffer
;
187 if (Index
!= AML_OP_PARSE_INDEX_GET_SIZE
) {
188 *DataType
= EFI_ACPI_DATA_TYPE_OPCODE
;
189 *Data
= (VOID
*)CurrentBuffer
;
191 if (*CurrentBuffer
== AML_EXT_OP
) {
196 *DataSize
= OpLength
;
197 if (Index
== AML_OP_PARSE_INDEX_GET_OPCODE
) {
200 if (OpLength
> MaxBufferSize
) {
201 return EFI_INVALID_PARAMETER
;
203 CurrentBuffer
+= OpLength
;
206 // 2. Skip PkgLength field, if have
208 if ((AmlByteEncoding
->Attribute
& AML_HAS_PKG_LENGTH
) != 0) {
209 PkgOffset
= AmlGetPkgLength(CurrentBuffer
, &PkgLength
);
211 // Override MaxBufferSize if it is valid PkgLength
213 if (OpLength
+ PkgLength
> MaxBufferSize
) {
214 return EFI_INVALID_PARAMETER
;
216 MaxBufferSize
= OpLength
+ PkgLength
;
222 CurrentBuffer
+= PkgOffset
;
225 // 3. Get Term one by one.
227 TermIndex
= AML_OP_PARSE_INDEX_GET_TERM1
;
228 while ((Index
>= TermIndex
) && (TermIndex
<= AmlByteEncoding
->MaxIndex
) && ((UINTN
)CurrentBuffer
< (UINTN
)Buffer
+ MaxBufferSize
)) {
229 Status
= AmlParseOptionTerm (
232 (UINTN
)Buffer
+ MaxBufferSize
- (UINTN
)CurrentBuffer
,
238 if (EFI_ERROR (Status
)) {
239 return EFI_INVALID_PARAMETER
;
242 if (Index
== TermIndex
) {
252 CurrentBuffer
+= *DataSize
;
257 // Finish all options, but no option found.
259 if ((UINTN
)CurrentBuffer
> (UINTN
)Buffer
+ MaxBufferSize
) {
260 return EFI_INVALID_PARAMETER
;
262 if ((UINTN
)CurrentBuffer
== (UINTN
)Buffer
+ MaxBufferSize
) {
263 if (Index
!= AML_OP_PARSE_INDEX_GET_SIZE
) {
264 return EFI_INVALID_PARAMETER
;
269 // 4. Finish parsing all node, return size
271 ASSERT (Index
== AML_OP_PARSE_INDEX_GET_SIZE
);
272 if ((AmlByteEncoding
->Attribute
& AML_HAS_PKG_LENGTH
) != 0) {
273 *DataSize
= OpLength
+ PkgLength
;
275 *DataSize
= (UINTN
)CurrentBuffer
- (UINTN
)Buffer
;
284 @param[in] AmlByteEncoding AML Byte Encoding.
285 @param[in] Buffer AML object buffer.
286 @param[in] MaxBufferSize AML object buffer MAX size. The parser can not parse any data exceed this region.
288 @return Size of the object.
292 IN AML_BYTE_ENCODING
*AmlByteEncoding
,
294 IN UINTN MaxBufferSize
300 Status
= AmlParseOptionCommon (
304 AML_OP_PARSE_INDEX_GET_SIZE
,
309 if (EFI_ERROR (Status
)) {
319 @param[in] AmlHandle AML handle.
321 @return Name of the object.
325 IN EFI_AML_HANDLE
*AmlHandle
328 AML_BYTE_ENCODING
*AmlByteEncoding
;
331 AML_OP_PARSE_INDEX TermIndex
;
333 EFI_ACPI_DATA_TYPE DataType
;
335 AmlByteEncoding
= AmlHandle
->AmlByteEncoding
;
337 ASSERT ((AmlByteEncoding
->Attribute
& AML_IN_NAMESPACE
) != 0);
340 // Find out Last Name index, according to OpCode table.
341 // The last name will be the node name by design.
343 TermIndex
= AmlByteEncoding
->MaxIndex
;
344 for (TermIndex
= AmlByteEncoding
->MaxIndex
; TermIndex
> 0; TermIndex
--) {
345 if (AmlByteEncoding
->Format
[TermIndex
- 1] == AML_NAME
) {
349 ASSERT (TermIndex
!= 0);
352 // Get Name for this node.
354 Status
= AmlParseOptionHandleCommon (
361 if (EFI_ERROR (Status
)) {
364 ASSERT (DataType
== EFI_ACPI_DATA_TYPE_NAME_STRING
);
370 Return offset of last option.
372 @param[in] AmlHandle AML Handle.
373 @param[out] Buffer Upon return, points to the offset after last option.
375 @retval EFI_SUCCESS Success.
376 @retval EFI_INVALID_PARAMETER AmlHandle does not refer to a valid ACPI object.
379 AmlGetOffsetAfterLastOption (
380 IN EFI_AML_HANDLE
*AmlHandle
,
384 EFI_ACPI_DATA_TYPE DataType
;
389 Status
= AmlParseOptionHandleCommon (
391 AmlHandle
->AmlByteEncoding
->MaxIndex
,
396 if (EFI_ERROR (Status
)) {
397 return EFI_INVALID_PARAMETER
;
401 // We need to parse the rest buffer after last node.
403 *Buffer
= (UINT8
*)((UINTN
)Data
+ DataSize
);
406 // We need skip PkgLength if no Option
408 if (DataType
== EFI_ACPI_DATA_TYPE_OPCODE
) {
409 *Buffer
+= AmlGetPkgLength (*Buffer
, &DataSize
);
415 Retrieve information according to AmlHandle
417 @param[in] AmlHandle AML handle.
418 @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
419 in the ACPI encoding, with index 0 always being the ACPI opcode.
420 @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
421 for the specified index.
422 @param[out] Data Upon return, points to the pointer to the data.
423 @param[out] DataSize Upon return, points to the size of Data.
425 @retval EFI_SUCCESS Success.
426 @retval EFI_INVALID_PARAMETER AmlHandle does not refer to a valid ACPI object.
429 AmlParseOptionHandleCommon (
430 IN EFI_AML_HANDLE
*AmlHandle
,
431 IN AML_OP_PARSE_INDEX Index
,
432 OUT EFI_ACPI_DATA_TYPE
*DataType
,
437 return AmlParseOptionCommon (
438 AmlHandle
->AmlByteEncoding
,