1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
4 * Module Name: psargs - Parse AML opcode arguments
6 * Copyright (C) 2000 - 2023, 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 static void acpi_ps_free_field_list(union acpi_parse_object
*start
);
30 /*******************************************************************************
32 * FUNCTION: acpi_ps_get_next_package_length
34 * PARAMETERS: parser_state - Current parser state object
36 * RETURN: Decoded package length. On completion, the AML pointer points
37 * past the length byte or bytes.
39 * DESCRIPTION: Decode and return a package length field.
40 * Note: Largest package length is 28 bits, from ACPI specification
42 ******************************************************************************/
45 acpi_ps_get_next_package_length(struct acpi_parse_state
*parser_state
)
47 u8
*aml
= parser_state
->aml
;
48 u32 package_length
= 0;
50 u8 byte_zero_mask
= 0x3F; /* Default [0:5] */
52 ACPI_FUNCTION_TRACE(ps_get_next_package_length
);
55 * Byte 0 bits [6:7] contain the number of additional bytes
56 * used to encode the package length, either 0,1,2, or 3
58 byte_count
= (aml
[0] >> 6);
59 parser_state
->aml
+= ((acpi_size
)byte_count
+ 1);
61 /* Get bytes 3, 2, 1 as needed */
65 * Final bit positions for the package length bytes:
71 package_length
|= (aml
[byte_count
] << ((byte_count
<< 3) - 4));
73 byte_zero_mask
= 0x0F; /* Use bits [0:3] of byte 0 */
77 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
79 package_length
|= (aml
[0] & byte_zero_mask
);
80 return_UINT32(package_length
);
83 /*******************************************************************************
85 * FUNCTION: acpi_ps_get_next_package_end
87 * PARAMETERS: parser_state - Current parser state object
89 * RETURN: Pointer to end-of-package +1
91 * DESCRIPTION: Get next package length and return a pointer past the end of
92 * the package. Consumes the package length field
94 ******************************************************************************/
96 u8
*acpi_ps_get_next_package_end(struct acpi_parse_state
*parser_state
)
98 u8
*start
= parser_state
->aml
;
101 ACPI_FUNCTION_TRACE(ps_get_next_package_end
);
103 /* Function below updates parser_state->Aml */
105 package_length
= acpi_ps_get_next_package_length(parser_state
);
107 return_PTR(start
+ package_length
); /* end of package */
110 /*******************************************************************************
112 * FUNCTION: acpi_ps_get_next_namestring
114 * PARAMETERS: parser_state - Current parser state object
116 * RETURN: Pointer to the start of the name string (pointer points into
119 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
120 * prefix characters. Set parser state to point past the string.
121 * (Name is consumed from the AML.)
123 ******************************************************************************/
125 char *acpi_ps_get_next_namestring(struct acpi_parse_state
*parser_state
)
127 u8
*start
= parser_state
->aml
;
128 u8
*end
= parser_state
->aml
;
130 ACPI_FUNCTION_TRACE(ps_get_next_namestring
);
132 /* Point past any namestring prefix characters (backslash or carat) */
134 while (ACPI_IS_ROOT_PREFIX(*end
) || ACPI_IS_PARENT_PREFIX(*end
)) {
138 /* Decode the path prefix character */
151 case AML_DUAL_NAME_PREFIX
:
153 /* Two name segments */
155 end
+= 1 + (2 * ACPI_NAMESEG_SIZE
);
158 case AML_MULTI_NAME_PREFIX
:
160 /* Multiple name segments, 4 chars each, count in next byte */
162 end
+= 2 + (*(end
+ 1) * ACPI_NAMESEG_SIZE
);
167 /* Single name segment */
169 end
+= ACPI_NAMESEG_SIZE
;
173 parser_state
->aml
= end
;
174 return_PTR((char *)start
);
177 /*******************************************************************************
179 * FUNCTION: acpi_ps_get_next_namepath
181 * PARAMETERS: parser_state - Current parser state object
182 * arg - Where the namepath will be stored
183 * arg_count - If the namepath points to a control method
184 * the method's argument is returned here.
185 * possible_method_call - Whether the namepath can possibly be the
186 * start of a method call
190 * DESCRIPTION: Get next name (if method call, return # of required args).
191 * Names are looked up in the internal namespace to determine
192 * if the name represents a control method. If a method
193 * is found, the number of arguments to the method is returned.
194 * This information is critical for parsing to continue correctly.
196 ******************************************************************************/
199 acpi_ps_get_next_namepath(struct acpi_walk_state
*walk_state
,
200 struct acpi_parse_state
*parser_state
,
201 union acpi_parse_object
*arg
, u8 possible_method_call
)
205 union acpi_parse_object
*name_op
;
206 union acpi_operand_object
*method_desc
;
207 struct acpi_namespace_node
*node
;
208 u8
*start
= parser_state
->aml
;
210 ACPI_FUNCTION_TRACE(ps_get_next_namepath
);
212 path
= acpi_ps_get_next_namestring(parser_state
);
213 acpi_ps_init_op(arg
, AML_INT_NAMEPATH_OP
);
215 /* Null path case is allowed, just exit */
218 arg
->common
.value
.name
= path
;
219 return_ACPI_STATUS(AE_OK
);
223 * Lookup the name in the internal namespace, starting with the current
224 * scope. We don't want to add anything new to the namespace here,
225 * however, so we use MODE_EXECUTE.
226 * Allow searching of the parent tree, but don't open a new scope -
227 * we just want to lookup the object (must be mode EXECUTE to perform
230 status
= acpi_ns_lookup(walk_state
->scope_info
, path
,
231 ACPI_TYPE_ANY
, ACPI_IMODE_EXECUTE
,
232 ACPI_NS_SEARCH_PARENT
| ACPI_NS_DONT_OPEN_SCOPE
,
236 * If this name is a control method invocation, we must
237 * setup the method call
239 if (ACPI_SUCCESS(status
) &&
240 possible_method_call
&& (node
->type
== ACPI_TYPE_METHOD
)) {
241 if ((GET_CURRENT_ARG_TYPE(walk_state
->arg_types
) ==
243 || (GET_CURRENT_ARG_TYPE(walk_state
->arg_types
) ==
246 * acpi_ps_get_next_namestring has increased the AML pointer past
247 * the method invocation namestring, so we need to restore the
248 * saved AML pointer back to the original method invocation
251 walk_state
->parser_state
.aml
= start
;
252 walk_state
->arg_count
= 1;
253 acpi_ps_init_op(arg
, AML_INT_METHODCALL_OP
);
256 /* This name is actually a control method invocation */
258 method_desc
= acpi_ns_get_attached_object(node
);
259 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
260 "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
261 node
->name
.ascii
, node
, method_desc
, path
));
263 name_op
= acpi_ps_alloc_op(AML_INT_NAMEPATH_OP
, start
);
265 return_ACPI_STATUS(AE_NO_MEMORY
);
268 /* Change Arg into a METHOD CALL and attach name to it */
270 acpi_ps_init_op(arg
, AML_INT_METHODCALL_OP
);
271 name_op
->common
.value
.name
= path
;
273 /* Point METHODCALL/NAME to the METHOD Node */
275 name_op
->common
.node
= node
;
276 acpi_ps_append_arg(arg
, name_op
);
280 "Control Method %p has no attached object",
282 return_ACPI_STATUS(AE_AML_INTERNAL
);
285 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
286 "Control Method - %p Args %X\n",
287 node
, method_desc
->method
.param_count
));
289 /* Get the number of arguments to expect */
291 walk_state
->arg_count
= method_desc
->method
.param_count
;
292 return_ACPI_STATUS(AE_OK
);
296 * Special handling if the name was not found during the lookup -
297 * some not_found cases are allowed
299 if (status
== AE_NOT_FOUND
) {
301 /* 1) not_found is ok during load pass 1/2 (allow forward references) */
303 if ((walk_state
->parse_flags
& ACPI_PARSE_MODE_MASK
) !=
304 ACPI_PARSE_EXECUTE
) {
308 /* 2) not_found during a cond_ref_of(x) is ok by definition */
310 else if (walk_state
->op
->common
.aml_opcode
==
311 AML_CONDITIONAL_REF_OF_OP
) {
316 * 3) not_found while building a Package is ok at this point, we
317 * may flag as an error later if slack mode is not enabled.
318 * (Some ASL code depends on allowing this behavior)
320 else if ((arg
->common
.parent
) &&
321 ((arg
->common
.parent
->common
.aml_opcode
==
323 || (arg
->common
.parent
->common
.aml_opcode
==
324 AML_VARIABLE_PACKAGE_OP
))) {
329 /* Final exception check (may have been changed from code above) */
331 if (ACPI_FAILURE(status
)) {
332 ACPI_ERROR_NAMESPACE(walk_state
->scope_info
, path
, status
);
334 if ((walk_state
->parse_flags
& ACPI_PARSE_MODE_MASK
) ==
335 ACPI_PARSE_EXECUTE
) {
337 /* Report a control method execution error */
339 status
= acpi_ds_method_error(status
, walk_state
);
343 /* Save the namepath */
345 arg
->common
.value
.name
= path
;
346 return_ACPI_STATUS(status
);
349 /*******************************************************************************
351 * FUNCTION: acpi_ps_get_next_simple_arg
353 * PARAMETERS: parser_state - Current parser state object
354 * arg_type - The argument type (AML_*_ARG)
355 * arg - Where the argument is returned
359 * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
361 ******************************************************************************/
364 acpi_ps_get_next_simple_arg(struct acpi_parse_state
*parser_state
,
365 u32 arg_type
, union acpi_parse_object
*arg
)
369 u8
*aml
= parser_state
->aml
;
371 ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg
, arg_type
);
376 /* Get 1 byte from the AML stream */
378 opcode
= AML_BYTE_OP
;
379 arg
->common
.value
.integer
= (u64
) *aml
;
385 /* Get 2 bytes from the AML stream */
387 opcode
= AML_WORD_OP
;
388 ACPI_MOVE_16_TO_64(&arg
->common
.value
.integer
, aml
);
394 /* Get 4 bytes from the AML stream */
396 opcode
= AML_DWORD_OP
;
397 ACPI_MOVE_32_TO_64(&arg
->common
.value
.integer
, aml
);
403 /* Get 8 bytes from the AML stream */
405 opcode
= AML_QWORD_OP
;
406 ACPI_MOVE_64_TO_64(&arg
->common
.value
.integer
, aml
);
412 /* Get a pointer to the string, point past the string */
414 opcode
= AML_STRING_OP
;
415 arg
->common
.value
.string
= ACPI_CAST_PTR(char, aml
);
417 /* Find the null terminator */
420 while (aml
[length
]) {
427 case ARGP_NAMESTRING
:
429 acpi_ps_init_op(arg
, AML_INT_NAMEPATH_OP
);
430 arg
->common
.value
.name
=
431 acpi_ps_get_next_namestring(parser_state
);
436 ACPI_ERROR((AE_INFO
, "Invalid ArgType 0x%X", arg_type
));
440 acpi_ps_init_op(arg
, opcode
);
441 parser_state
->aml
+= length
;
445 /*******************************************************************************
447 * FUNCTION: acpi_ps_get_next_field
449 * PARAMETERS: parser_state - Current parser state object
451 * RETURN: A newly allocated FIELD op
453 * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
455 ******************************************************************************/
457 static union acpi_parse_object
*acpi_ps_get_next_field(struct acpi_parse_state
461 union acpi_parse_object
*field
;
462 union acpi_parse_object
*arg
= NULL
;
472 ACPI_FUNCTION_TRACE(ps_get_next_field
);
474 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
475 aml
= parser_state
->aml
;
477 /* Determine field type */
479 switch (ACPI_GET8(parser_state
->aml
)) {
480 case AML_FIELD_OFFSET_OP
:
482 opcode
= AML_INT_RESERVEDFIELD_OP
;
486 case AML_FIELD_ACCESS_OP
:
488 opcode
= AML_INT_ACCESSFIELD_OP
;
492 case AML_FIELD_CONNECTION_OP
:
494 opcode
= AML_INT_CONNECTION_OP
;
498 case AML_FIELD_EXT_ACCESS_OP
:
500 opcode
= AML_INT_EXTACCESSFIELD_OP
;
506 opcode
= AML_INT_NAMEDFIELD_OP
;
510 /* Allocate a new field op */
512 field
= acpi_ps_alloc_op(opcode
, aml
);
517 /* Decode the field type */
519 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
521 case AML_INT_NAMEDFIELD_OP
:
523 /* Get the 4-character name */
525 ACPI_MOVE_32_TO_32(&name
, parser_state
->aml
);
526 acpi_ps_set_name(field
, name
);
527 parser_state
->aml
+= ACPI_NAMESEG_SIZE
;
529 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
531 #ifdef ACPI_ASL_COMPILER
533 * Because the package length isn't represented as a parse tree object,
534 * take comments surrounding this and add to the previously created
537 if (field
->common
.inline_comment
) {
538 field
->common
.name_comment
=
539 field
->common
.inline_comment
;
541 field
->common
.inline_comment
= acpi_gbl_current_inline_comment
;
542 acpi_gbl_current_inline_comment
= NULL
;
545 /* Get the length which is encoded as a package length */
547 field
->common
.value
.size
=
548 acpi_ps_get_next_package_length(parser_state
);
551 case AML_INT_RESERVEDFIELD_OP
:
553 /* Get the length which is encoded as a package length */
555 field
->common
.value
.size
=
556 acpi_ps_get_next_package_length(parser_state
);
559 case AML_INT_ACCESSFIELD_OP
:
560 case AML_INT_EXTACCESSFIELD_OP
:
563 * Get access_type and access_attrib and merge into the field Op
564 * access_type is first operand, access_attribute is second. stuff
565 * these bytes into the node integer value for convenience.
568 /* Get the two bytes (Type/Attribute) */
570 access_type
= ACPI_GET8(parser_state
->aml
);
572 access_attribute
= ACPI_GET8(parser_state
->aml
);
575 field
->common
.value
.integer
= (u8
)access_type
;
576 field
->common
.value
.integer
|= (u16
)(access_attribute
<< 8);
578 /* This opcode has a third byte, access_length */
580 if (opcode
== AML_INT_EXTACCESSFIELD_OP
) {
581 access_length
= ACPI_GET8(parser_state
->aml
);
584 field
->common
.value
.integer
|=
585 (u32
)(access_length
<< 16);
589 case AML_INT_CONNECTION_OP
:
592 * Argument for Connection operator can be either a Buffer
593 * (resource descriptor), or a name_string.
595 aml
= parser_state
->aml
;
596 if (ACPI_GET8(parser_state
->aml
) == AML_BUFFER_OP
) {
599 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
600 pkg_end
= parser_state
->aml
;
602 acpi_ps_get_next_package_length(parser_state
);
603 pkg_end
+= pkg_length
;
605 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
606 if (parser_state
->aml
< pkg_end
) {
611 acpi_ps_alloc_op(AML_INT_BYTELIST_OP
, aml
);
613 acpi_ps_free_op(field
);
617 /* Get the actual buffer length argument */
619 opcode
= ACPI_GET8(parser_state
->aml
);
622 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
624 case AML_BYTE_OP
: /* AML_BYTEDATA_ARG */
627 ACPI_GET8(parser_state
->aml
);
628 parser_state
->aml
+= 1;
631 case AML_WORD_OP
: /* AML_WORDDATA_ARG */
634 ACPI_GET16(parser_state
->aml
);
635 parser_state
->aml
+= 2;
638 case AML_DWORD_OP
: /* AML_DWORDATA_ARG */
641 ACPI_GET32(parser_state
->aml
);
642 parser_state
->aml
+= 4;
651 /* Fill in bytelist data */
653 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state
);
654 arg
->named
.value
.size
= buffer_length
;
655 arg
->named
.data
= parser_state
->aml
;
658 /* Skip to End of byte data */
660 parser_state
->aml
= pkg_end
;
662 arg
= acpi_ps_alloc_op(AML_INT_NAMEPATH_OP
, aml
);
664 acpi_ps_free_op(field
);
668 /* Get the Namestring argument */
670 arg
->common
.value
.name
=
671 acpi_ps_get_next_namestring(parser_state
);
674 /* Link the buffer/namestring to parent (CONNECTION_OP) */
676 acpi_ps_append_arg(field
, arg
);
681 /* Opcode was set in previous switch */
688 /*******************************************************************************
690 * FUNCTION: acpi_ps_free_field_list
692 * PARAMETERS: start - First Op in field list
696 * DESCRIPTION: Free all Op objects inside a field list.
698 ******************************************************************************/
700 static void acpi_ps_free_field_list(union acpi_parse_object
*start
)
702 union acpi_parse_object
*cur
= start
;
703 union acpi_parse_object
*next
;
704 union acpi_parse_object
*arg
;
707 next
= cur
->common
.next
;
709 /* AML_INT_CONNECTION_OP can have a single argument */
711 arg
= acpi_ps_get_arg(cur
, 0);
713 acpi_ps_free_op(arg
);
716 acpi_ps_free_op(cur
);
721 /*******************************************************************************
723 * FUNCTION: acpi_ps_get_next_arg
725 * PARAMETERS: walk_state - Current state
726 * parser_state - Current parser state object
727 * arg_type - The argument type (AML_*_ARG)
728 * return_arg - Where the next arg is returned
730 * RETURN: Status, and an op object containing the next argument.
732 * DESCRIPTION: Get next argument (including complex list arguments that require
733 * pushing the parser stack)
735 ******************************************************************************/
738 acpi_ps_get_next_arg(struct acpi_walk_state
*walk_state
,
739 struct acpi_parse_state
*parser_state
,
740 u32 arg_type
, union acpi_parse_object
**return_arg
)
742 union acpi_parse_object
*arg
= NULL
;
743 union acpi_parse_object
*prev
= NULL
;
744 union acpi_parse_object
*field
;
746 acpi_status status
= AE_OK
;
748 ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg
, parser_state
);
750 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
751 "Expected argument type ARGP: %s (%2.2X)\n",
752 acpi_ut_get_argument_type_name(arg_type
), arg_type
));
760 case ARGP_NAMESTRING
:
762 /* Constants, strings, and namestrings are all the same size */
764 arg
= acpi_ps_alloc_op(AML_BYTE_OP
, parser_state
->aml
);
766 return_ACPI_STATUS(AE_NO_MEMORY
);
769 acpi_ps_get_next_simple_arg(parser_state
, arg_type
, arg
);
774 /* Package length, nothing returned */
776 parser_state
->pkg_end
=
777 acpi_ps_get_next_package_end(parser_state
);
782 if (parser_state
->aml
< parser_state
->pkg_end
) {
786 while (parser_state
->aml
< parser_state
->pkg_end
) {
787 field
= acpi_ps_get_next_field(parser_state
);
790 acpi_ps_free_field_list(arg
);
793 return_ACPI_STATUS(AE_NO_MEMORY
);
797 prev
->common
.next
= field
;
804 /* Skip to End of byte data */
806 parser_state
->aml
= parser_state
->pkg_end
;
812 if (parser_state
->aml
< parser_state
->pkg_end
) {
816 arg
= acpi_ps_alloc_op(AML_INT_BYTELIST_OP
,
819 return_ACPI_STATUS(AE_NO_MEMORY
);
822 /* Fill in bytelist data */
824 arg
->common
.value
.size
= (u32
)
825 ACPI_PTR_DIFF(parser_state
->pkg_end
,
827 arg
->named
.data
= parser_state
->aml
;
829 /* Skip to End of byte data */
831 parser_state
->aml
= parser_state
->pkg_end
;
835 case ARGP_SIMPLENAME
:
836 case ARGP_NAME_OR_REF
:
838 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
839 "**** SimpleName/NameOrRef: %s (%2.2X)\n",
840 acpi_ut_get_argument_type_name(arg_type
),
843 subop
= acpi_ps_peek_opcode(parser_state
);
845 acpi_ps_is_leading_char(subop
) ||
846 ACPI_IS_ROOT_PREFIX(subop
) ||
847 ACPI_IS_PARENT_PREFIX(subop
)) {
849 /* null_name or name_string */
852 acpi_ps_alloc_op(AML_INT_NAMEPATH_OP
,
855 return_ACPI_STATUS(AE_NO_MEMORY
);
859 acpi_ps_get_next_namepath(walk_state
, parser_state
,
861 ACPI_NOT_METHOD_CALL
);
862 if (ACPI_FAILURE(status
)) {
863 acpi_ps_free_op(arg
);
864 return_ACPI_STATUS(status
);
867 /* Single complex argument, nothing returned */
869 walk_state
->arg_count
= 1;
876 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
877 "**** Target/Supername: %s (%2.2X)\n",
878 acpi_ut_get_argument_type_name(arg_type
),
881 subop
= acpi_ps_peek_opcode(parser_state
);
883 acpi_ps_is_leading_char(subop
) ||
884 ACPI_IS_ROOT_PREFIX(subop
) ||
885 ACPI_IS_PARENT_PREFIX(subop
)) {
887 /* NULL target (zero). Convert to a NULL namepath */
890 acpi_ps_alloc_op(AML_INT_NAMEPATH_OP
,
893 return_ACPI_STATUS(AE_NO_MEMORY
);
897 acpi_ps_get_next_namepath(walk_state
, parser_state
,
899 ACPI_POSSIBLE_METHOD_CALL
);
900 if (ACPI_FAILURE(status
)) {
901 acpi_ps_free_op(arg
);
902 return_ACPI_STATUS(status
);
905 if (arg
->common
.aml_opcode
== AML_INT_METHODCALL_OP
) {
907 /* Free method call op and corresponding namestring sub-ob */
909 acpi_ps_free_op(arg
->common
.value
.arg
);
910 acpi_ps_free_op(arg
);
912 walk_state
->arg_count
= 1;
915 /* Single complex argument, nothing returned */
917 walk_state
->arg_count
= 1;
924 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
925 "**** TermArg/DataObj: %s (%2.2X)\n",
926 acpi_ut_get_argument_type_name(arg_type
),
929 /* Single complex argument, nothing returned */
931 walk_state
->arg_count
= 1;
934 case ARGP_DATAOBJLIST
:
938 if (parser_state
->aml
< parser_state
->pkg_end
) {
940 /* Non-empty list of variable arguments, nothing returned */
942 walk_state
->arg_count
= ACPI_VAR_ARGS
;
948 ACPI_ERROR((AE_INFO
, "Invalid ArgType: 0x%X", arg_type
));
949 status
= AE_AML_OPERAND_TYPE
;
954 return_ACPI_STATUS(status
);