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.
15 #include "AcpiTable.h"
18 Retrieve option term according to AmlByteEncoding and Buffer.
20 @param[in] AmlByteEncoding AML Byte Encoding.
21 @param[in] Buffer AML buffer.
22 @param[in] MaxBufferSize AML buffer MAX size. The parser can not parse any data exceed this region.
23 @param[in] TermIndex Index of the data to retrieve from the object.
24 @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
25 for the specified index.
26 @param[out] Data Upon return, points to the pointer to the data.
27 @param[out] DataSize Upon return, points to the size of Data.
29 @retval EFI_SUCCESS Success.
30 @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid ACPI object.
34 IN AML_BYTE_ENCODING
*AmlByteEncoding
,
36 IN UINTN MaxBufferSize
,
37 IN AML_OP_PARSE_INDEX TermIndex
,
38 OUT EFI_ACPI_DATA_TYPE
*DataType
,
43 AML_BYTE_ENCODING
*ChildAmlByteEncoding
;
46 if (DataType
!= NULL
) {
47 *DataType
= AmlTypeToAcpiType (AmlByteEncoding
->Format
[TermIndex
- 1]);
53 // Parse term according to AML type
55 switch (AmlByteEncoding
->Format
[TermIndex
- 1]) {
57 *DataSize
= sizeof(UINT8
);
60 *DataSize
= sizeof(UINT16
);
63 *DataSize
= sizeof(UINT32
);
66 *DataSize
= sizeof(UINT64
);
69 *DataSize
= AsciiStrSize((CHAR8
*)Buffer
);
72 Status
= AmlGetNameStringSize (Buffer
, DataSize
);
73 if (EFI_ERROR (Status
)) {
74 return EFI_INVALID_PARAMETER
;
78 ChildAmlByteEncoding
= AmlSearchByOpByte (Buffer
);
79 if (ChildAmlByteEncoding
== NULL
) {
80 return EFI_INVALID_PARAMETER
;
84 // NOTE: We need override DataType here, if there is a case the AML_OBJECT is AML_NAME.
85 // We need convert type from EFI_ACPI_DATA_TYPE_CHILD to EFI_ACPI_DATA_TYPE_NAME_STRING.
86 // We should not return CHILD because there is NO OpCode for NameString.
88 if ((ChildAmlByteEncoding
->Attribute
& AML_IS_NAME_CHAR
) != 0) {
89 if (DataType
!= NULL
) {
90 *DataType
= AmlTypeToAcpiType (AML_NAME
);
92 Status
= AmlGetNameStringSize (Buffer
, DataSize
);
93 if (EFI_ERROR (Status
)) {
94 return EFI_INVALID_PARAMETER
;
100 // It is real AML_OBJECT
102 *DataSize
= AmlGetObjectSize (
103 ChildAmlByteEncoding
,
107 if (*DataSize
== 0) {
108 return EFI_INVALID_PARAMETER
;
118 return EFI_INVALID_PARAMETER
;
120 if (*DataSize
> MaxBufferSize
) {
121 return EFI_INVALID_PARAMETER
;
127 Retrieve information according to AmlByteEncoding and Buffer.
129 @param[in] AmlByteEncoding AML Byte Encoding.
130 @param[in] Buffer AML buffer.
131 @param[in] MaxBufferSize AML buffer MAX size. The parser can not parse any data exceed this region.
132 @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
133 in the ACPI encoding, with index 0 always being the ACPI opcode.
134 @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
135 for the specified index.
136 @param[out] Data Upon return, points to the pointer to the data.
137 @param[out] DataSize Upon return, points to the size of Data.
139 @retval EFI_SUCCESS Success.
140 @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid ACPI object.
143 AmlParseOptionCommon (
144 IN AML_BYTE_ENCODING
*AmlByteEncoding
,
146 IN UINTN MaxBufferSize
,
147 IN AML_OP_PARSE_INDEX Index
,
148 OUT EFI_ACPI_DATA_TYPE
*DataType
,
153 UINT8
*CurrentBuffer
;
157 AML_OP_PARSE_INDEX TermIndex
;
160 ASSERT ((Index
<= AmlByteEncoding
->MaxIndex
) || (Index
== AML_OP_PARSE_INDEX_GET_SIZE
));
163 // 0. Check if this is NAME string.
165 if ((AmlByteEncoding
->Attribute
& AML_IS_NAME_CHAR
) != 0) {
167 // Only allow GET_SIZE
169 if (Index
!= AML_OP_PARSE_INDEX_GET_SIZE
) {
170 return EFI_INVALID_PARAMETER
;
173 // return NameString size
175 Status
= AmlGetNameStringSize (Buffer
, DataSize
);
176 if (EFI_ERROR (Status
)) {
177 return EFI_INVALID_PARAMETER
;
179 if (*DataSize
> MaxBufferSize
) {
180 return EFI_INVALID_PARAMETER
;
186 // Not NAME string, start parsing
188 CurrentBuffer
= Buffer
;
193 if (Index
!= AML_OP_PARSE_INDEX_GET_SIZE
) {
194 *DataType
= EFI_ACPI_DATA_TYPE_OPCODE
;
195 *Data
= (VOID
*)CurrentBuffer
;
197 if (*CurrentBuffer
== AML_EXT_OP
) {
202 *DataSize
= OpLength
;
203 if (Index
== AML_OP_PARSE_INDEX_GET_OPCODE
) {
206 if (OpLength
> MaxBufferSize
) {
207 return EFI_INVALID_PARAMETER
;
209 CurrentBuffer
+= OpLength
;
212 // 2. Skip PkgLength field, if have
214 if ((AmlByteEncoding
->Attribute
& AML_HAS_PKG_LENGTH
) != 0) {
215 PkgOffset
= AmlGetPkgLength(CurrentBuffer
, &PkgLength
);
217 // Override MaxBufferSize if it is valid PkgLength
219 if (OpLength
+ PkgLength
> MaxBufferSize
) {
220 return EFI_INVALID_PARAMETER
;
222 MaxBufferSize
= OpLength
+ PkgLength
;
228 CurrentBuffer
+= PkgOffset
;
231 // 3. Get Term one by one.
233 TermIndex
= AML_OP_PARSE_INDEX_GET_TERM1
;
234 while ((Index
>= TermIndex
) && (TermIndex
<= AmlByteEncoding
->MaxIndex
) && ((UINTN
)CurrentBuffer
< (UINTN
)Buffer
+ MaxBufferSize
)) {
235 Status
= AmlParseOptionTerm (
238 (UINTN
)Buffer
+ MaxBufferSize
- (UINTN
)CurrentBuffer
,
244 if (EFI_ERROR (Status
)) {
245 return EFI_INVALID_PARAMETER
;
248 if (Index
== TermIndex
) {
258 CurrentBuffer
+= *DataSize
;
263 // Finish all options, but no option found.
265 if ((UINTN
)CurrentBuffer
> (UINTN
)Buffer
+ MaxBufferSize
) {
266 return EFI_INVALID_PARAMETER
;
268 if ((UINTN
)CurrentBuffer
== (UINTN
)Buffer
+ MaxBufferSize
) {
269 if (Index
!= AML_OP_PARSE_INDEX_GET_SIZE
) {
270 return EFI_INVALID_PARAMETER
;
275 // 4. Finish parsing all node, return size
277 ASSERT (Index
== AML_OP_PARSE_INDEX_GET_SIZE
);
278 if ((AmlByteEncoding
->Attribute
& AML_HAS_PKG_LENGTH
) != 0) {
279 *DataSize
= OpLength
+ PkgLength
;
281 *DataSize
= (UINTN
)CurrentBuffer
- (UINTN
)Buffer
;
290 @param[in] AmlByteEncoding AML Byte Encoding.
291 @param[in] Buffer AML object buffer.
292 @param[in] MaxBufferSize AML object buffer MAX size. The parser can not parse any data exceed this region.
294 @return Size of the object.
298 IN AML_BYTE_ENCODING
*AmlByteEncoding
,
300 IN UINTN MaxBufferSize
306 Status
= AmlParseOptionCommon (
310 AML_OP_PARSE_INDEX_GET_SIZE
,
315 if (EFI_ERROR (Status
)) {
325 @param[in] AmlHandle AML handle.
327 @return Name of the object.
331 IN EFI_AML_HANDLE
*AmlHandle
334 AML_BYTE_ENCODING
*AmlByteEncoding
;
337 AML_OP_PARSE_INDEX TermIndex
;
339 EFI_ACPI_DATA_TYPE DataType
;
341 AmlByteEncoding
= AmlHandle
->AmlByteEncoding
;
343 ASSERT ((AmlByteEncoding
->Attribute
& AML_IN_NAMESPACE
) != 0);
346 // Find out Last Name index, accroding to OpCode table.
347 // The last name will be the node name by design.
349 TermIndex
= AmlByteEncoding
->MaxIndex
;
350 for (TermIndex
= AmlByteEncoding
->MaxIndex
; TermIndex
> 0; TermIndex
--) {
351 if (AmlByteEncoding
->Format
[TermIndex
- 1] == AML_NAME
) {
355 ASSERT (TermIndex
!= 0);
358 // Get Name for this node.
360 Status
= AmlParseOptionHandleCommon (
367 if (EFI_ERROR (Status
)) {
370 ASSERT (DataType
== EFI_ACPI_DATA_TYPE_NAME_STRING
);
376 Return offset of last option.
378 @param[in] AmlHandle AML Handle.
379 @param[out] Buffer Upon return, points to the offset after last option.
381 @retval EFI_SUCCESS Success.
382 @retval EFI_INVALID_PARAMETER AmlHandle does not refer to a valid ACPI object.
385 AmlGetOffsetAfterLastOption (
386 IN EFI_AML_HANDLE
*AmlHandle
,
390 EFI_ACPI_DATA_TYPE DataType
;
395 Status
= AmlParseOptionHandleCommon (
397 AmlHandle
->AmlByteEncoding
->MaxIndex
,
402 if (EFI_ERROR (Status
)) {
403 return EFI_INVALID_PARAMETER
;
407 // We need to parse the rest buffer after last node.
409 *Buffer
= (UINT8
*)((UINTN
)Data
+ DataSize
);
412 // We need skip PkgLength if no Option
414 if (DataType
== EFI_ACPI_DATA_TYPE_OPCODE
) {
415 *Buffer
+= AmlGetPkgLength (*Buffer
, &DataSize
);
421 Retrieve information according to AmlHandle
423 @param[in] AmlHandle AML handle.
424 @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
425 in the ACPI encoding, with index 0 always being the ACPI opcode.
426 @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
427 for the specified index.
428 @param[out] Data Upon return, points to the pointer to the data.
429 @param[out] DataSize Upon return, points to the size of Data.
431 @retval EFI_SUCCESS Success.
432 @retval EFI_INVALID_PARAMETER AmlHandle does not refer to a valid ACPI object.
435 AmlParseOptionHandleCommon (
436 IN EFI_AML_HANDLE
*AmlHandle
,
437 IN AML_OP_PARSE_INDEX Index
,
438 OUT EFI_ACPI_DATA_TYPE
*DataType
,
443 return AmlParseOptionCommon (
444 AmlHandle
->AmlByteEncoding
,