root/drivers/acpi/acpica/psargs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ps_get_next_package_end
  3. acpi_ps_get_next_namestring
  4. acpi_ps_get_next_namepath
  5. acpi_ps_get_next_simple_arg
  6. acpi_ps_get_next_field
  7. acpi_ps_get_next_arg

   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 - 2019, 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 /*******************************************************************************
  29  *
  30  * FUNCTION:    acpi_ps_get_next_package_length
  31  *
  32  * PARAMETERS:  parser_state        - Current parser state object
  33  *
  34  * RETURN:      Decoded package length. On completion, the AML pointer points
  35  *              past the length byte or bytes.
  36  *
  37  * DESCRIPTION: Decode and return a package length field.
  38  *              Note: Largest package length is 28 bits, from ACPI specification
  39  *
  40  ******************************************************************************/
  41 
  42 static u32
  43 acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
  44 {
  45         u8 *aml = parser_state->aml;
  46         u32 package_length = 0;
  47         u32 byte_count;
  48         u8 byte_zero_mask = 0x3F;       /* Default [0:5] */
  49 
  50         ACPI_FUNCTION_TRACE(ps_get_next_package_length);
  51 
  52         /*
  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
  55          */
  56         byte_count = (aml[0] >> 6);
  57         parser_state->aml += ((acpi_size)byte_count + 1);
  58 
  59         /* Get bytes 3, 2, 1 as needed */
  60 
  61         while (byte_count) {
  62                 /*
  63                  * Final bit positions for the package length bytes:
  64                  *      Byte3->[20:27]
  65                  *      Byte2->[12:19]
  66                  *      Byte1->[04:11]
  67                  *      Byte0->[00:03]
  68                  */
  69                 package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
  70 
  71                 byte_zero_mask = 0x0F;  /* Use bits [0:3] of byte 0 */
  72                 byte_count--;
  73         }
  74 
  75         /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
  76 
  77         package_length |= (aml[0] & byte_zero_mask);
  78         return_UINT32(package_length);
  79 }
  80 
  81 /*******************************************************************************
  82  *
  83  * FUNCTION:    acpi_ps_get_next_package_end
  84  *
  85  * PARAMETERS:  parser_state        - Current parser state object
  86  *
  87  * RETURN:      Pointer to end-of-package +1
  88  *
  89  * DESCRIPTION: Get next package length and return a pointer past the end of
  90  *              the package. Consumes the package length field
  91  *
  92  ******************************************************************************/
  93 
  94 u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
  95 {
  96         u8 *start = parser_state->aml;
  97         u32 package_length;
  98 
  99         ACPI_FUNCTION_TRACE(ps_get_next_package_end);
 100 
 101         /* Function below updates parser_state->Aml */
 102 
 103         package_length = acpi_ps_get_next_package_length(parser_state);
 104 
 105         return_PTR(start + package_length);     /* end of package */
 106 }
 107 
 108 /*******************************************************************************
 109  *
 110  * FUNCTION:    acpi_ps_get_next_namestring
 111  *
 112  * PARAMETERS:  parser_state        - Current parser state object
 113  *
 114  * RETURN:      Pointer to the start of the name string (pointer points into
 115  *              the AML.
 116  *
 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.)
 120  *
 121  ******************************************************************************/
 122 
 123 char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
 124 {
 125         u8 *start = parser_state->aml;
 126         u8 *end = parser_state->aml;
 127 
 128         ACPI_FUNCTION_TRACE(ps_get_next_namestring);
 129 
 130         /* Point past any namestring prefix characters (backslash or carat) */
 131 
 132         while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) {
 133                 end++;
 134         }
 135 
 136         /* Decode the path prefix character */
 137 
 138         switch (*end) {
 139         case 0:
 140 
 141                 /* null_name */
 142 
 143                 if (end == start) {
 144                         start = NULL;
 145                 }
 146                 end++;
 147                 break;
 148 
 149         case AML_DUAL_NAME_PREFIX:
 150 
 151                 /* Two name segments */
 152 
 153                 end += 1 + (2 * ACPI_NAMESEG_SIZE);
 154                 break;
 155 
 156         case AML_MULTI_NAME_PREFIX:
 157 
 158                 /* Multiple name segments, 4 chars each, count in next byte */
 159 
 160                 end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE);
 161                 break;
 162 
 163         default:
 164 
 165                 /* Single name segment */
 166 
 167                 end += ACPI_NAMESEG_SIZE;
 168                 break;
 169         }
 170 
 171         parser_state->aml = end;
 172         return_PTR((char *)start);
 173 }
 174 
 175 /*******************************************************************************
 176  *
 177  * FUNCTION:    acpi_ps_get_next_namepath
 178  *
 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
 185  *
 186  * RETURN:      Status
 187  *
 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.
 193  *
 194  ******************************************************************************/
 195 
 196 acpi_status
 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)
 200 {
 201         acpi_status status;
 202         char *path;
 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;
 207 
 208         ACPI_FUNCTION_TRACE(ps_get_next_namepath);
 209 
 210         path = acpi_ps_get_next_namestring(parser_state);
 211         acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
 212 
 213         /* Null path case is allowed, just exit */
 214 
 215         if (!path) {
 216                 arg->common.value.name = path;
 217                 return_ACPI_STATUS(AE_OK);
 218         }
 219 
 220         /*
 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
 226          * the upsearch)
 227          */
 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,
 231                                 NULL, &node);
 232 
 233         /*
 234          * If this name is a control method invocation, we must
 235          * setup the method call
 236          */
 237         if (ACPI_SUCCESS(status) &&
 238             possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
 239                 if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
 240                      ARGP_SUPERNAME)
 241                     || (GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
 242                         ARGP_TARGET)) {
 243                         /*
 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
 247                          * namestring.
 248                          */
 249                         walk_state->parser_state.aml = start;
 250                         walk_state->arg_count = 1;
 251                         acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
 252                 }
 253 
 254                 /* This name is actually a control method invocation */
 255 
 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));
 260 
 261                 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start);
 262                 if (!name_op) {
 263                         return_ACPI_STATUS(AE_NO_MEMORY);
 264                 }
 265 
 266                 /* Change Arg into a METHOD CALL and attach name to it */
 267 
 268                 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
 269                 name_op->common.value.name = path;
 270 
 271                 /* Point METHODCALL/NAME to the METHOD Node */
 272 
 273                 name_op->common.node = node;
 274                 acpi_ps_append_arg(arg, name_op);
 275 
 276                 if (!method_desc) {
 277                         ACPI_ERROR((AE_INFO,
 278                                     "Control Method %p has no attached object",
 279                                     node));
 280                         return_ACPI_STATUS(AE_AML_INTERNAL);
 281                 }
 282 
 283                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 284                                   "Control Method - %p Args %X\n",
 285                                   node, method_desc->method.param_count));
 286 
 287                 /* Get the number of arguments to expect */
 288 
 289                 walk_state->arg_count = method_desc->method.param_count;
 290                 return_ACPI_STATUS(AE_OK);
 291         }
 292 
 293         /*
 294          * Special handling if the name was not found during the lookup -
 295          * some not_found cases are allowed
 296          */
 297         if (status == AE_NOT_FOUND) {
 298 
 299                 /* 1) not_found is ok during load pass 1/2 (allow forward references) */
 300 
 301                 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
 302                     ACPI_PARSE_EXECUTE) {
 303                         status = AE_OK;
 304                 }
 305 
 306                 /* 2) not_found during a cond_ref_of(x) is ok by definition */
 307 
 308                 else if (walk_state->op->common.aml_opcode ==
 309                          AML_CONDITIONAL_REF_OF_OP) {
 310                         status = AE_OK;
 311                 }
 312 
 313                 /*
 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)
 317                  */
 318                 else if ((arg->common.parent) &&
 319                          ((arg->common.parent->common.aml_opcode ==
 320                            AML_PACKAGE_OP)
 321                           || (arg->common.parent->common.aml_opcode ==
 322                               AML_VARIABLE_PACKAGE_OP))) {
 323                         status = AE_OK;
 324                 }
 325         }
 326 
 327         /* Final exception check (may have been changed from code above) */
 328 
 329         if (ACPI_FAILURE(status)) {
 330                 ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status);
 331 
 332                 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
 333                     ACPI_PARSE_EXECUTE) {
 334 
 335                         /* Report a control method execution error */
 336 
 337                         status = acpi_ds_method_error(status, walk_state);
 338                 }
 339         }
 340 
 341         /* Save the namepath */
 342 
 343         arg->common.value.name = path;
 344         return_ACPI_STATUS(status);
 345 }
 346 
 347 /*******************************************************************************
 348  *
 349  * FUNCTION:    acpi_ps_get_next_simple_arg
 350  *
 351  * PARAMETERS:  parser_state        - Current parser state object
 352  *              arg_type            - The argument type (AML_*_ARG)
 353  *              arg                 - Where the argument is returned
 354  *
 355  * RETURN:      None
 356  *
 357  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
 358  *
 359  ******************************************************************************/
 360 
 361 void
 362 acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
 363                             u32 arg_type, union acpi_parse_object *arg)
 364 {
 365         u32 length;
 366         u16 opcode;
 367         u8 *aml = parser_state->aml;
 368 
 369         ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
 370 
 371         switch (arg_type) {
 372         case ARGP_BYTEDATA:
 373 
 374                 /* Get 1 byte from the AML stream */
 375 
 376                 opcode = AML_BYTE_OP;
 377                 arg->common.value.integer = (u64) *aml;
 378                 length = 1;
 379                 break;
 380 
 381         case ARGP_WORDDATA:
 382 
 383                 /* Get 2 bytes from the AML stream */
 384 
 385                 opcode = AML_WORD_OP;
 386                 ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
 387                 length = 2;
 388                 break;
 389 
 390         case ARGP_DWORDDATA:
 391 
 392                 /* Get 4 bytes from the AML stream */
 393 
 394                 opcode = AML_DWORD_OP;
 395                 ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
 396                 length = 4;
 397                 break;
 398 
 399         case ARGP_QWORDDATA:
 400 
 401                 /* Get 8 bytes from the AML stream */
 402 
 403                 opcode = AML_QWORD_OP;
 404                 ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
 405                 length = 8;
 406                 break;
 407 
 408         case ARGP_CHARLIST:
 409 
 410                 /* Get a pointer to the string, point past the string */
 411 
 412                 opcode = AML_STRING_OP;
 413                 arg->common.value.string = ACPI_CAST_PTR(char, aml);
 414 
 415                 /* Find the null terminator */
 416 
 417                 length = 0;
 418                 while (aml[length]) {
 419                         length++;
 420                 }
 421                 length++;
 422                 break;
 423 
 424         case ARGP_NAME:
 425         case ARGP_NAMESTRING:
 426 
 427                 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
 428                 arg->common.value.name =
 429                     acpi_ps_get_next_namestring(parser_state);
 430                 return_VOID;
 431 
 432         default:
 433 
 434                 ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type));
 435                 return_VOID;
 436         }
 437 
 438         acpi_ps_init_op(arg, opcode);
 439         parser_state->aml += length;
 440         return_VOID;
 441 }
 442 
 443 /*******************************************************************************
 444  *
 445  * FUNCTION:    acpi_ps_get_next_field
 446  *
 447  * PARAMETERS:  parser_state        - Current parser state object
 448  *
 449  * RETURN:      A newly allocated FIELD op
 450  *
 451  * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
 452  *
 453  ******************************************************************************/
 454 
 455 static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
 456                                                        *parser_state)
 457 {
 458         u8 *aml;
 459         union acpi_parse_object *field;
 460         union acpi_parse_object *arg = NULL;
 461         u16 opcode;
 462         u32 name;
 463         u8 access_type;
 464         u8 access_attribute;
 465         u8 access_length;
 466         u32 pkg_length;
 467         u8 *pkg_end;
 468         u32 buffer_length;
 469 
 470         ACPI_FUNCTION_TRACE(ps_get_next_field);
 471 
 472         ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 473         aml = parser_state->aml;
 474 
 475         /* Determine field type */
 476 
 477         switch (ACPI_GET8(parser_state->aml)) {
 478         case AML_FIELD_OFFSET_OP:
 479 
 480                 opcode = AML_INT_RESERVEDFIELD_OP;
 481                 parser_state->aml++;
 482                 break;
 483 
 484         case AML_FIELD_ACCESS_OP:
 485 
 486                 opcode = AML_INT_ACCESSFIELD_OP;
 487                 parser_state->aml++;
 488                 break;
 489 
 490         case AML_FIELD_CONNECTION_OP:
 491 
 492                 opcode = AML_INT_CONNECTION_OP;
 493                 parser_state->aml++;
 494                 break;
 495 
 496         case AML_FIELD_EXT_ACCESS_OP:
 497 
 498                 opcode = AML_INT_EXTACCESSFIELD_OP;
 499                 parser_state->aml++;
 500                 break;
 501 
 502         default:
 503 
 504                 opcode = AML_INT_NAMEDFIELD_OP;
 505                 break;
 506         }
 507 
 508         /* Allocate a new field op */
 509 
 510         field = acpi_ps_alloc_op(opcode, aml);
 511         if (!field) {
 512                 return_PTR(NULL);
 513         }
 514 
 515         /* Decode the field type */
 516 
 517         ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 518         switch (opcode) {
 519         case AML_INT_NAMEDFIELD_OP:
 520 
 521                 /* Get the 4-character name */
 522 
 523                 ACPI_MOVE_32_TO_32(&name, parser_state->aml);
 524                 acpi_ps_set_name(field, name);
 525                 parser_state->aml += ACPI_NAMESEG_SIZE;
 526 
 527                 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 528 
 529 #ifdef ACPI_ASL_COMPILER
 530                 /*
 531                  * Because the package length isn't represented as a parse tree object,
 532                  * take comments surrounding this and add to the previously created
 533                  * parse node.
 534                  */
 535                 if (field->common.inline_comment) {
 536                         field->common.name_comment =
 537                             field->common.inline_comment;
 538                 }
 539                 field->common.inline_comment = acpi_gbl_current_inline_comment;
 540                 acpi_gbl_current_inline_comment = NULL;
 541 #endif
 542 
 543                 /* Get the length which is encoded as a package length */
 544 
 545                 field->common.value.size =
 546                     acpi_ps_get_next_package_length(parser_state);
 547                 break;
 548 
 549         case AML_INT_RESERVEDFIELD_OP:
 550 
 551                 /* Get the length which is encoded as a package length */
 552 
 553                 field->common.value.size =
 554                     acpi_ps_get_next_package_length(parser_state);
 555                 break;
 556 
 557         case AML_INT_ACCESSFIELD_OP:
 558         case AML_INT_EXTACCESSFIELD_OP:
 559 
 560                 /*
 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.
 564                  */
 565 
 566                 /* Get the two bytes (Type/Attribute) */
 567 
 568                 access_type = ACPI_GET8(parser_state->aml);
 569                 parser_state->aml++;
 570                 access_attribute = ACPI_GET8(parser_state->aml);
 571                 parser_state->aml++;
 572 
 573                 field->common.value.integer = (u8)access_type;
 574                 field->common.value.integer |= (u16)(access_attribute << 8);
 575 
 576                 /* This opcode has a third byte, access_length */
 577 
 578                 if (opcode == AML_INT_EXTACCESSFIELD_OP) {
 579                         access_length = ACPI_GET8(parser_state->aml);
 580                         parser_state->aml++;
 581 
 582                         field->common.value.integer |=
 583                             (u32)(access_length << 16);
 584                 }
 585                 break;
 586 
 587         case AML_INT_CONNECTION_OP:
 588 
 589                 /*
 590                  * Argument for Connection operator can be either a Buffer
 591                  * (resource descriptor), or a name_string.
 592                  */
 593                 aml = parser_state->aml;
 594                 if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
 595                         parser_state->aml++;
 596 
 597                         ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 598                         pkg_end = parser_state->aml;
 599                         pkg_length =
 600                             acpi_ps_get_next_package_length(parser_state);
 601                         pkg_end += pkg_length;
 602 
 603                         ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 604                         if (parser_state->aml < pkg_end) {
 605 
 606                                 /* Non-empty list */
 607 
 608                                 arg =
 609                                     acpi_ps_alloc_op(AML_INT_BYTELIST_OP, aml);
 610                                 if (!arg) {
 611                                         acpi_ps_free_op(field);
 612                                         return_PTR(NULL);
 613                                 }
 614 
 615                                 /* Get the actual buffer length argument */
 616 
 617                                 opcode = ACPI_GET8(parser_state->aml);
 618                                 parser_state->aml++;
 619 
 620                                 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 621                                 switch (opcode) {
 622                                 case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
 623 
 624                                         buffer_length =
 625                                             ACPI_GET8(parser_state->aml);
 626                                         parser_state->aml += 1;
 627                                         break;
 628 
 629                                 case AML_WORD_OP:       /* AML_WORDDATA_ARG */
 630 
 631                                         buffer_length =
 632                                             ACPI_GET16(parser_state->aml);
 633                                         parser_state->aml += 2;
 634                                         break;
 635 
 636                                 case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
 637 
 638                                         buffer_length =
 639                                             ACPI_GET32(parser_state->aml);
 640                                         parser_state->aml += 4;
 641                                         break;
 642 
 643                                 default:
 644 
 645                                         buffer_length = 0;
 646                                         break;
 647                                 }
 648 
 649                                 /* Fill in bytelist data */
 650 
 651                                 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 652                                 arg->named.value.size = buffer_length;
 653                                 arg->named.data = parser_state->aml;
 654                         }
 655 
 656                         /* Skip to End of byte data */
 657 
 658                         parser_state->aml = pkg_end;
 659                 } else {
 660                         arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, aml);
 661                         if (!arg) {
 662                                 acpi_ps_free_op(field);
 663                                 return_PTR(NULL);
 664                         }
 665 
 666                         /* Get the Namestring argument */
 667 
 668                         arg->common.value.name =
 669                             acpi_ps_get_next_namestring(parser_state);
 670                 }
 671 
 672                 /* Link the buffer/namestring to parent (CONNECTION_OP) */
 673 
 674                 acpi_ps_append_arg(field, arg);
 675                 break;
 676 
 677         default:
 678 
 679                 /* Opcode was set in previous switch */
 680                 break;
 681         }
 682 
 683         return_PTR(field);
 684 }
 685 
 686 /*******************************************************************************
 687  *
 688  * FUNCTION:    acpi_ps_get_next_arg
 689  *
 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
 694  *
 695  * RETURN:      Status, and an op object containing the next argument.
 696  *
 697  * DESCRIPTION: Get next argument (including complex list arguments that require
 698  *              pushing the parser stack)
 699  *
 700  ******************************************************************************/
 701 
 702 acpi_status
 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)
 706 {
 707         union acpi_parse_object *arg = NULL;
 708         union acpi_parse_object *prev = NULL;
 709         union acpi_parse_object *field;
 710         u32 subop;
 711         acpi_status status = AE_OK;
 712 
 713         ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
 714 
 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));
 718 
 719         switch (arg_type) {
 720         case ARGP_BYTEDATA:
 721         case ARGP_WORDDATA:
 722         case ARGP_DWORDDATA:
 723         case ARGP_CHARLIST:
 724         case ARGP_NAME:
 725         case ARGP_NAMESTRING:
 726 
 727                 /* Constants, strings, and namestrings are all the same size */
 728 
 729                 arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml);
 730                 if (!arg) {
 731                         return_ACPI_STATUS(AE_NO_MEMORY);
 732                 }
 733 
 734                 acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
 735                 break;
 736 
 737         case ARGP_PKGLENGTH:
 738 
 739                 /* Package length, nothing returned */
 740 
 741                 parser_state->pkg_end =
 742                     acpi_ps_get_next_package_end(parser_state);
 743                 break;
 744 
 745         case ARGP_FIELDLIST:
 746 
 747                 if (parser_state->aml < parser_state->pkg_end) {
 748 
 749                         /* Non-empty list */
 750 
 751                         while (parser_state->aml < parser_state->pkg_end) {
 752                                 field = acpi_ps_get_next_field(parser_state);
 753                                 if (!field) {
 754                                         return_ACPI_STATUS(AE_NO_MEMORY);
 755                                 }
 756 
 757                                 if (prev) {
 758                                         prev->common.next = field;
 759                                 } else {
 760                                         arg = field;
 761                                 }
 762                                 prev = field;
 763                         }
 764 
 765                         /* Skip to End of byte data */
 766 
 767                         parser_state->aml = parser_state->pkg_end;
 768                 }
 769                 break;
 770 
 771         case ARGP_BYTELIST:
 772 
 773                 if (parser_state->aml < parser_state->pkg_end) {
 774 
 775                         /* Non-empty list */
 776 
 777                         arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP,
 778                                                parser_state->aml);
 779                         if (!arg) {
 780                                 return_ACPI_STATUS(AE_NO_MEMORY);
 781                         }
 782 
 783                         /* Fill in bytelist data */
 784 
 785                         arg->common.value.size = (u32)
 786                             ACPI_PTR_DIFF(parser_state->pkg_end,
 787                                           parser_state->aml);
 788                         arg->named.data = parser_state->aml;
 789 
 790                         /* Skip to End of byte data */
 791 
 792                         parser_state->aml = parser_state->pkg_end;
 793                 }
 794                 break;
 795 
 796         case ARGP_SIMPLENAME:
 797         case ARGP_NAME_OR_REF:
 798 
 799                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 800                                   "**** SimpleName/NameOrRef: %s (%2.2X)\n",
 801                                   acpi_ut_get_argument_type_name(arg_type),
 802                                   arg_type));
 803 
 804                 subop = acpi_ps_peek_opcode(parser_state);
 805                 if (subop == 0 ||
 806                     acpi_ps_is_leading_char(subop) ||
 807                     ACPI_IS_ROOT_PREFIX(subop) ||
 808                     ACPI_IS_PARENT_PREFIX(subop)) {
 809 
 810                         /* null_name or name_string */
 811 
 812                         arg =
 813                             acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
 814                                              parser_state->aml);
 815                         if (!arg) {
 816                                 return_ACPI_STATUS(AE_NO_MEMORY);
 817                         }
 818 
 819                         status =
 820                             acpi_ps_get_next_namepath(walk_state, parser_state,
 821                                                       arg,
 822                                                       ACPI_NOT_METHOD_CALL);
 823                 } else {
 824                         /* Single complex argument, nothing returned */
 825 
 826                         walk_state->arg_count = 1;
 827                 }
 828                 break;
 829 
 830         case ARGP_TARGET:
 831         case ARGP_SUPERNAME:
 832 
 833                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 834                                   "**** Target/Supername: %s (%2.2X)\n",
 835                                   acpi_ut_get_argument_type_name(arg_type),
 836                                   arg_type));
 837 
 838                 subop = acpi_ps_peek_opcode(parser_state);
 839                 if (subop == 0 ||
 840                     acpi_ps_is_leading_char(subop) ||
 841                     ACPI_IS_ROOT_PREFIX(subop) ||
 842                     ACPI_IS_PARENT_PREFIX(subop)) {
 843 
 844                         /* NULL target (zero). Convert to a NULL namepath */
 845 
 846                         arg =
 847                             acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
 848                                              parser_state->aml);
 849                         if (!arg) {
 850                                 return_ACPI_STATUS(AE_NO_MEMORY);
 851                         }
 852 
 853                         status =
 854                             acpi_ps_get_next_namepath(walk_state, parser_state,
 855                                                       arg,
 856                                                       ACPI_POSSIBLE_METHOD_CALL);
 857 
 858                         if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
 859 
 860                                 /* Free method call op and corresponding namestring sub-ob */
 861 
 862                                 acpi_ps_free_op(arg->common.value.arg);
 863                                 acpi_ps_free_op(arg);
 864                                 arg = NULL;
 865                                 walk_state->arg_count = 1;
 866                         }
 867                 } else {
 868                         /* Single complex argument, nothing returned */
 869 
 870                         walk_state->arg_count = 1;
 871                 }
 872                 break;
 873 
 874         case ARGP_DATAOBJ:
 875         case ARGP_TERMARG:
 876 
 877                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 878                                   "**** TermArg/DataObj: %s (%2.2X)\n",
 879                                   acpi_ut_get_argument_type_name(arg_type),
 880                                   arg_type));
 881 
 882                 /* Single complex argument, nothing returned */
 883 
 884                 walk_state->arg_count = 1;
 885                 break;
 886 
 887         case ARGP_DATAOBJLIST:
 888         case ARGP_TERMLIST:
 889         case ARGP_OBJLIST:
 890 
 891                 if (parser_state->aml < parser_state->pkg_end) {
 892 
 893                         /* Non-empty list of variable arguments, nothing returned */
 894 
 895                         walk_state->arg_count = ACPI_VAR_ARGS;
 896                 }
 897                 break;
 898 
 899         default:
 900 
 901                 ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type));
 902                 status = AE_AML_OPERAND_TYPE;
 903                 break;
 904         }
 905 
 906         *return_arg = arg;
 907         return_ACPI_STATUS(status);
 908 }

/* [<][>][^][v][top][bottom][index][help] */