nspredef.c revision 200553
1/****************************************************************************** 2 * 3 * Module Name: nspredef - Validation of ACPI predefined methods and objects 4 * 5 *****************************************************************************/ 6 7/****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116#define ACPI_CREATE_PREDEFINED_TABLE 117 118#include <contrib/dev/acpica/include/acpi.h> 119#include <contrib/dev/acpica/include/accommon.h> 120#include <contrib/dev/acpica/include/acnamesp.h> 121#include <contrib/dev/acpica/include/acpredef.h> 122 123 124#define _COMPONENT ACPI_NAMESPACE 125 ACPI_MODULE_NAME ("nspredef") 126 127 128/******************************************************************************* 129 * 130 * This module validates predefined ACPI objects that appear in the namespace, 131 * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this 132 * validation is to detect problems with BIOS-exposed predefined ACPI objects 133 * before the results are returned to the ACPI-related drivers. 134 * 135 * There are several areas that are validated: 136 * 137 * 1) The number of input arguments as defined by the method/object in the 138 * ASL is validated against the ACPI specification. 139 * 2) The type of the return object (if any) is validated against the ACPI 140 * specification. 141 * 3) For returned package objects, the count of package elements is 142 * validated, as well as the type of each package element. Nested 143 * packages are supported. 144 * 145 * For any problems found, a warning message is issued. 146 * 147 ******************************************************************************/ 148 149 150/* Local prototypes */ 151 152static ACPI_STATUS 153AcpiNsCheckPackage ( 154 ACPI_PREDEFINED_DATA *Data, 155 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 156 157static ACPI_STATUS 158AcpiNsCheckPackageList ( 159 ACPI_PREDEFINED_DATA *Data, 160 const ACPI_PREDEFINED_INFO *Package, 161 ACPI_OPERAND_OBJECT **Elements, 162 UINT32 Count); 163 164static ACPI_STATUS 165AcpiNsCheckPackageElements ( 166 ACPI_PREDEFINED_DATA *Data, 167 ACPI_OPERAND_OBJECT **Elements, 168 UINT8 Type1, 169 UINT32 Count1, 170 UINT8 Type2, 171 UINT32 Count2, 172 UINT32 StartIndex); 173 174static ACPI_STATUS 175AcpiNsCheckObjectType ( 176 ACPI_PREDEFINED_DATA *Data, 177 ACPI_OPERAND_OBJECT **ReturnObjectPtr, 178 UINT32 ExpectedBtypes, 179 UINT32 PackageIndex); 180 181static ACPI_STATUS 182AcpiNsCheckReference ( 183 ACPI_PREDEFINED_DATA *Data, 184 ACPI_OPERAND_OBJECT *ReturnObject); 185 186static void 187AcpiNsGetExpectedTypes ( 188 char *Buffer, 189 UINT32 ExpectedBtypes); 190 191/* 192 * Names for the types that can be returned by the predefined objects. 193 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs 194 */ 195static const char *AcpiRtypeNames[] = 196{ 197 "/Integer", 198 "/String", 199 "/Buffer", 200 "/Package", 201 "/Reference", 202}; 203 204 205/******************************************************************************* 206 * 207 * FUNCTION: AcpiNsCheckPredefinedNames 208 * 209 * PARAMETERS: Node - Namespace node for the method/object 210 * UserParamCount - Number of parameters actually passed 211 * ReturnStatus - Status from the object evaluation 212 * ReturnObjectPtr - Pointer to the object returned from the 213 * evaluation of a method or object 214 * 215 * RETURN: Status 216 * 217 * DESCRIPTION: Check an ACPI name for a match in the predefined name list. 218 * 219 ******************************************************************************/ 220 221ACPI_STATUS 222AcpiNsCheckPredefinedNames ( 223 ACPI_NAMESPACE_NODE *Node, 224 UINT32 UserParamCount, 225 ACPI_STATUS ReturnStatus, 226 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 227{ 228 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 229 ACPI_STATUS Status = AE_OK; 230 const ACPI_PREDEFINED_INFO *Predefined; 231 char *Pathname; 232 ACPI_PREDEFINED_DATA *Data; 233 234 235 /* Match the name for this method/object against the predefined list */ 236 237 Predefined = AcpiNsCheckForPredefinedName (Node); 238 239 /* Get the full pathname to the object, for use in warning messages */ 240 241 Pathname = AcpiNsGetExternalPathname (Node); 242 if (!Pathname) 243 { 244 return (AE_OK); /* Could not get pathname, ignore */ 245 } 246 247 /* 248 * Check that the parameter count for this method matches the ASL 249 * definition. For predefined names, ensure that both the caller and 250 * the method itself are in accordance with the ACPI specification. 251 */ 252 AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined); 253 254 /* If not a predefined name, we cannot validate the return object */ 255 256 if (!Predefined) 257 { 258 goto Cleanup; 259 } 260 261 /* 262 * If the method failed or did not actually return an object, we cannot 263 * validate the return object 264 */ 265 if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE)) 266 { 267 goto Cleanup; 268 } 269 270 /* 271 * If there is no return value, check if we require a return value for 272 * this predefined name. Either one return value is expected, or none, 273 * for both methods and other objects. 274 * 275 * Exit now if there is no return object. Warning if one was expected. 276 */ 277 if (!ReturnObject) 278 { 279 if ((Predefined->Info.ExpectedBtypes) && 280 (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE))) 281 { 282 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 283 "Missing expected return value")); 284 285 Status = AE_AML_NO_RETURN_VALUE; 286 } 287 goto Cleanup; 288 } 289 290 /* 291 * 1) We have a return value, but if one wasn't expected, just exit, this is 292 * not a problem. For example, if the "Implicit Return" feature is 293 * enabled, methods will always return a value. 294 * 295 * 2) If the return value can be of any type, then we cannot perform any 296 * validation, exit. 297 */ 298 if ((!Predefined->Info.ExpectedBtypes) || 299 (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL)) 300 { 301 goto Cleanup; 302 } 303 304 /* Create the parameter data block for object validation */ 305 306 Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA)); 307 if (!Data) 308 { 309 goto Cleanup; 310 } 311 Data->Predefined = Predefined; 312 Data->NodeFlags = Node->Flags; 313 Data->Pathname = Pathname; 314 315 /* 316 * Check that the type of the main return object is what is expected 317 * for this predefined name 318 */ 319 Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr, 320 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT); 321 if (ACPI_FAILURE (Status)) 322 { 323 goto Exit; 324 } 325 326 /* 327 * For returned Package objects, check the type of all sub-objects. 328 * Note: Package may have been newly created by call above. 329 */ 330 if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE) 331 { 332 Status = AcpiNsCheckPackage (Data, ReturnObjectPtr); 333 if (ACPI_FAILURE (Status)) 334 { 335 goto Exit; 336 } 337 } 338 339 /* 340 * The return object was OK, or it was successfully repaired above. 341 * Now make some additional checks such as verifying that package 342 * objects are sorted correctly (if required) or buffer objects have 343 * the correct data width (bytes vs. dwords). These repairs are 344 * performed on a per-name basis, i.e., the code is specific to 345 * particular predefined names. 346 */ 347 Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr); 348 349Exit: 350 /* 351 * If the object validation failed or if we successfully repaired one 352 * or more objects, mark the parent node to suppress further warning 353 * messages during the next evaluation of the same method/object. 354 */ 355 if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED)) 356 { 357 Node->Flags |= ANOBJ_EVALUATED; 358 } 359 ACPI_FREE (Data); 360 361Cleanup: 362 ACPI_FREE (Pathname); 363 return (Status); 364} 365 366 367/******************************************************************************* 368 * 369 * FUNCTION: AcpiNsCheckParameterCount 370 * 371 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 372 * Node - Namespace node for the method/object 373 * UserParamCount - Number of args passed in by the caller 374 * Predefined - Pointer to entry in predefined name table 375 * 376 * RETURN: None 377 * 378 * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a 379 * predefined name is what is expected (i.e., what is defined in 380 * the ACPI specification for this predefined name.) 381 * 382 ******************************************************************************/ 383 384void 385AcpiNsCheckParameterCount ( 386 char *Pathname, 387 ACPI_NAMESPACE_NODE *Node, 388 UINT32 UserParamCount, 389 const ACPI_PREDEFINED_INFO *Predefined) 390{ 391 UINT32 ParamCount; 392 UINT32 RequiredParamsCurrent; 393 UINT32 RequiredParamsOld; 394 395 396 /* Methods have 0-7 parameters. All other types have zero. */ 397 398 ParamCount = 0; 399 if (Node->Type == ACPI_TYPE_METHOD) 400 { 401 ParamCount = Node->Object->Method.ParamCount; 402 } 403 404 if (!Predefined) 405 { 406 /* 407 * Check the parameter count for non-predefined methods/objects. 408 * 409 * Warning if too few or too many arguments have been passed by the 410 * caller. An incorrect number of arguments may not cause the method 411 * to fail. However, the method will fail if there are too few 412 * arguments and the method attempts to use one of the missing ones. 413 */ 414 if (UserParamCount < ParamCount) 415 { 416 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 417 "Insufficient arguments - needs %u, found %u", 418 ParamCount, UserParamCount)); 419 } 420 else if (UserParamCount > ParamCount) 421 { 422 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 423 "Excess arguments - needs %u, found %u", 424 ParamCount, UserParamCount)); 425 } 426 return; 427 } 428 429 /* 430 * Validate the user-supplied parameter count. 431 * Allow two different legal argument counts (_SCP, etc.) 432 */ 433 RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F; 434 RequiredParamsOld = Predefined->Info.ParamCount >> 4; 435 436 if (UserParamCount != ACPI_UINT32_MAX) 437 { 438 if ((UserParamCount != RequiredParamsCurrent) && 439 (UserParamCount != RequiredParamsOld)) 440 { 441 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 442 "Parameter count mismatch - " 443 "caller passed %u, ACPI requires %u", 444 UserParamCount, RequiredParamsCurrent)); 445 } 446 } 447 448 /* 449 * Check that the ASL-defined parameter count is what is expected for 450 * this predefined name (parameter count as defined by the ACPI 451 * specification) 452 */ 453 if ((ParamCount != RequiredParamsCurrent) && 454 (ParamCount != RequiredParamsOld)) 455 { 456 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags, 457 "Parameter count mismatch - ASL declared %u, ACPI requires %u", 458 ParamCount, RequiredParamsCurrent)); 459 } 460} 461 462 463/******************************************************************************* 464 * 465 * FUNCTION: AcpiNsCheckForPredefinedName 466 * 467 * PARAMETERS: Node - Namespace node for the method/object 468 * 469 * RETURN: Pointer to entry in predefined table. NULL indicates not found. 470 * 471 * DESCRIPTION: Check an object name against the predefined object list. 472 * 473 ******************************************************************************/ 474 475const ACPI_PREDEFINED_INFO * 476AcpiNsCheckForPredefinedName ( 477 ACPI_NAMESPACE_NODE *Node) 478{ 479 const ACPI_PREDEFINED_INFO *ThisName; 480 481 482 /* Quick check for a predefined name, first character must be underscore */ 483 484 if (Node->Name.Ascii[0] != '_') 485 { 486 return (NULL); 487 } 488 489 /* Search info table for a predefined method/object name */ 490 491 ThisName = PredefinedNames; 492 while (ThisName->Info.Name[0]) 493 { 494 if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name)) 495 { 496 return (ThisName); 497 } 498 499 /* 500 * Skip next entry in the table if this name returns a Package 501 * (next entry contains the package info) 502 */ 503 if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) 504 { 505 ThisName++; 506 } 507 508 ThisName++; 509 } 510 511 return (NULL); /* Not found */ 512} 513 514 515/******************************************************************************* 516 * 517 * FUNCTION: AcpiNsCheckPackage 518 * 519 * PARAMETERS: Data - Pointer to validation data structure 520 * ReturnObjectPtr - Pointer to the object returned from the 521 * evaluation of a method or object 522 * 523 * RETURN: Status 524 * 525 * DESCRIPTION: Check a returned package object for the correct count and 526 * correct type of all sub-objects. 527 * 528 ******************************************************************************/ 529 530static ACPI_STATUS 531AcpiNsCheckPackage ( 532 ACPI_PREDEFINED_DATA *Data, 533 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 534{ 535 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 536 const ACPI_PREDEFINED_INFO *Package; 537 ACPI_OPERAND_OBJECT **Elements; 538 ACPI_STATUS Status = AE_OK; 539 UINT32 ExpectedCount; 540 UINT32 Count; 541 UINT32 i; 542 543 544 ACPI_FUNCTION_NAME (NsCheckPackage); 545 546 547 /* The package info for this name is in the next table entry */ 548 549 Package = Data->Predefined + 1; 550 551 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 552 "%s Validating return Package of Type %X, Count %X\n", 553 Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count)); 554 555 /* 556 * For variable-length Packages, we can safely remove all embedded 557 * and trailing NULL package elements 558 */ 559 AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject); 560 561 /* Extract package count and elements array */ 562 563 Elements = ReturnObject->Package.Elements; 564 Count = ReturnObject->Package.Count; 565 566 /* The package must have at least one element, else invalid */ 567 568 if (!Count) 569 { 570 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 571 "Return Package has no elements (empty)")); 572 573 return (AE_AML_OPERAND_VALUE); 574 } 575 576 /* 577 * Decode the type of the expected package contents 578 * 579 * PTYPE1 packages contain no subpackages 580 * PTYPE2 packages contain sub-packages 581 */ 582 switch (Package->RetInfo.Type) 583 { 584 case ACPI_PTYPE1_FIXED: 585 586 /* 587 * The package count is fixed and there are no sub-packages 588 * 589 * If package is too small, exit. 590 * If package is larger than expected, issue warning but continue 591 */ 592 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 593 if (Count < ExpectedCount) 594 { 595 goto PackageTooSmall; 596 } 597 else if (Count > ExpectedCount) 598 { 599 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 600 "%s: Return Package is larger than needed - " 601 "found %u, expected %u\n", 602 Data->Pathname, Count, ExpectedCount)); 603 } 604 605 /* Validate all elements of the returned package */ 606 607 Status = AcpiNsCheckPackageElements (Data, Elements, 608 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 609 Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0); 610 break; 611 612 613 case ACPI_PTYPE1_VAR: 614 615 /* 616 * The package count is variable, there are no sub-packages, and all 617 * elements must be of the same type 618 */ 619 for (i = 0; i < Count; i++) 620 { 621 Status = AcpiNsCheckObjectType (Data, Elements, 622 Package->RetInfo.ObjectType1, i); 623 if (ACPI_FAILURE (Status)) 624 { 625 return (Status); 626 } 627 Elements++; 628 } 629 break; 630 631 632 case ACPI_PTYPE1_OPTION: 633 634 /* 635 * The package count is variable, there are no sub-packages. There are 636 * a fixed number of required elements, and a variable number of 637 * optional elements. 638 * 639 * Check if package is at least as large as the minimum required 640 */ 641 ExpectedCount = Package->RetInfo3.Count; 642 if (Count < ExpectedCount) 643 { 644 goto PackageTooSmall; 645 } 646 647 /* Variable number of sub-objects */ 648 649 for (i = 0; i < Count; i++) 650 { 651 if (i < Package->RetInfo3.Count) 652 { 653 /* These are the required package elements (0, 1, or 2) */ 654 655 Status = AcpiNsCheckObjectType (Data, Elements, 656 Package->RetInfo3.ObjectType[i], i); 657 if (ACPI_FAILURE (Status)) 658 { 659 return (Status); 660 } 661 } 662 else 663 { 664 /* These are the optional package elements */ 665 666 Status = AcpiNsCheckObjectType (Data, Elements, 667 Package->RetInfo3.TailObjectType, i); 668 if (ACPI_FAILURE (Status)) 669 { 670 return (Status); 671 } 672 } 673 Elements++; 674 } 675 break; 676 677 678 case ACPI_PTYPE2_REV_FIXED: 679 680 /* First element is the (Integer) revision */ 681 682 Status = AcpiNsCheckObjectType (Data, Elements, 683 ACPI_RTYPE_INTEGER, 0); 684 if (ACPI_FAILURE (Status)) 685 { 686 return (Status); 687 } 688 689 Elements++; 690 Count--; 691 692 /* Examine the sub-packages */ 693 694 Status = AcpiNsCheckPackageList (Data, Package, Elements, Count); 695 break; 696 697 698 case ACPI_PTYPE2_PKG_COUNT: 699 700 /* First element is the (Integer) count of sub-packages to follow */ 701 702 Status = AcpiNsCheckObjectType (Data, Elements, 703 ACPI_RTYPE_INTEGER, 0); 704 if (ACPI_FAILURE (Status)) 705 { 706 return (Status); 707 } 708 709 /* 710 * Count cannot be larger than the parent package length, but allow it 711 * to be smaller. The >= accounts for the Integer above. 712 */ 713 ExpectedCount = (UINT32) (*Elements)->Integer.Value; 714 if (ExpectedCount >= Count) 715 { 716 goto PackageTooSmall; 717 } 718 719 Count = ExpectedCount; 720 Elements++; 721 722 /* Examine the sub-packages */ 723 724 Status = AcpiNsCheckPackageList (Data, Package, Elements, Count); 725 break; 726 727 728 case ACPI_PTYPE2: 729 case ACPI_PTYPE2_FIXED: 730 case ACPI_PTYPE2_MIN: 731 case ACPI_PTYPE2_COUNT: 732 733 /* 734 * These types all return a single Package that consists of a 735 * variable number of sub-Packages. 736 * 737 * First, ensure that the first element is a sub-Package. If not, 738 * the BIOS may have incorrectly returned the object as a single 739 * package instead of a Package of Packages (a common error if 740 * there is only one entry). We may be able to repair this by 741 * wrapping the returned Package with a new outer Package. 742 */ 743 if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE)) 744 { 745 /* Create the new outer package and populate it */ 746 747 Status = AcpiNsRepairPackageList (Data, ReturnObjectPtr); 748 if (ACPI_FAILURE (Status)) 749 { 750 return (Status); 751 } 752 753 /* Update locals to point to the new package (of 1 element) */ 754 755 ReturnObject = *ReturnObjectPtr; 756 Elements = ReturnObject->Package.Elements; 757 Count = 1; 758 } 759 760 /* Examine the sub-packages */ 761 762 Status = AcpiNsCheckPackageList (Data, Package, Elements, Count); 763 break; 764 765 766 default: 767 768 /* Should not get here if predefined info table is correct */ 769 770 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 771 "Invalid internal return type in table entry: %X", 772 Package->RetInfo.Type)); 773 774 return (AE_AML_INTERNAL); 775 } 776 777 return (Status); 778 779 780PackageTooSmall: 781 782 /* Error exit for the case with an incorrect package count */ 783 784 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 785 "Return Package is too small - found %u elements, expected %u", 786 Count, ExpectedCount)); 787 788 return (AE_AML_OPERAND_VALUE); 789} 790 791 792/******************************************************************************* 793 * 794 * FUNCTION: AcpiNsCheckPackageList 795 * 796 * PARAMETERS: Data - Pointer to validation data structure 797 * Package - Pointer to package-specific info for method 798 * Elements - Element list of parent package. All elements 799 * of this list should be of type Package. 800 * Count - Count of subpackages 801 * 802 * RETURN: Status 803 * 804 * DESCRIPTION: Examine a list of subpackages 805 * 806 ******************************************************************************/ 807 808static ACPI_STATUS 809AcpiNsCheckPackageList ( 810 ACPI_PREDEFINED_DATA *Data, 811 const ACPI_PREDEFINED_INFO *Package, 812 ACPI_OPERAND_OBJECT **Elements, 813 UINT32 Count) 814{ 815 ACPI_OPERAND_OBJECT *SubPackage; 816 ACPI_OPERAND_OBJECT **SubElements; 817 ACPI_STATUS Status; 818 UINT32 ExpectedCount; 819 UINT32 i; 820 UINT32 j; 821 822 823 /* 824 * Validate each sub-Package in the parent Package 825 * 826 * NOTE: assumes list of sub-packages contains no NULL elements. 827 * Any NULL elements should have been removed by earlier call 828 * to AcpiNsRemoveNullElements. 829 */ 830 for (i = 0; i < Count; i++) 831 { 832 SubPackage = *Elements; 833 SubElements = SubPackage->Package.Elements; 834 835 /* Each sub-object must be of type Package */ 836 837 Status = AcpiNsCheckObjectType (Data, &SubPackage, 838 ACPI_RTYPE_PACKAGE, i); 839 if (ACPI_FAILURE (Status)) 840 { 841 return (Status); 842 } 843 844 /* Examine the different types of expected sub-packages */ 845 846 switch (Package->RetInfo.Type) 847 { 848 case ACPI_PTYPE2: 849 case ACPI_PTYPE2_PKG_COUNT: 850 case ACPI_PTYPE2_REV_FIXED: 851 852 /* Each subpackage has a fixed number of elements */ 853 854 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 855 if (SubPackage->Package.Count < ExpectedCount) 856 { 857 goto PackageTooSmall; 858 } 859 860 Status = AcpiNsCheckPackageElements (Data, SubElements, 861 Package->RetInfo.ObjectType1, 862 Package->RetInfo.Count1, 863 Package->RetInfo.ObjectType2, 864 Package->RetInfo.Count2, 0); 865 if (ACPI_FAILURE (Status)) 866 { 867 return (Status); 868 } 869 break; 870 871 872 case ACPI_PTYPE2_FIXED: 873 874 /* Each sub-package has a fixed length */ 875 876 ExpectedCount = Package->RetInfo2.Count; 877 if (SubPackage->Package.Count < ExpectedCount) 878 { 879 goto PackageTooSmall; 880 } 881 882 /* Check the type of each sub-package element */ 883 884 for (j = 0; j < ExpectedCount; j++) 885 { 886 Status = AcpiNsCheckObjectType (Data, &SubElements[j], 887 Package->RetInfo2.ObjectType[j], j); 888 if (ACPI_FAILURE (Status)) 889 { 890 return (Status); 891 } 892 } 893 break; 894 895 896 case ACPI_PTYPE2_MIN: 897 898 /* Each sub-package has a variable but minimum length */ 899 900 ExpectedCount = Package->RetInfo.Count1; 901 if (SubPackage->Package.Count < ExpectedCount) 902 { 903 goto PackageTooSmall; 904 } 905 906 /* Check the type of each sub-package element */ 907 908 Status = AcpiNsCheckPackageElements (Data, SubElements, 909 Package->RetInfo.ObjectType1, 910 SubPackage->Package.Count, 0, 0, 0); 911 if (ACPI_FAILURE (Status)) 912 { 913 return (Status); 914 } 915 break; 916 917 918 case ACPI_PTYPE2_COUNT: 919 920 /* 921 * First element is the (Integer) count of elements, including 922 * the count field. 923 */ 924 Status = AcpiNsCheckObjectType (Data, SubElements, 925 ACPI_RTYPE_INTEGER, 0); 926 if (ACPI_FAILURE (Status)) 927 { 928 return (Status); 929 } 930 931 /* 932 * Make sure package is large enough for the Count and is 933 * is as large as the minimum size 934 */ 935 ExpectedCount = (UINT32) (*SubElements)->Integer.Value; 936 if (SubPackage->Package.Count < ExpectedCount) 937 { 938 goto PackageTooSmall; 939 } 940 if (SubPackage->Package.Count < Package->RetInfo.Count1) 941 { 942 ExpectedCount = Package->RetInfo.Count1; 943 goto PackageTooSmall; 944 } 945 946 /* Check the type of each sub-package element */ 947 948 Status = AcpiNsCheckPackageElements (Data, (SubElements + 1), 949 Package->RetInfo.ObjectType1, 950 (ExpectedCount - 1), 0, 0, 1); 951 if (ACPI_FAILURE (Status)) 952 { 953 return (Status); 954 } 955 break; 956 957 958 default: /* Should not get here, type was validated by caller */ 959 960 return (AE_AML_INTERNAL); 961 } 962 963 Elements++; 964 } 965 966 return (AE_OK); 967 968 969PackageTooSmall: 970 971 /* The sub-package count was smaller than required */ 972 973 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 974 "Return Sub-Package[%u] is too small - found %u elements, expected %u", 975 i, SubPackage->Package.Count, ExpectedCount)); 976 977 return (AE_AML_OPERAND_VALUE); 978} 979 980 981/******************************************************************************* 982 * 983 * FUNCTION: AcpiNsCheckPackageElements 984 * 985 * PARAMETERS: Data - Pointer to validation data structure 986 * Elements - Pointer to the package elements array 987 * Type1 - Object type for first group 988 * Count1 - Count for first group 989 * Type2 - Object type for second group 990 * Count2 - Count for second group 991 * StartIndex - Start of the first group of elements 992 * 993 * RETURN: Status 994 * 995 * DESCRIPTION: Check that all elements of a package are of the correct object 996 * type. Supports up to two groups of different object types. 997 * 998 ******************************************************************************/ 999 1000static ACPI_STATUS 1001AcpiNsCheckPackageElements ( 1002 ACPI_PREDEFINED_DATA *Data, 1003 ACPI_OPERAND_OBJECT **Elements, 1004 UINT8 Type1, 1005 UINT32 Count1, 1006 UINT8 Type2, 1007 UINT32 Count2, 1008 UINT32 StartIndex) 1009{ 1010 ACPI_OPERAND_OBJECT **ThisElement = Elements; 1011 ACPI_STATUS Status; 1012 UINT32 i; 1013 1014 1015 /* 1016 * Up to two groups of package elements are supported by the data 1017 * structure. All elements in each group must be of the same type. 1018 * The second group can have a count of zero. 1019 */ 1020 for (i = 0; i < Count1; i++) 1021 { 1022 Status = AcpiNsCheckObjectType (Data, ThisElement, 1023 Type1, i + StartIndex); 1024 if (ACPI_FAILURE (Status)) 1025 { 1026 return (Status); 1027 } 1028 ThisElement++; 1029 } 1030 1031 for (i = 0; i < Count2; i++) 1032 { 1033 Status = AcpiNsCheckObjectType (Data, ThisElement, 1034 Type2, (i + Count1 + StartIndex)); 1035 if (ACPI_FAILURE (Status)) 1036 { 1037 return (Status); 1038 } 1039 ThisElement++; 1040 } 1041 1042 return (AE_OK); 1043} 1044 1045 1046/******************************************************************************* 1047 * 1048 * FUNCTION: AcpiNsCheckObjectType 1049 * 1050 * PARAMETERS: Data - Pointer to validation data structure 1051 * ReturnObjectPtr - Pointer to the object returned from the 1052 * evaluation of a method or object 1053 * ExpectedBtypes - Bitmap of expected return type(s) 1054 * PackageIndex - Index of object within parent package (if 1055 * applicable - ACPI_NOT_PACKAGE_ELEMENT 1056 * otherwise) 1057 * 1058 * RETURN: Status 1059 * 1060 * DESCRIPTION: Check the type of the return object against the expected object 1061 * type(s). Use of Btype allows multiple expected object types. 1062 * 1063 ******************************************************************************/ 1064 1065static ACPI_STATUS 1066AcpiNsCheckObjectType ( 1067 ACPI_PREDEFINED_DATA *Data, 1068 ACPI_OPERAND_OBJECT **ReturnObjectPtr, 1069 UINT32 ExpectedBtypes, 1070 UINT32 PackageIndex) 1071{ 1072 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 1073 ACPI_STATUS Status = AE_OK; 1074 UINT32 ReturnBtype; 1075 char TypeBuffer[48]; /* Room for 5 types */ 1076 1077 1078 /* 1079 * If we get a NULL ReturnObject here, it is a NULL package element, 1080 * and this is always an error. 1081 */ 1082 if (!ReturnObject) 1083 { 1084 goto TypeErrorExit; 1085 } 1086 1087 /* A Namespace node should not get here, but make sure */ 1088 1089 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) 1090 { 1091 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 1092 "Invalid return type - Found a Namespace node [%4.4s] type %s", 1093 ReturnObject->Node.Name.Ascii, 1094 AcpiUtGetTypeName (ReturnObject->Node.Type))); 1095 return (AE_AML_OPERAND_TYPE); 1096 } 1097 1098 /* 1099 * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. 1100 * The bitmapped type allows multiple possible return types. 1101 * 1102 * Note, the cases below must handle all of the possible types returned 1103 * from all of the predefined names (including elements of returned 1104 * packages) 1105 */ 1106 switch (ReturnObject->Common.Type) 1107 { 1108 case ACPI_TYPE_INTEGER: 1109 ReturnBtype = ACPI_RTYPE_INTEGER; 1110 break; 1111 1112 case ACPI_TYPE_BUFFER: 1113 ReturnBtype = ACPI_RTYPE_BUFFER; 1114 break; 1115 1116 case ACPI_TYPE_STRING: 1117 ReturnBtype = ACPI_RTYPE_STRING; 1118 break; 1119 1120 case ACPI_TYPE_PACKAGE: 1121 ReturnBtype = ACPI_RTYPE_PACKAGE; 1122 break; 1123 1124 case ACPI_TYPE_LOCAL_REFERENCE: 1125 ReturnBtype = ACPI_RTYPE_REFERENCE; 1126 break; 1127 1128 default: 1129 /* Not one of the supported objects, must be incorrect */ 1130 1131 goto TypeErrorExit; 1132 } 1133 1134 /* Is the object one of the expected types? */ 1135 1136 if (!(ReturnBtype & ExpectedBtypes)) 1137 { 1138 /* Type mismatch -- attempt repair of the returned object */ 1139 1140 Status = AcpiNsRepairObject (Data, ExpectedBtypes, 1141 PackageIndex, ReturnObjectPtr); 1142 if (ACPI_SUCCESS (Status)) 1143 { 1144 return (AE_OK); /* Repair was successful */ 1145 } 1146 goto TypeErrorExit; 1147 } 1148 1149 /* For reference objects, check that the reference type is correct */ 1150 1151 if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) 1152 { 1153 Status = AcpiNsCheckReference (Data, ReturnObject); 1154 } 1155 1156 return (Status); 1157 1158 1159TypeErrorExit: 1160 1161 /* Create a string with all expected types for this predefined object */ 1162 1163 AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes); 1164 1165 if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) 1166 { 1167 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 1168 "Return type mismatch - found %s, expected %s", 1169 AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 1170 } 1171 else 1172 { 1173 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 1174 "Return Package type mismatch at index %u - " 1175 "found %s, expected %s", PackageIndex, 1176 AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 1177 } 1178 1179 return (AE_AML_OPERAND_TYPE); 1180} 1181 1182 1183/******************************************************************************* 1184 * 1185 * FUNCTION: AcpiNsCheckReference 1186 * 1187 * PARAMETERS: Data - Pointer to validation data structure 1188 * ReturnObject - Object returned from the evaluation of a 1189 * method or object 1190 * 1191 * RETURN: Status 1192 * 1193 * DESCRIPTION: Check a returned reference object for the correct reference 1194 * type. The only reference type that can be returned from a 1195 * predefined method is a named reference. All others are invalid. 1196 * 1197 ******************************************************************************/ 1198 1199static ACPI_STATUS 1200AcpiNsCheckReference ( 1201 ACPI_PREDEFINED_DATA *Data, 1202 ACPI_OPERAND_OBJECT *ReturnObject) 1203{ 1204 1205 /* 1206 * Check the reference object for the correct reference type (opcode). 1207 * The only type of reference that can be converted to an ACPI_OBJECT is 1208 * a reference to a named object (reference class: NAME) 1209 */ 1210 if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME) 1211 { 1212 return (AE_OK); 1213 } 1214 1215 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 1216 "Return type mismatch - unexpected reference object type [%s] %2.2X", 1217 AcpiUtGetReferenceName (ReturnObject), 1218 ReturnObject->Reference.Class)); 1219 1220 return (AE_AML_OPERAND_TYPE); 1221} 1222 1223 1224/******************************************************************************* 1225 * 1226 * FUNCTION: AcpiNsGetExpectedTypes 1227 * 1228 * PARAMETERS: Buffer - Pointer to where the string is returned 1229 * ExpectedBtypes - Bitmap of expected return type(s) 1230 * 1231 * RETURN: Buffer is populated with type names. 1232 * 1233 * DESCRIPTION: Translate the expected types bitmap into a string of ascii 1234 * names of expected types, for use in warning messages. 1235 * 1236 ******************************************************************************/ 1237 1238static void 1239AcpiNsGetExpectedTypes ( 1240 char *Buffer, 1241 UINT32 ExpectedBtypes) 1242{ 1243 UINT32 ThisRtype; 1244 UINT32 i; 1245 UINT32 j; 1246 1247 1248 j = 1; 1249 Buffer[0] = 0; 1250 ThisRtype = ACPI_RTYPE_INTEGER; 1251 1252 for (i = 0; i < ACPI_NUM_RTYPES; i++) 1253 { 1254 /* If one of the expected types, concatenate the name of this type */ 1255 1256 if (ExpectedBtypes & ThisRtype) 1257 { 1258 ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]); 1259 j = 0; /* Use name separator from now on */ 1260 } 1261 ThisRtype <<= 1; /* Next Rtype */ 1262 } 1263} 1264