1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
4 * Module Name: psargs - Parse AML opcode arguments
6 * Copyright (C) 2000 - 2018, Intel Corp.
8 *****************************************************************************/
10 #include <acpi/acpi.h>
16 #include "acconvert.h"
18 #define _COMPONENT ACPI_PARSER
19 ACPI_MODULE_NAME("psargs")
21 /* Local prototypes */
23 acpi_ps_get_next_package_length(struct acpi_parse_state
*parser_state
);
25 static union acpi_parse_object
*acpi_ps_get_next_field(struct acpi_parse_state
28 /*******************************************************************************
30 * FUNCTION: acpi_ps_get_next_package_length
32 * PARAMETERS: parser_state - Current parser state object
34 * RETURN: Decoded package length. On completion, the AML pointer points
35 * past the length byte or bytes.
37 * DESCRIPTION: Decode and return a package length field.
38 * Note: Largest package length is 28 bits, from ACPI specification
40 ******************************************************************************/
43 acpi_ps_get_next_package_length(struct acpi_parse_state
*parser_state
)
45 u8
*aml
= parser_state
->aml
;
46 u32 package_length
= 0;
48 u8 byte_zero_mask
= 0x3F; /* Default [0:5] */
50 ACPI_FUNCTION_TRACE(ps_get_next_package_length
);
53 * Byte 0 bits [6:7] contain the number of additional bytes
54 * used to encode the package length, either 0,1,2, or 3
56 byte_count
= (aml
[0] >> 6);
57 parser_state
->aml
+= ((acpi_size
)byte_count
+ 1);
59 /* Get bytes 3, 2, 1 as needed */
63 * Final bit positions for the package length bytes:
69 package_length
|= (aml
[byte_count
] << ((byte_count
<< 3) - 4));
71 byte_zero_mask
= 0x0F; /* Use bits [0:3] of byte 0 */
75 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
77 package_length
|= (aml
[0] & byte_zero_mask
);
78 return_UINT32(package_length
);
81 /*******************************************************************************
83 * FUNCTION: acpi_ps_get_next_package_end
85 * PARAMETERS: parser_state - Current parser state object
87 * RETURN: Pointer to end-of-package +1
89 * DESCRIPTION: Get next package length and return a pointer past the end of
90 * the package. Consumes the package length field
92 ******************************************************************************/
94 u8
*acpi_ps_get_next_package_end(struct acpi_parse_state
*parser_state
)
96 u8
*start
= parser_state
->aml
;
99 ACPI_FUNCTION_TRACE(ps_get_next_package_end
);
101 /* Function below updates parser_state->Aml */
103 package_length
= acpi_ps_get_next_package_length(parser_state
);
105 return_PTR(start
+ package_length
); /* end of package */
108 /*******************************************************************************
110 * FUNCTION: acpi_ps_get_next_namestring
112 * PARAMETERS: parser_state - Current parser state object
114 * RETURN: Pointer to the start of the name string (pointer points into
117 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
118 * prefix characters. Set parser state to point past the string.
119 * (Name is consumed from the AML.)
121 ******************************************************************************/
123 char *acpi_ps_get_next_namestring(struct acpi_parse_state
*parser_state
)
125 u8
*start
= parser_state
->aml
;
126 u8
*end
= parser_state
->aml
;
128 ACPI_FUNCTION_TRACE(ps_get_next_namestring
);
130 /* Point past any namestring prefix characters (backslash or carat) */
132 while (ACPI_IS_ROOT_PREFIX(*end
) || ACPI_IS_PARENT_PREFIX(*end
)) {
136 /* Decode the path prefix character */
149 case AML_DUAL_NAME_PREFIX
:
151 /* Two name segments */
153 end
+= 1 + (2 * ACPI_NAME_SIZE
);
156 case AML_MULTI_NAME_PREFIX
:
158 /* Multiple name segments, 4 chars each, count in next byte */
160 end
+= 2 + (*(end
+ 1) * ACPI_NAME_SIZE
);
165 /* Single name segment */
167 end
+= ACPI_NAME_SIZE
;
171 parser_state
->aml
= end
;
172 return_PTR((char *)start
);
175 /*******************************************************************************
177 * FUNCTION: acpi_ps_get_next_namepath
179 * PARAMETERS: parser_state - Current parser state object
180 * arg - Where the namepath will be stored
181 * arg_count - If the namepath points to a control method
182 * the method's argument is returned here.
183 * possible_method_call - Whether the namepath can possibly be the
184 * start of a method call
188 * DESCRIPTION: Get next name (if method call, return # of required args).
189 * Names are looked up in the internal namespace to determine
190 * if the name represents a control method. If a method
191 * is found, the number of arguments to the method is returned.
192 * This information is critical for parsing to continue correctly.
194 ******************************************************************************/
197 acpi_ps_get_next_namepath(struct acpi_walk_state
*walk_state
,
198 struct acpi_parse_state
*parser_state
,
199 union acpi_parse_object
*arg
, u8 possible_method_call
)
203 union acpi_parse_object
*name_op
;
204 union acpi_operand_object
*method_desc
;
205 struct acpi_namespace_node
*node
;
206 u8
*start
= parser_state
->aml
;
208 ACPI_FUNCTION_TRACE(ps_get_next_namepath
);
210 path
= acpi_ps_get_next_namestring(parser_state
);
211 acpi_ps_init_op(arg
, AML_INT_NAMEPATH_OP
);
213 /* Null path case is allowed, just exit */
216 arg
->common
.value
.name
= path
;
217 return_ACPI_STATUS(AE_OK
);
221 * Lookup the name in the internal namespace, starting with the current
222 * scope. We don't want to add anything new to the namespace here,
223 * however, so we use MODE_EXECUTE.
224 * Allow searching of the parent tree, but don't open a new scope -
225 * we just want to lookup the object (must be mode EXECUTE to perform
228 status
= acpi_ns_lookup(walk_state
->scope_info
, path
,
229 ACPI_TYPE_ANY
, ACPI_IMODE_EXECUTE
,
230 ACPI_NS_SEARCH_PARENT
| ACPI_NS_DONT_OPEN_SCOPE
,
234 * If this name is a control method invocation, we must
235 * setup the method call
237 if (ACPI_SUCCESS(status
) &&
238 possible_method_call
&& (node
->type
== ACPI_TYPE_METHOD
)) {
239 if ((GET_CURRENT_ARG_TYPE(walk_state
->arg_types
) ==
241 || (GET_CURRENT_ARG_TYPE(walk_state
->arg_types
) ==
244 * acpi_ps_get_next_namestring has increased the AML pointer past
245 * the method invocation namestring, so we need to restore the
246 * saved AML pointer back to the original method invocation
249 walk_state
->parser_state
.aml
= start
;
250 walk_state
->arg_count
= 1;
251 acpi_ps_init_op(arg
, AML_INT_METHODCALL_OP
);
254 /* This name is actually a control method invocation */
256 method_desc
= acpi_ns_get_attached_object(node
);
257 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
258 "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
259 node
->name
.ascii
, node
, method_desc
, path
));
261 name_op
= acpi_ps_alloc_op(AML_INT_NAMEPATH_OP
, start
);
263 return_ACPI_STATUS(AE_NO_MEMORY
);
266 /* Change Arg into a METHOD CALL and attach name to it */
268 acpi_ps_init_op(arg
, AML_INT_METHODCALL_OP
);
269 name_op
->common
.value
.name
= path
;
271 /* Point METHODCALL/NAME to the METHOD Node */
273 name_op
->common
.node
= node
;
274 acpi_ps_append_arg(arg
, name_op
);
278 "Control Method %p has no attached object",
280 return_ACPI_STATUS(AE_AML_INTERNAL
);
283 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
284 "Control Method - %p Args %X\n",
285 node
, method_desc
->method
.param_count
));
287 /* Get the number of arguments to expect */
289 walk_state
->arg_count
= method_desc
->method
.param_count
;
290 return_ACPI_STATUS(AE_OK
);
294 * Special handling if the name was not found during the lookup -
295 * some not_found cases are allowed
297 if (status
== AE_NOT_FOUND
) {
299 /* 1) not_found is ok during load pass 1/2 (allow forward references) */
301 if ((walk_state
->parse_flags
& ACPI_PARSE_MODE_MASK
) !=
302 ACPI_PARSE_EXECUTE
) {
306 /* 2) not_found during a cond_ref_of(x) is ok by definition */
308 else if (walk_state
->op
->common
.aml_opcode
==
309 AML_CONDITIONAL_REF_OF_OP
) {
314 * 3) not_found while building a Package is ok at this point, we
315 * may flag as an error later if slack mode is not enabled.
316 * (Some ASL code depends on allowing this behavior)
318 else if ((arg
->common
.parent
) &&
319 ((arg
->common
.parent
->common
.aml_opcode
==
321 || (arg
->common
.parent
->common
.aml_opcode
==
322 AML_VARIABLE_PACKAGE_OP
))) {
327 /* Final exception check (may have been changed from code above) */
329 if (ACPI_FAILURE(status
)) {
330 ACPI_ERROR_NAMESPACE(walk_state
->scope_info
, path
, status
);
332 if ((walk_state
->parse_flags
& ACPI_PARSE_MODE_MASK
) ==
333 ACPI_PARSE_EXECUTE
) {
335 /* Report a control method execution error */
337 status
= acpi_ds_method_error(status
, walk_state
);
341 /* Save the namepath */
343 arg
->common
.value
.name
= path
;
344 return_ACPI_STATUS(status
);
347 /*******************************************************************************
349 * FUNCTION: acpi_ps_get_next_simple_arg
351 * PARAMETERS: parser_state - Current parser state object
352 * arg_type - The argument type (AML_*_ARG)
353 * arg - Where the argument is returned
357 * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
359 ******************************************************************************/
362 acpi_ps_get_next_simple_arg(struct acpi_parse_state
*parser_state
,
363 u32 arg_type
, union acpi_parse_object
*arg
)
367 u8
*aml
= parser_state
->aml
;
369 ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg
, arg_type
);
374 /* Get 1 byte from the AML stream */
376 opcode
= AML_BYTE_OP
;
377 arg
->common
.value
.integer
= (u64
) *aml
;
383 /* Get 2 bytes from the AML stream */
385 opcode
= AML_WORD_OP
;
386 ACPI_MOVE_16_TO_64(&arg
->common
.value
.integer
, aml
);
392 /* Get 4 bytes from the AML stream */
394 opcode
= AML_DWORD_OP
;
395 ACPI_MOVE_32_TO_64(&arg
->common
.value
.integer
, aml
);
401 /* Get 8 bytes from the AML stream */
403 opcode
= AML_QWORD_OP
;
404 ACPI_MOVE_64_TO_64(&arg
->common
.value
.integer
, aml
);
410 /* Get a pointer to the string, point past the string */
412 opcode
= AML_STRING_OP
;
413 arg
->common
.value
.string
= ACPI_CAST_PTR(char, aml
);
415 /* Find the null terminator */
418 while (aml
[length
]) {
425 case ARGP_NAMESTRING
:
427 acpi_ps_init_op(arg
, AML_INT_NAMEPATH_OP
);
428 arg
->common
.value
.name
=
429 acpi_ps_get_next_namestring(parser_state
);
434 ACPI_ERROR((AE_INFO
, "Invalid ArgType 0x%X", arg_type
));
438 acpi_ps_init_op(arg
, opcode
);
439 parser_state
->aml
+= length
;
443 /*******************************************************************************
445 * FUNCTION: acpi_ps_get_next_field
447 * PARAMETERS: parser_state - Current parser state object
449 * RETURN: A newly allocated FIELD op
451 * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
453 ******************************************************************************/
455 static union acpi_parse_object
*acpi_ps_get_next_field(struct acpi_parse_state
459 union acpi_parse_object
*field
;
460 union acpi_parse_object
*arg
= NULL
;
470 ACPI_FUNCTION_TRACE(ps_get_next_field
);
472 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
473 aml
= parser_state
->aml
;
475 /* Determine field type */
477 switch (ACPI_GET8(parser_state
->aml
)) {
478 case AML_FIELD_OFFSET_OP
:
480 opcode
= AML_INT_RESERVEDFIELD_OP
;
484 case AML_FIELD_ACCESS_OP
:
486 opcode
= AML_INT_ACCESSFIELD_OP
;
490 case AML_FIELD_CONNECTION_OP
:
492 opcode
= AML_INT_CONNECTION_OP
;
496 case AML_FIELD_EXT_ACCESS_OP
:
498 opcode
= AML_INT_EXTACCESSFIELD_OP
;
504 opcode
= AML_INT_NAMEDFIELD_OP
;
508 /* Allocate a new field op */
510 field
= acpi_ps_alloc_op(opcode
, aml
);
515 /* Decode the field type */
517 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
519 case AML_INT_NAMEDFIELD_OP
:
521 /* Get the 4-character name */
523 ACPI_MOVE_32_TO_32(&name
, parser_state
->aml
);
524 acpi_ps_set_name(field
, name
);
525 parser_state
->aml
+= ACPI_NAME_SIZE
;
527 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
529 #ifdef ACPI_ASL_COMPILER
531 * Because the package length isn't represented as a parse tree object,
532 * take comments surrounding this and add to the previously created
535 if (field
->common
.inline_comment
) {
536 field
->common
.name_comment
=
537 field
->common
.inline_comment
;
539 field
->common
.inline_comment
= acpi_gbl_current_inline_comment
;
540 acpi_gbl_current_inline_comment
= NULL
;
543 /* Get the length which is encoded as a package length */
545 field
->common
.value
.size
=
546 acpi_ps_get_next_package_length(parser_state
);
549 case AML_INT_RESERVEDFIELD_OP
:
551 /* Get the length which is encoded as a package length */
553 field
->common
.value
.size
=
554 acpi_ps_get_next_package_length(parser_state
);
557 case AML_INT_ACCESSFIELD_OP
:
558 case AML_INT_EXTACCESSFIELD_OP
:
561 * Get access_type and access_attrib and merge into the field Op
562 * access_type is first operand, access_attribute is second. stuff
563 * these bytes into the node integer value for convenience.
566 /* Get the two bytes (Type/Attribute) */
568 access_type
= ACPI_GET8(parser_state
->aml
);
570 access_attribute
= ACPI_GET8(parser_state
->aml
);
573 field
->common
.value
.integer
= (u8
)access_type
;
574 field
->common
.value
.integer
|= (u16
)(access_attribute
<< 8);
576 /* This opcode has a third byte, access_length */
578 if (opcode
== AML_INT_EXTACCESSFIELD_OP
) {
579 access_length
= ACPI_GET8(parser_state
->aml
);
582 field
->common
.value
.integer
|=
583 (u32
)(access_length
<< 16);
587 case AML_INT_CONNECTION_OP
:
590 * Argument for Connection operator can be either a Buffer
591 * (resource descriptor), or a name_string.
593 aml
= parser_state
->aml
;
594 if (ACPI_GET8(parser_state
->aml
) == AML_BUFFER_OP
) {
597 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
598 pkg_end
= parser_state
->aml
;
600 acpi_ps_get_next_package_length(parser_state
);
601 pkg_end
+= pkg_length
;
603 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
604 if (parser_state
->aml
< pkg_end
) {
609 acpi_ps_alloc_op(AML_INT_BYTELIST_OP
, aml
);
611 acpi_ps_free_op(field
);
615 /* Get the actual buffer length argument */
617 opcode
= ACPI_GET8(parser_state
->aml
);
620 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
622 case AML_BYTE_OP
: /* AML_BYTEDATA_ARG */
625 ACPI_GET8(parser_state
->aml
);
626 parser_state
->aml
+= 1;
629 case AML_WORD_OP
: /* AML_WORDDATA_ARG */
632 ACPI_GET16(parser_state
->aml
);
633 parser_state
->aml
+= 2;
636 case AML_DWORD_OP
: /* AML_DWORDATA_ARG */
639 ACPI_GET32(parser_state
->aml
);
640 parser_state
->aml
+= 4;
649 /* Fill in bytelist data */
651 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
652 arg
->named
.value
.size
= buffer_length
;
653 arg
->named
.data
= parser_state
->aml
;
656 /* Skip to End of byte data */
658 parser_state
->aml
= pkg_end
;
660 arg
= acpi_ps_alloc_op(AML_INT_NAMEPATH_OP
, aml
);
662 acpi_ps_free_op(field
);
666 /* Get the Namestring argument */
668 arg
->common
.value
.name
=
669 acpi_ps_get_next_namestring(parser_state
);
672 /* Link the buffer/namestring to parent (CONNECTION_OP) */
674 acpi_ps_append_arg(field
, arg
);
679 /* Opcode was set in previous switch */
686 /*******************************************************************************
688 * FUNCTION: acpi_ps_get_next_arg
690 * PARAMETERS: walk_state - Current state
691 * parser_state - Current parser state object
692 * arg_type - The argument type (AML_*_ARG)
693 * return_arg - Where the next arg is returned
695 * RETURN: Status, and an op object containing the next argument.
697 * DESCRIPTION: Get next argument (including complex list arguments that require
698 * pushing the parser stack)
700 ******************************************************************************/
703 acpi_ps_get_next_arg(struct acpi_walk_state
*walk_state
,
704 struct acpi_parse_state
*parser_state
,
705 u32 arg_type
, union acpi_parse_object
**return_arg
)
707 union acpi_parse_object
*arg
= NULL
;
708 union acpi_parse_object
*prev
= NULL
;
709 union acpi_parse_object
*field
;
711 acpi_status status
= AE_OK
;
713 ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg
, parser_state
);
715 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
716 "Expected argument type ARGP: %s (%2.2X)\n",
717 acpi_ut_get_argument_type_name(arg_type
), arg_type
));
725 case ARGP_NAMESTRING
:
727 /* Constants, strings, and namestrings are all the same size */
729 arg
= acpi_ps_alloc_op(AML_BYTE_OP
, parser_state
->aml
);
731 return_ACPI_STATUS(AE_NO_MEMORY
);
734 acpi_ps_get_next_simple_arg(parser_state
, arg_type
, arg
);
739 /* Package length, nothing returned */
741 parser_state
->pkg_end
=
742 acpi_ps_get_next_package_end(parser_state
);
747 if (parser_state
->aml
< parser_state
->pkg_end
) {
751 while (parser_state
->aml
< parser_state
->pkg_end
) {
752 field
= acpi_ps_get_next_field(parser_state
);
754 return_ACPI_STATUS(AE_NO_MEMORY
);
758 prev
->common
.next
= field
;
765 /* Skip to End of byte data */
767 parser_state
->aml
= parser_state
->pkg_end
;
773 if (parser_state
->aml
< parser_state
->pkg_end
) {
777 arg
= acpi_ps_alloc_op(AML_INT_BYTELIST_OP
,
780 return_ACPI_STATUS(AE_NO_MEMORY
);
783 /* Fill in bytelist data */
785 arg
->common
.value
.size
= (u32
)
786 ACPI_PTR_DIFF(parser_state
->pkg_end
,
788 arg
->named
.data
= parser_state
->aml
;
790 /* Skip to End of byte data */
792 parser_state
->aml
= parser_state
->pkg_end
;
796 case ARGP_SIMPLENAME
:
797 case ARGP_NAME_OR_REF
:
799 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
800 "**** SimpleName/NameOrRef: %s (%2.2X)\n",
801 acpi_ut_get_argument_type_name(arg_type
),
804 subop
= acpi_ps_peek_opcode(parser_state
);
806 acpi_ps_is_leading_char(subop
) ||
807 ACPI_IS_ROOT_PREFIX(subop
) ||
808 ACPI_IS_PARENT_PREFIX(subop
)) {
810 /* null_name or name_string */
813 acpi_ps_alloc_op(AML_INT_NAMEPATH_OP
,
816 return_ACPI_STATUS(AE_NO_MEMORY
);
820 acpi_ps_get_next_namepath(walk_state
, parser_state
,
822 ACPI_NOT_METHOD_CALL
);
824 /* Single complex argument, nothing returned */
826 walk_state
->arg_count
= 1;
833 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
834 "**** Target/Supername: %s (%2.2X)\n",
835 acpi_ut_get_argument_type_name(arg_type
),
838 subop
= acpi_ps_peek_opcode(parser_state
);
840 acpi_ps_is_leading_char(subop
) ||
841 ACPI_IS_ROOT_PREFIX(subop
) ||
842 ACPI_IS_PARENT_PREFIX(subop
)) {
844 /* NULL target (zero). Convert to a NULL namepath */
847 acpi_ps_alloc_op(AML_INT_NAMEPATH_OP
,
850 return_ACPI_STATUS(AE_NO_MEMORY
);
854 acpi_ps_get_next_namepath(walk_state
, parser_state
,
856 ACPI_POSSIBLE_METHOD_CALL
);
858 if (arg
->common
.aml_opcode
== AML_INT_METHODCALL_OP
) {
860 /* Free method call op and corresponding namestring sub-ob */
862 acpi_ps_free_op(arg
->common
.value
.arg
);
863 acpi_ps_free_op(arg
);
865 walk_state
->arg_count
= 1;
868 /* Single complex argument, nothing returned */
870 walk_state
->arg_count
= 1;
877 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
878 "**** TermArg/DataObj: %s (%2.2X)\n",
879 acpi_ut_get_argument_type_name(arg_type
),
882 /* Single complex argument, nothing returned */
884 walk_state
->arg_count
= 1;
887 case ARGP_DATAOBJLIST
:
891 if (parser_state
->aml
< parser_state
->pkg_end
) {
893 /* Non-empty list of variable arguments, nothing returned */
895 walk_state
->arg_count
= ACPI_VAR_ARGS
;
901 ACPI_ERROR((AE_INFO
, "Invalid ArgType: 0x%X", arg_type
));
902 status
= AE_AML_OPERAND_TYPE
;
907 return_ACPI_STATUS(status
);