1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /****************************************************************************** 3 * 4 * Module Name: psargs - Parse AML opcode arguments 5 * 6 * Copyright (C) 2000 - 2026, Intel Corp. 7 * 8 *****************************************************************************/ 9 10 #include <acpi/acpi.h> 11 #include "accommon.h" 12 #include "acparser.h" 13 #include "amlcode.h" 14 #include "acnamesp.h" 15 #include "acdispat.h" 16 #include "acconvert.h" 17 18 #define _COMPONENT ACPI_PARSER 19 ACPI_MODULE_NAME("psargs") 20 21 /* Local prototypes */ 22 static u32 23 acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state); 24 25 static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state 26 *parser_state); 27 28 static void acpi_ps_free_field_list(union acpi_parse_object *start); 29 30 /******************************************************************************* 31 * 32 * FUNCTION: acpi_ps_get_next_package_length 33 * 34 * PARAMETERS: parser_state - Current parser state object 35 * 36 * RETURN: Decoded package length. On completion, the AML pointer points 37 * past the length byte or bytes. 38 * 39 * DESCRIPTION: Decode and return a package length field. 40 * Note: Largest package length is 28 bits, from ACPI specification 41 * 42 ******************************************************************************/ 43 44 static u32 45 acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) 46 { 47 u8 *aml = parser_state->aml; 48 u32 package_length = 0; 49 u32 byte_count; 50 u8 byte_zero_mask = 0x3F; /* Default [0:5] */ 51 u32 remaining; 52 53 ACPI_FUNCTION_TRACE(ps_get_next_package_length); 54 55 /* 56 * Byte 0 bits [6:7] contain the number of additional bytes 57 * used to encode the package length, either 0,1,2, or 3 58 */ 59 60 /* Check if we have at least one byte to read */ 61 remaining = (u32)ACPI_PTR_DIFF(parser_state->aml_end, aml); 62 if (remaining == 0) { 63 return_UINT32(0); 64 } 65 66 byte_count = (aml[0] >> 6); 67 68 /* Validate byte_count and ensure we have enough bytes to read */ 69 if (byte_count >= remaining) { 70 71 /* Clamp to available bytes and advance to end */ 72 parser_state->aml = parser_state->aml_end; 73 return_UINT32(0); 74 } 75 76 parser_state->aml += ((acpi_size)byte_count + 1); 77 78 /* Get bytes 3, 2, 1 as needed */ 79 80 while (byte_count) { 81 /* 82 * Final bit positions for the package length bytes: 83 * Byte3->[20:27] 84 * Byte2->[12:19] 85 * Byte1->[04:11] 86 * Byte0->[00:03] 87 */ 88 package_length |= (aml[byte_count] << ((byte_count << 3) - 4)); 89 90 byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */ 91 byte_count--; 92 } 93 94 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ 95 96 package_length |= (aml[0] & byte_zero_mask); 97 return_UINT32(package_length); 98 } 99 100 /******************************************************************************* 101 * 102 * FUNCTION: acpi_ps_get_next_package_end 103 * 104 * PARAMETERS: parser_state - Current parser state object 105 * 106 * RETURN: Pointer to end-of-package +1 107 * 108 * DESCRIPTION: Get next package length and return a pointer past the end of 109 * the package. Consumes the package length field 110 * 111 ******************************************************************************/ 112 113 u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state) 114 { 115 u8 *start = parser_state->aml; 116 u32 package_length; 117 118 ACPI_FUNCTION_TRACE(ps_get_next_package_end); 119 120 /* Function below updates parser_state->Aml */ 121 122 package_length = acpi_ps_get_next_package_length(parser_state); 123 124 return_PTR(start + package_length); /* end of package */ 125 } 126 127 /******************************************************************************* 128 * 129 * FUNCTION: acpi_ps_get_next_namestring 130 * 131 * PARAMETERS: parser_state - Current parser state object 132 * 133 * RETURN: Pointer to the start of the name string (pointer points into 134 * the AML. 135 * 136 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name 137 * prefix characters. Set parser state to point past the string. 138 * (Name is consumed from the AML.) 139 * 140 ******************************************************************************/ 141 142 char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) 143 { 144 u8 *start = parser_state->aml; 145 u8 *end = parser_state->aml; 146 147 ACPI_FUNCTION_TRACE(ps_get_next_namestring); 148 149 /* Point past any namestring prefix characters (backslash or carat) */ 150 151 while (end < parser_state->aml_end && 152 (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end))) { 153 end++; 154 } 155 156 if (end >= parser_state->aml_end) { 157 parser_state->aml = parser_state->aml_end; 158 return_PTR(NULL); 159 } 160 161 /* Decode the path prefix character */ 162 163 switch (*end) { 164 case 0: 165 166 /* null_name */ 167 168 if (end == start) { 169 start = NULL; 170 } 171 end++; 172 break; 173 174 case AML_DUAL_NAME_PREFIX: 175 176 /* Two name segments */ 177 178 end += 1 + (2 * ACPI_NAMESEG_SIZE); 179 break; 180 181 case AML_MULTI_NAME_PREFIX: 182 183 /* Multiple name segments, 4 chars each, count in next byte */ 184 185 if ((end + 1) >= parser_state->aml_end) { 186 parser_state->aml = parser_state->aml_end; 187 return_PTR(NULL); 188 } 189 190 end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE); 191 break; 192 193 default: 194 195 /* Single name segment */ 196 197 end += ACPI_NAMESEG_SIZE; 198 break; 199 } 200 201 if (end > parser_state->aml_end) { 202 parser_state->aml = parser_state->aml_end; 203 return_PTR(NULL); 204 } 205 206 parser_state->aml = end; 207 return_PTR((char *)start); 208 } 209 210 /******************************************************************************* 211 * 212 * FUNCTION: acpi_ps_get_next_namepath 213 * 214 * PARAMETERS: parser_state - Current parser state object 215 * arg - Where the namepath will be stored 216 * arg_count - If the namepath points to a control method 217 * the method's argument is returned here. 218 * possible_method_call - Whether the namepath can possibly be the 219 * start of a method call 220 * 221 * RETURN: Status 222 * 223 * DESCRIPTION: Get next name (if method call, return # of required args). 224 * Names are looked up in the internal namespace to determine 225 * if the name represents a control method. If a method 226 * is found, the number of arguments to the method is returned. 227 * This information is critical for parsing to continue correctly. 228 * 229 ******************************************************************************/ 230 231 acpi_status 232 acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, 233 struct acpi_parse_state *parser_state, 234 union acpi_parse_object *arg, u8 possible_method_call) 235 { 236 acpi_status status; 237 char *path; 238 union acpi_parse_object *name_op; 239 union acpi_operand_object *method_desc; 240 struct acpi_namespace_node *node; 241 u8 *start = parser_state->aml; 242 243 ACPI_FUNCTION_TRACE(ps_get_next_namepath); 244 245 path = acpi_ps_get_next_namestring(parser_state); 246 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); 247 248 /* Null path case is allowed, just exit */ 249 250 if (!path) { 251 arg->common.value.name = path; 252 return_ACPI_STATUS(AE_OK); 253 } 254 255 /* 256 * Lookup the name in the internal namespace, starting with the current 257 * scope. We don't want to add anything new to the namespace here, 258 * however, so we use MODE_EXECUTE. 259 * Allow searching of the parent tree, but don't open a new scope - 260 * we just want to lookup the object (must be mode EXECUTE to perform 261 * the upsearch) 262 */ 263 status = acpi_ns_lookup(walk_state->scope_info, path, 264 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 265 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 266 NULL, &node); 267 268 /* 269 * If this name is a control method invocation, we must 270 * setup the method call 271 */ 272 if (ACPI_SUCCESS(status) && 273 possible_method_call && (node->type == ACPI_TYPE_METHOD)) { 274 if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) == 275 ARGP_SUPERNAME) 276 || (GET_CURRENT_ARG_TYPE(walk_state->arg_types) == 277 ARGP_TARGET)) { 278 /* 279 * acpi_ps_get_next_namestring has increased the AML pointer past 280 * the method invocation namestring, so we need to restore the 281 * saved AML pointer back to the original method invocation 282 * namestring. 283 */ 284 walk_state->parser_state.aml = start; 285 walk_state->arg_count = 1; 286 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); 287 } 288 289 /* This name is actually a control method invocation */ 290 291 method_desc = acpi_ns_get_attached_object(node); 292 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 293 "Control Method invocation %4.4s - %p Desc %p Path=%p\n", 294 node->name.ascii, node, method_desc, path)); 295 296 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start); 297 if (!name_op) { 298 return_ACPI_STATUS(AE_NO_MEMORY); 299 } 300 301 /* Change Arg into a METHOD CALL and attach name to it */ 302 303 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); 304 name_op->common.value.name = path; 305 306 /* Point METHODCALL/NAME to the METHOD Node */ 307 308 name_op->common.node = node; 309 acpi_ps_append_arg(arg, name_op); 310 311 if (!method_desc) { 312 ACPI_ERROR((AE_INFO, 313 "Control Method %p has no attached object", 314 node)); 315 return_ACPI_STATUS(AE_AML_INTERNAL); 316 } 317 318 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 319 "Control Method - %p Args %X\n", 320 node, method_desc->method.param_count)); 321 322 /* Get the number of arguments to expect */ 323 324 walk_state->arg_count = method_desc->method.param_count; 325 return_ACPI_STATUS(AE_OK); 326 } 327 328 /* 329 * Special handling if the name was not found during the lookup - 330 * some not_found cases are allowed 331 */ 332 if (status == AE_NOT_FOUND) { 333 334 /* 1) not_found is ok during load pass 1/2 (allow forward references) */ 335 336 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) != 337 ACPI_PARSE_EXECUTE) { 338 status = AE_OK; 339 } 340 341 /* 2) not_found during a cond_ref_of(x) is ok by definition */ 342 343 else if (walk_state->op->common.aml_opcode == 344 AML_CONDITIONAL_REF_OF_OP) { 345 status = AE_OK; 346 } 347 348 /* 349 * 3) not_found while building a Package is ok at this point, we 350 * may flag as an error later if slack mode is not enabled. 351 * (Some ASL code depends on allowing this behavior) 352 */ 353 else if ((arg->common.parent) && 354 ((arg->common.parent->common.aml_opcode == 355 AML_PACKAGE_OP) 356 || (arg->common.parent->common.aml_opcode == 357 AML_VARIABLE_PACKAGE_OP))) { 358 status = AE_OK; 359 } 360 } 361 362 /* Final exception check (may have been changed from code above) */ 363 364 if (ACPI_FAILURE(status)) { 365 ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status); 366 367 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == 368 ACPI_PARSE_EXECUTE) { 369 370 /* Report a control method execution error */ 371 372 status = acpi_ds_method_error(status, walk_state); 373 } 374 } 375 376 /* Save the namepath */ 377 378 arg->common.value.name = path; 379 return_ACPI_STATUS(status); 380 } 381 382 /******************************************************************************* 383 * 384 * FUNCTION: acpi_ps_get_next_simple_arg 385 * 386 * PARAMETERS: parser_state - Current parser state object 387 * arg_type - The argument type (AML_*_ARG) 388 * arg - Where the argument is returned 389 * 390 * RETURN: None 391 * 392 * DESCRIPTION: Get the next simple argument (constant, string, or namestring) 393 * 394 ******************************************************************************/ 395 396 void 397 acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, 398 u32 arg_type, union acpi_parse_object *arg) 399 { 400 u32 length; 401 u16 opcode; 402 u8 *aml = parser_state->aml; 403 u32 remaining = (u32)ACPI_PTR_DIFF(parser_state->aml_end, aml); 404 u64 partial_value; 405 406 ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type); 407 408 switch (arg_type) { 409 case ARGP_BYTEDATA: 410 411 /* Get 1 byte from the AML stream */ 412 413 opcode = AML_BYTE_OP; 414 if (remaining >= 1) { 415 arg->common.value.integer = (u64)*aml; 416 length = 1; 417 } else { 418 arg->common.value.integer = 0; 419 length = 0; 420 } 421 break; 422 423 case ARGP_WORDDATA: 424 425 /* Get 2 bytes from the AML stream */ 426 427 opcode = AML_WORD_OP; 428 if (remaining >= 2) { 429 ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml); 430 length = 2; 431 } else { 432 arg->common.value.integer = 0; 433 length = 0; 434 if (remaining > 0) { 435 partial_value = 0; 436 memcpy(&partial_value, aml, remaining); 437 arg->common.value.integer = partial_value; 438 length = remaining; 439 } 440 } 441 break; 442 443 case ARGP_DWORDDATA: 444 445 /* Get 4 bytes from the AML stream */ 446 447 opcode = AML_DWORD_OP; 448 if (remaining >= 4) { 449 ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml); 450 length = 4; 451 } else { 452 arg->common.value.integer = 0; 453 length = 0; 454 if (remaining > 0) { 455 partial_value = 0; 456 memcpy(&partial_value, aml, remaining); 457 arg->common.value.integer = partial_value; 458 length = remaining; 459 } 460 } 461 break; 462 463 case ARGP_QWORDDATA: 464 465 /* Get 8 bytes from the AML stream */ 466 467 opcode = AML_QWORD_OP; 468 if (remaining >= 8) { 469 ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml); 470 length = 8; 471 } else { 472 arg->common.value.integer = 0; 473 length = 0; 474 if (remaining > 0) { 475 partial_value = 0; 476 memcpy(&partial_value, aml, remaining); 477 arg->common.value.integer = partial_value; 478 length = remaining; 479 } 480 } 481 break; 482 483 case ARGP_CHARLIST: 484 485 /* Get a pointer to the string, point past the string */ 486 487 opcode = AML_STRING_OP; 488 arg->common.value.string = ACPI_CAST_PTR(char, aml); 489 490 /* Find the null terminator */ 491 492 length = 0; 493 while ((length < remaining) && aml[length]) { 494 length++; 495 } 496 if (length < remaining) { 497 498 /* Account for the terminating null */ 499 length++; 500 } else { 501 /* 502 * No terminator found - add null at buffer boundary 503 * and report a warning 504 */ 505 ACPI_WARNING((AE_INFO, 506 "Invalid AML string: no null terminator, truncating at offset %u", 507 (u32)(aml - parser_state->aml))); 508 509 /* Add null terminator at the boundary */ 510 if (remaining > 0) { 511 aml[remaining - 1] = 0; 512 length = remaining; 513 } 514 } 515 break; 516 517 case ARGP_NAME: 518 case ARGP_NAMESTRING: 519 520 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); 521 arg->common.value.name = 522 acpi_ps_get_next_namestring(parser_state); 523 return_VOID; 524 525 default: 526 527 ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type)); 528 return_VOID; 529 } 530 531 acpi_ps_init_op(arg, opcode); 532 parser_state->aml += length; 533 return_VOID; 534 } 535 536 /******************************************************************************* 537 * 538 * FUNCTION: acpi_ps_get_next_field 539 * 540 * PARAMETERS: parser_state - Current parser state object 541 * 542 * RETURN: A newly allocated FIELD op 543 * 544 * DESCRIPTION: Get next field (named_field, reserved_field, or access_field) 545 * 546 ******************************************************************************/ 547 548 static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state 549 *parser_state) 550 { 551 u8 *aml; 552 union acpi_parse_object *field; 553 union acpi_parse_object *arg = NULL; 554 u16 opcode; 555 u32 name; 556 u8 access_type; 557 u8 access_attribute; 558 u8 access_length; 559 u32 pkg_length; 560 u8 *pkg_end; 561 u32 buffer_length; 562 563 ACPI_FUNCTION_TRACE(ps_get_next_field); 564 565 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 566 aml = parser_state->aml; 567 568 if (aml >= parser_state->aml_end) { 569 return_PTR(NULL); 570 } 571 572 /* Determine field type */ 573 574 switch (ACPI_GET8(parser_state->aml)) { 575 case AML_FIELD_OFFSET_OP: 576 577 opcode = AML_INT_RESERVEDFIELD_OP; 578 parser_state->aml++; 579 break; 580 581 case AML_FIELD_ACCESS_OP: 582 583 opcode = AML_INT_ACCESSFIELD_OP; 584 parser_state->aml++; 585 break; 586 587 case AML_FIELD_CONNECTION_OP: 588 589 opcode = AML_INT_CONNECTION_OP; 590 parser_state->aml++; 591 break; 592 593 case AML_FIELD_EXT_ACCESS_OP: 594 595 opcode = AML_INT_EXTACCESSFIELD_OP; 596 parser_state->aml++; 597 break; 598 599 default: 600 601 opcode = AML_INT_NAMEDFIELD_OP; 602 break; 603 } 604 605 /* Allocate a new field op */ 606 607 field = acpi_ps_alloc_op(opcode, aml); 608 if (!field) { 609 return_PTR(NULL); 610 } 611 612 /* Decode the field type */ 613 614 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 615 switch (opcode) { 616 case AML_INT_NAMEDFIELD_OP: 617 618 /* Get the 4-character name */ 619 620 if ((parser_state->aml + ACPI_NAMESEG_SIZE) > 621 parser_state->aml_end) { 622 acpi_ps_free_op(field); 623 return_PTR(NULL); 624 } 625 ACPI_MOVE_32_TO_32(&name, parser_state->aml); 626 acpi_ps_set_name(field, name); 627 parser_state->aml += ACPI_NAMESEG_SIZE; 628 629 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 630 631 #ifdef ACPI_ASL_COMPILER 632 /* 633 * Because the package length isn't represented as a parse tree object, 634 * take comments surrounding this and add to the previously created 635 * parse node. 636 */ 637 if (field->common.inline_comment) { 638 field->common.name_comment = 639 field->common.inline_comment; 640 } 641 field->common.inline_comment = acpi_gbl_current_inline_comment; 642 acpi_gbl_current_inline_comment = NULL; 643 #endif 644 645 /* Get the length which is encoded as a package length */ 646 647 field->common.value.size = 648 acpi_ps_get_next_package_length(parser_state); 649 break; 650 651 case AML_INT_RESERVEDFIELD_OP: 652 653 /* Get the length which is encoded as a package length */ 654 655 field->common.value.size = 656 acpi_ps_get_next_package_length(parser_state); 657 break; 658 659 case AML_INT_ACCESSFIELD_OP: 660 case AML_INT_EXTACCESSFIELD_OP: 661 662 /* 663 * Get access_type and access_attrib and merge into the field Op 664 * access_type is first operand, access_attribute is second. stuff 665 * these bytes into the node integer value for convenience. 666 */ 667 668 /* Get the two bytes (Type/Attribute) */ 669 670 if ((parser_state->aml + 2) > parser_state->aml_end) { 671 acpi_ps_free_op(field); 672 return_PTR(NULL); 673 } 674 access_type = ACPI_GET8(parser_state->aml); 675 parser_state->aml++; 676 access_attribute = ACPI_GET8(parser_state->aml); 677 parser_state->aml++; 678 679 field->common.value.integer = (u8)access_type; 680 field->common.value.integer |= (u16)(access_attribute << 8); 681 682 /* This opcode has a third byte, access_length */ 683 684 if (opcode == AML_INT_EXTACCESSFIELD_OP) { 685 if (parser_state->aml >= parser_state->aml_end) { 686 acpi_ps_free_op(field); 687 return_PTR(NULL); 688 } 689 access_length = ACPI_GET8(parser_state->aml); 690 parser_state->aml++; 691 692 field->common.value.integer |= 693 (u32)(access_length << 16); 694 } 695 break; 696 697 case AML_INT_CONNECTION_OP: 698 699 /* 700 * Argument for Connection operator can be either a Buffer 701 * (resource descriptor), or a name_string. 702 */ 703 aml = parser_state->aml; 704 if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) { 705 parser_state->aml++; 706 707 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 708 pkg_end = parser_state->aml; 709 pkg_length = 710 acpi_ps_get_next_package_length(parser_state); 711 pkg_end += pkg_length; 712 713 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 714 if (parser_state->aml < pkg_end) { 715 716 /* Non-empty list */ 717 718 arg = 719 acpi_ps_alloc_op(AML_INT_BYTELIST_OP, aml); 720 if (!arg) { 721 acpi_ps_free_op(field); 722 return_PTR(NULL); 723 } 724 725 /* Get the actual buffer length argument */ 726 727 opcode = ACPI_GET8(parser_state->aml); 728 parser_state->aml++; 729 730 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 731 switch (opcode) { 732 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 733 734 buffer_length = 735 ACPI_GET8(parser_state->aml); 736 parser_state->aml += 1; 737 break; 738 739 case AML_WORD_OP: /* AML_WORDDATA_ARG */ 740 741 buffer_length = 742 ACPI_GET16(parser_state->aml); 743 parser_state->aml += 2; 744 break; 745 746 case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 747 748 buffer_length = 749 ACPI_GET32(parser_state->aml); 750 parser_state->aml += 4; 751 break; 752 753 default: 754 755 buffer_length = 0; 756 break; 757 } 758 759 /* Fill in bytelist data */ 760 761 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 762 arg->named.value.size = buffer_length; 763 arg->named.data = parser_state->aml; 764 } 765 766 /* Skip to End of byte data */ 767 768 parser_state->aml = pkg_end; 769 } else { 770 arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, aml); 771 if (!arg) { 772 acpi_ps_free_op(field); 773 return_PTR(NULL); 774 } 775 776 /* Get the Namestring argument */ 777 778 arg->common.value.name = 779 acpi_ps_get_next_namestring(parser_state); 780 } 781 782 /* Link the buffer/namestring to parent (CONNECTION_OP) */ 783 784 acpi_ps_append_arg(field, arg); 785 break; 786 787 default: 788 789 /* Opcode was set in previous switch */ 790 break; 791 } 792 793 return_PTR(field); 794 } 795 796 /******************************************************************************* 797 * 798 * FUNCTION: acpi_ps_free_field_list 799 * 800 * PARAMETERS: start - First Op in field list 801 * 802 * RETURN: None. 803 * 804 * DESCRIPTION: Free all Op objects inside a field list. 805 * 806 ******************************************************************************/ 807 808 static void acpi_ps_free_field_list(union acpi_parse_object *start) 809 { 810 union acpi_parse_object *cur = start; 811 union acpi_parse_object *next; 812 union acpi_parse_object *arg; 813 814 while (cur) { 815 next = cur->common.next; 816 817 /* AML_INT_CONNECTION_OP can have a single argument */ 818 819 arg = acpi_ps_get_arg(cur, 0); 820 if (arg) { 821 acpi_ps_free_op(arg); 822 } 823 824 acpi_ps_free_op(cur); 825 cur = next; 826 } 827 } 828 829 /******************************************************************************* 830 * 831 * FUNCTION: acpi_ps_get_next_arg 832 * 833 * PARAMETERS: walk_state - Current state 834 * parser_state - Current parser state object 835 * arg_type - The argument type (AML_*_ARG) 836 * return_arg - Where the next arg is returned 837 * 838 * RETURN: Status, and an op object containing the next argument. 839 * 840 * DESCRIPTION: Get next argument (including complex list arguments that require 841 * pushing the parser stack) 842 * 843 ******************************************************************************/ 844 845 acpi_status 846 acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, 847 struct acpi_parse_state *parser_state, 848 u32 arg_type, union acpi_parse_object **return_arg) 849 { 850 union acpi_parse_object *arg = NULL; 851 union acpi_parse_object *prev = NULL; 852 union acpi_parse_object *field; 853 u32 subop; 854 acpi_status status = AE_OK; 855 856 ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state); 857 858 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 859 "Expected argument type ARGP: %s (%2.2X)\n", 860 acpi_ut_get_argument_type_name(arg_type), arg_type)); 861 862 switch (arg_type) { 863 case ARGP_BYTEDATA: 864 case ARGP_WORDDATA: 865 case ARGP_DWORDDATA: 866 case ARGP_CHARLIST: 867 case ARGP_NAME: 868 case ARGP_NAMESTRING: 869 870 /* Constants, strings, and namestrings are all the same size */ 871 872 arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml); 873 if (!arg) { 874 return_ACPI_STATUS(AE_NO_MEMORY); 875 } 876 877 acpi_ps_get_next_simple_arg(parser_state, arg_type, arg); 878 break; 879 880 case ARGP_PKGLENGTH: 881 882 /* Package length, nothing returned */ 883 884 parser_state->pkg_end = 885 acpi_ps_get_next_package_end(parser_state); 886 if ((parser_state->pkg_end > parser_state->aml_end) 887 || (parser_state->pkg_end < parser_state->aml)) { 888 return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT); 889 } 890 break; 891 892 case ARGP_FIELDLIST: 893 894 if (parser_state->aml < parser_state->pkg_end) { 895 896 /* Non-empty list */ 897 898 while (parser_state->aml < parser_state->pkg_end) { 899 field = acpi_ps_get_next_field(parser_state); 900 if (!field) { 901 if (arg) { 902 acpi_ps_free_field_list(arg); 903 } 904 905 return_ACPI_STATUS(AE_NO_MEMORY); 906 } 907 908 if (prev) { 909 prev->common.next = field; 910 } else { 911 arg = field; 912 } 913 prev = field; 914 } 915 916 /* Skip to End of byte data */ 917 918 parser_state->aml = parser_state->pkg_end; 919 } 920 break; 921 922 case ARGP_BYTELIST: 923 924 if (parser_state->aml < parser_state->pkg_end) { 925 926 /* Non-empty list */ 927 928 arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP, 929 parser_state->aml); 930 if (!arg) { 931 return_ACPI_STATUS(AE_NO_MEMORY); 932 } 933 934 /* Fill in bytelist data */ 935 936 arg->common.value.size = (u32) 937 ACPI_PTR_DIFF(parser_state->pkg_end, 938 parser_state->aml); 939 arg->named.data = parser_state->aml; 940 941 /* Skip to End of byte data */ 942 943 parser_state->aml = parser_state->pkg_end; 944 } 945 break; 946 947 case ARGP_SIMPLENAME: 948 case ARGP_NAME_OR_REF: 949 950 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 951 "**** SimpleName/NameOrRef: %s (%2.2X)\n", 952 acpi_ut_get_argument_type_name(arg_type), 953 arg_type)); 954 955 subop = acpi_ps_peek_opcode(parser_state); 956 if (subop == 0 || 957 acpi_ps_is_leading_char(subop) || 958 ACPI_IS_ROOT_PREFIX(subop) || 959 ACPI_IS_PARENT_PREFIX(subop)) { 960 961 /* null_name or name_string */ 962 963 arg = 964 acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, 965 parser_state->aml); 966 if (!arg) { 967 return_ACPI_STATUS(AE_NO_MEMORY); 968 } 969 970 status = 971 acpi_ps_get_next_namepath(walk_state, parser_state, 972 arg, 973 ACPI_NOT_METHOD_CALL); 974 if (ACPI_FAILURE(status)) { 975 acpi_ps_free_op(arg); 976 return_ACPI_STATUS(status); 977 } 978 } else { 979 /* Single complex argument, nothing returned */ 980 981 walk_state->arg_count = 1; 982 } 983 break; 984 985 case ARGP_TARGET: 986 case ARGP_SUPERNAME: 987 988 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 989 "**** Target/Supername: %s (%2.2X)\n", 990 acpi_ut_get_argument_type_name(arg_type), 991 arg_type)); 992 993 subop = acpi_ps_peek_opcode(parser_state); 994 if (subop == 0 || 995 acpi_ps_is_leading_char(subop) || 996 ACPI_IS_ROOT_PREFIX(subop) || 997 ACPI_IS_PARENT_PREFIX(subop)) { 998 999 /* NULL target (zero). Convert to a NULL namepath */ 1000 1001 arg = 1002 acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, 1003 parser_state->aml); 1004 if (!arg) { 1005 return_ACPI_STATUS(AE_NO_MEMORY); 1006 } 1007 1008 status = 1009 acpi_ps_get_next_namepath(walk_state, parser_state, 1010 arg, 1011 ACPI_POSSIBLE_METHOD_CALL); 1012 if (ACPI_FAILURE(status)) { 1013 acpi_ps_free_op(arg); 1014 return_ACPI_STATUS(status); 1015 } 1016 1017 if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) { 1018 1019 /* Free method call op and corresponding namestring sub-ob */ 1020 1021 acpi_ps_free_op(arg->common.value.arg); 1022 acpi_ps_free_op(arg); 1023 arg = NULL; 1024 walk_state->arg_count = 1; 1025 } 1026 } else { 1027 /* Single complex argument, nothing returned */ 1028 1029 walk_state->arg_count = 1; 1030 } 1031 break; 1032 1033 case ARGP_DATAOBJ: 1034 case ARGP_TERMARG: 1035 1036 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 1037 "**** TermArg/DataObj: %s (%2.2X)\n", 1038 acpi_ut_get_argument_type_name(arg_type), 1039 arg_type)); 1040 1041 /* Single complex argument, nothing returned */ 1042 1043 walk_state->arg_count = 1; 1044 break; 1045 1046 case ARGP_DATAOBJLIST: 1047 case ARGP_TERMLIST: 1048 case ARGP_OBJLIST: 1049 1050 if (parser_state->aml < parser_state->pkg_end) { 1051 1052 /* Non-empty list of variable arguments, nothing returned */ 1053 1054 walk_state->arg_count = ACPI_VAR_ARGS; 1055 } 1056 break; 1057 1058 default: 1059 1060 ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type)); 1061 status = AE_AML_OPERAND_TYPE; 1062 break; 1063 } 1064 1065 *return_arg = arg; 1066 return_ACPI_STATUS(status); 1067 } 1068