1 /****************************************************************************** 2 * 3 * Module Name: psobject - Support for parse objects 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acparser.h> 47 #include <contrib/dev/acpica/include/amlcode.h> 48 49 #define _COMPONENT ACPI_PARSER 50 ACPI_MODULE_NAME ("psobject") 51 52 53 /* Local prototypes */ 54 55 static ACPI_STATUS 56 AcpiPsGetAmlOpcode ( 57 ACPI_WALK_STATE *WalkState); 58 59 60 /******************************************************************************* 61 * 62 * FUNCTION: AcpiPsGetAmlOpcode 63 * 64 * PARAMETERS: WalkState - Current state 65 * 66 * RETURN: Status 67 * 68 * DESCRIPTION: Extract the next AML opcode from the input stream. 69 * 70 ******************************************************************************/ 71 72 static ACPI_STATUS 73 AcpiPsGetAmlOpcode ( 74 ACPI_WALK_STATE *WalkState) 75 { 76 UINT32 AmlOffset; 77 78 79 ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState); 80 81 82 WalkState->Aml = WalkState->ParserState.Aml; 83 WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState)); 84 85 /* 86 * First cut to determine what we have found: 87 * 1) A valid AML opcode 88 * 2) A name string 89 * 3) An unknown/invalid opcode 90 */ 91 WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 92 93 switch (WalkState->OpInfo->Class) 94 { 95 case AML_CLASS_ASCII: 96 case AML_CLASS_PREFIX: 97 /* 98 * Starts with a valid prefix or ASCII char, this is a name 99 * string. Convert the bare name string to a namepath. 100 */ 101 WalkState->Opcode = AML_INT_NAMEPATH_OP; 102 WalkState->ArgTypes = ARGP_NAMESTRING; 103 break; 104 105 case AML_CLASS_UNKNOWN: 106 107 /* The opcode is unrecognized. Complain and skip unknown opcodes */ 108 109 if (WalkState->PassNumber == 2) 110 { 111 AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml, 112 WalkState->ParserState.AmlStart); 113 114 ACPI_ERROR ((AE_INFO, 115 "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring", 116 WalkState->Opcode, 117 (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER)))); 118 119 ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48); 120 121 #ifdef ACPI_ASL_COMPILER 122 /* 123 * This is executed for the disassembler only. Output goes 124 * to the disassembled ASL output file. 125 */ 126 AcpiOsPrintf ( 127 "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n", 128 WalkState->Opcode, 129 (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER))); 130 131 /* Dump the context surrounding the invalid opcode */ 132 133 AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16), 134 48, DB_BYTE_DISPLAY, 135 (AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16)); 136 AcpiOsPrintf (" */\n"); 137 #endif 138 } 139 140 /* Increment past one-byte or two-byte opcode */ 141 142 WalkState->ParserState.Aml++; 143 if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */ 144 { 145 WalkState->ParserState.Aml++; 146 } 147 148 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 149 150 default: 151 152 /* Found opcode info, this is a normal opcode */ 153 154 WalkState->ParserState.Aml += 155 AcpiPsGetOpcodeSize (WalkState->Opcode); 156 WalkState->ArgTypes = WalkState->OpInfo->ParseArgs; 157 break; 158 } 159 160 return_ACPI_STATUS (AE_OK); 161 } 162 163 164 /******************************************************************************* 165 * 166 * FUNCTION: AcpiPsBuildNamedOp 167 * 168 * PARAMETERS: WalkState - Current state 169 * AmlOpStart - Begin of named Op in AML 170 * UnnamedOp - Early Op (not a named Op) 171 * Op - Returned Op 172 * 173 * RETURN: Status 174 * 175 * DESCRIPTION: Parse a named Op 176 * 177 ******************************************************************************/ 178 179 ACPI_STATUS 180 AcpiPsBuildNamedOp ( 181 ACPI_WALK_STATE *WalkState, 182 UINT8 *AmlOpStart, 183 ACPI_PARSE_OBJECT *UnnamedOp, 184 ACPI_PARSE_OBJECT **Op) 185 { 186 ACPI_STATUS Status = AE_OK; 187 ACPI_PARSE_OBJECT *Arg = NULL; 188 189 190 ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState); 191 192 193 UnnamedOp->Common.Value.Arg = NULL; 194 UnnamedOp->Common.ArgListLength = 0; 195 UnnamedOp->Common.AmlOpcode = WalkState->Opcode; 196 197 /* 198 * Get and append arguments until we find the node that contains 199 * the name (the type ARGP_NAME). 200 */ 201 while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && 202 (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME)) 203 { 204 Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState), 205 GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); 206 if (ACPI_FAILURE (Status)) 207 { 208 return_ACPI_STATUS (Status); 209 } 210 211 AcpiPsAppendArg (UnnamedOp, Arg); 212 INCREMENT_ARG_LIST (WalkState->ArgTypes); 213 } 214 215 /* 216 * Make sure that we found a NAME and didn't run out of arguments 217 */ 218 if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes)) 219 { 220 return_ACPI_STATUS (AE_AML_NO_OPERAND); 221 } 222 223 /* We know that this arg is a name, move to next arg */ 224 225 INCREMENT_ARG_LIST (WalkState->ArgTypes); 226 227 /* 228 * Find the object. This will either insert the object into 229 * the namespace or simply look it up 230 */ 231 WalkState->Op = NULL; 232 233 Status = WalkState->DescendingCallback (WalkState, Op); 234 if (ACPI_FAILURE (Status)) 235 { 236 if (Status != AE_CTRL_TERMINATE) 237 { 238 ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog")); 239 } 240 return_ACPI_STATUS (Status); 241 } 242 243 if (!*Op) 244 { 245 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 246 } 247 248 Status = AcpiPsNextParseState (WalkState, *Op, Status); 249 if (ACPI_FAILURE (Status)) 250 { 251 if (Status == AE_CTRL_PENDING) 252 { 253 Status = AE_CTRL_PARSE_PENDING; 254 } 255 return_ACPI_STATUS (Status); 256 } 257 258 AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg); 259 260 if ((*Op)->Common.AmlOpcode == AML_REGION_OP || 261 (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP) 262 { 263 /* 264 * Defer final parsing of an OperationRegion body, because we don't 265 * have enough info in the first pass to parse it correctly (i.e., 266 * there may be method calls within the TermArg elements of the body.) 267 * 268 * However, we must continue parsing because the opregion is not a 269 * standalone package -- we don't know where the end is at this point. 270 * 271 * (Length is unknown until parse of the body complete) 272 */ 273 (*Op)->Named.Data = AmlOpStart; 274 (*Op)->Named.Length = 0; 275 } 276 277 return_ACPI_STATUS (AE_OK); 278 } 279 280 281 /******************************************************************************* 282 * 283 * FUNCTION: AcpiPsCreateOp 284 * 285 * PARAMETERS: WalkState - Current state 286 * AmlOpStart - Op start in AML 287 * NewOp - Returned Op 288 * 289 * RETURN: Status 290 * 291 * DESCRIPTION: Get Op from AML 292 * 293 ******************************************************************************/ 294 295 ACPI_STATUS 296 AcpiPsCreateOp ( 297 ACPI_WALK_STATE *WalkState, 298 UINT8 *AmlOpStart, 299 ACPI_PARSE_OBJECT **NewOp) 300 { 301 ACPI_STATUS Status = AE_OK; 302 ACPI_PARSE_OBJECT *Op; 303 ACPI_PARSE_OBJECT *NamedOp = NULL; 304 ACPI_PARSE_OBJECT *ParentScope; 305 UINT8 ArgumentCount; 306 const ACPI_OPCODE_INFO *OpInfo; 307 308 309 ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState); 310 311 312 Status = AcpiPsGetAmlOpcode (WalkState); 313 if (Status == AE_CTRL_PARSE_CONTINUE) 314 { 315 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 316 } 317 318 /* Create Op structure and append to parent's argument list */ 319 320 WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 321 Op = AcpiPsAllocOp (WalkState->Opcode, AmlOpStart); 322 if (!Op) 323 { 324 return_ACPI_STATUS (AE_NO_MEMORY); 325 } 326 327 if (WalkState->OpInfo->Flags & AML_NAMED) 328 { 329 Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp); 330 AcpiPsFreeOp (Op); 331 if (ACPI_FAILURE (Status)) 332 { 333 return_ACPI_STATUS (Status); 334 } 335 336 *NewOp = NamedOp; 337 return_ACPI_STATUS (AE_OK); 338 } 339 340 /* Not a named opcode, just allocate Op and append to parent */ 341 342 if (WalkState->OpInfo->Flags & AML_CREATE) 343 { 344 /* 345 * Backup to beginning of CreateXXXfield declaration 346 * BodyLength is unknown until we parse the body 347 */ 348 Op->Named.Data = AmlOpStart; 349 Op->Named.Length = 0; 350 } 351 352 if (WalkState->Opcode == AML_BANK_FIELD_OP) 353 { 354 /* 355 * Backup to beginning of BankField declaration 356 * BodyLength is unknown until we parse the body 357 */ 358 Op->Named.Data = AmlOpStart; 359 Op->Named.Length = 0; 360 } 361 362 ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState)); 363 AcpiPsAppendArg (ParentScope, Op); 364 365 if (ParentScope) 366 { 367 OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode); 368 if (OpInfo->Flags & AML_HAS_TARGET) 369 { 370 ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type); 371 if (ParentScope->Common.ArgListLength > ArgumentCount) 372 { 373 Op->Common.Flags |= ACPI_PARSEOP_TARGET; 374 } 375 } 376 377 /* 378 * Special case for both Increment() and Decrement(), where 379 * the lone argument is both a source and a target. 380 */ 381 else if ((ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) || 382 (ParentScope->Common.AmlOpcode == AML_DECREMENT_OP)) 383 { 384 Op->Common.Flags |= ACPI_PARSEOP_TARGET; 385 } 386 } 387 388 if (WalkState->DescendingCallback != NULL) 389 { 390 /* 391 * Find the object. This will either insert the object into 392 * the namespace or simply look it up 393 */ 394 WalkState->Op = *NewOp = Op; 395 396 Status = WalkState->DescendingCallback (WalkState, &Op); 397 Status = AcpiPsNextParseState (WalkState, Op, Status); 398 if (Status == AE_CTRL_PENDING) 399 { 400 Status = AE_CTRL_PARSE_PENDING; 401 } 402 } 403 404 return_ACPI_STATUS (Status); 405 } 406 407 408 /******************************************************************************* 409 * 410 * FUNCTION: AcpiPsCompleteOp 411 * 412 * PARAMETERS: WalkState - Current state 413 * Op - Returned Op 414 * Status - Parse status before complete Op 415 * 416 * RETURN: Status 417 * 418 * DESCRIPTION: Complete Op 419 * 420 ******************************************************************************/ 421 422 ACPI_STATUS 423 AcpiPsCompleteOp ( 424 ACPI_WALK_STATE *WalkState, 425 ACPI_PARSE_OBJECT **Op, 426 ACPI_STATUS Status) 427 { 428 ACPI_STATUS Status2; 429 430 431 ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState); 432 433 434 /* 435 * Finished one argument of the containing scope 436 */ 437 WalkState->ParserState.Scope->ParseScope.ArgCount--; 438 439 /* Close this Op (will result in parse subtree deletion) */ 440 441 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 442 if (ACPI_FAILURE (Status2)) 443 { 444 return_ACPI_STATUS (Status2); 445 } 446 447 *Op = NULL; 448 449 switch (Status) 450 { 451 case AE_OK: 452 453 break; 454 455 case AE_CTRL_TRANSFER: 456 457 /* We are about to transfer to a called method */ 458 459 WalkState->PrevOp = NULL; 460 WalkState->PrevArgTypes = WalkState->ArgTypes; 461 return_ACPI_STATUS (Status); 462 463 case AE_CTRL_END: 464 465 AcpiPsPopScope (&(WalkState->ParserState), Op, 466 &WalkState->ArgTypes, &WalkState->ArgCount); 467 468 if (*Op) 469 { 470 WalkState->Op = *Op; 471 WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 472 WalkState->Opcode = (*Op)->Common.AmlOpcode; 473 474 Status = WalkState->AscendingCallback (WalkState); 475 Status = AcpiPsNextParseState (WalkState, *Op, Status); 476 477 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 478 if (ACPI_FAILURE (Status2)) 479 { 480 return_ACPI_STATUS (Status2); 481 } 482 } 483 484 Status = AE_OK; 485 break; 486 487 case AE_CTRL_BREAK: 488 case AE_CTRL_CONTINUE: 489 490 /* Pop off scopes until we find the While */ 491 492 while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP)) 493 { 494 AcpiPsPopScope (&(WalkState->ParserState), Op, 495 &WalkState->ArgTypes, &WalkState->ArgCount); 496 } 497 498 /* Close this iteration of the While loop */ 499 500 WalkState->Op = *Op; 501 WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 502 WalkState->Opcode = (*Op)->Common.AmlOpcode; 503 504 Status = WalkState->AscendingCallback (WalkState); 505 Status = AcpiPsNextParseState (WalkState, *Op, Status); 506 507 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 508 if (ACPI_FAILURE (Status2)) 509 { 510 return_ACPI_STATUS (Status2); 511 } 512 513 Status = AE_OK; 514 break; 515 516 case AE_CTRL_TERMINATE: 517 518 /* Clean up */ 519 do 520 { 521 if (*Op) 522 { 523 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 524 if (ACPI_FAILURE (Status2)) 525 { 526 return_ACPI_STATUS (Status2); 527 } 528 529 AcpiUtDeleteGenericState ( 530 AcpiUtPopGenericState (&WalkState->ControlState)); 531 } 532 533 AcpiPsPopScope (&(WalkState->ParserState), Op, 534 &WalkState->ArgTypes, &WalkState->ArgCount); 535 536 } while (*Op); 537 538 return_ACPI_STATUS (AE_OK); 539 540 default: /* All other non-AE_OK status */ 541 542 do 543 { 544 if (*Op) 545 { 546 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 547 if (ACPI_FAILURE (Status2)) 548 { 549 return_ACPI_STATUS (Status2); 550 } 551 } 552 553 AcpiPsPopScope (&(WalkState->ParserState), Op, 554 &WalkState->ArgTypes, &WalkState->ArgCount); 555 556 } while (*Op); 557 558 559 #if 0 560 /* 561 * TBD: Cleanup parse ops on error 562 */ 563 if (*Op == NULL) 564 { 565 AcpiPsPopScope (ParserState, Op, 566 &WalkState->ArgTypes, &WalkState->ArgCount); 567 } 568 #endif 569 WalkState->PrevOp = NULL; 570 WalkState->PrevArgTypes = WalkState->ArgTypes; 571 return_ACPI_STATUS (Status); 572 } 573 574 /* This scope complete? */ 575 576 if (AcpiPsHasCompletedScope (&(WalkState->ParserState))) 577 { 578 AcpiPsPopScope (&(WalkState->ParserState), Op, 579 &WalkState->ArgTypes, &WalkState->ArgCount); 580 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op)); 581 } 582 else 583 { 584 *Op = NULL; 585 } 586 587 return_ACPI_STATUS (AE_OK); 588 } 589 590 591 /******************************************************************************* 592 * 593 * FUNCTION: AcpiPsCompleteFinalOp 594 * 595 * PARAMETERS: WalkState - Current state 596 * Op - Current Op 597 * Status - Current parse status before complete last 598 * Op 599 * 600 * RETURN: Status 601 * 602 * DESCRIPTION: Complete last Op. 603 * 604 ******************************************************************************/ 605 606 ACPI_STATUS 607 AcpiPsCompleteFinalOp ( 608 ACPI_WALK_STATE *WalkState, 609 ACPI_PARSE_OBJECT *Op, 610 ACPI_STATUS Status) 611 { 612 ACPI_STATUS Status2; 613 614 615 ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState); 616 617 618 /* 619 * Complete the last Op (if not completed), and clear the scope stack. 620 * It is easily possible to end an AML "package" with an unbounded number 621 * of open scopes (such as when several ASL blocks are closed with 622 * sequential closing braces). We want to terminate each one cleanly. 623 */ 624 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op)); 625 do 626 { 627 if (Op) 628 { 629 if (WalkState->AscendingCallback != NULL) 630 { 631 WalkState->Op = Op; 632 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 633 WalkState->Opcode = Op->Common.AmlOpcode; 634 635 Status = WalkState->AscendingCallback (WalkState); 636 Status = AcpiPsNextParseState (WalkState, Op, Status); 637 if (Status == AE_CTRL_PENDING) 638 { 639 Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK); 640 if (ACPI_FAILURE (Status)) 641 { 642 return_ACPI_STATUS (Status); 643 } 644 } 645 646 if (Status == AE_CTRL_TERMINATE) 647 { 648 Status = AE_OK; 649 650 /* Clean up */ 651 do 652 { 653 if (Op) 654 { 655 Status2 = AcpiPsCompleteThisOp (WalkState, Op); 656 if (ACPI_FAILURE (Status2)) 657 { 658 return_ACPI_STATUS (Status2); 659 } 660 } 661 662 AcpiPsPopScope (&(WalkState->ParserState), &Op, 663 &WalkState->ArgTypes, &WalkState->ArgCount); 664 665 } while (Op); 666 667 return_ACPI_STATUS (Status); 668 } 669 670 else if (ACPI_FAILURE (Status)) 671 { 672 /* First error is most important */ 673 674 (void) AcpiPsCompleteThisOp (WalkState, Op); 675 return_ACPI_STATUS (Status); 676 } 677 } 678 679 Status2 = AcpiPsCompleteThisOp (WalkState, Op); 680 if (ACPI_FAILURE (Status2)) 681 { 682 return_ACPI_STATUS (Status2); 683 } 684 } 685 686 AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes, 687 &WalkState->ArgCount); 688 689 } while (Op); 690 691 return_ACPI_STATUS (Status); 692 } 693