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