1 /****************************************************************************** 2 * 3 * Module Name: nspredef - Validation of ACPI predefined methods and objects 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 <contrib/dev/acpica/include/acpi.h> 47 #include <contrib/dev/acpica/include/accommon.h> 48 #include <contrib/dev/acpica/include/acnamesp.h> 49 #include <contrib/dev/acpica/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 AcpiNsCheckReference ( 82 ACPI_PREDEFINED_DATA *Data, 83 ACPI_OPERAND_OBJECT *ReturnObject); 84 85 static void 86 AcpiNsGetExpectedTypes ( 87 char *Buffer, 88 UINT32 ExpectedBtypes); 89 90 /* 91 * Names for the types that can be returned by the predefined objects. 92 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs 93 */ 94 static const char *AcpiRtypeNames[] = 95 { 96 "/Integer", 97 "/String", 98 "/Buffer", 99 "/Package", 100 "/Reference", 101 }; 102 103 104 /******************************************************************************* 105 * 106 * FUNCTION: AcpiNsCheckPredefinedNames 107 * 108 * PARAMETERS: Node - Namespace node for the method/object 109 * UserParamCount - Number of parameters actually passed 110 * ReturnStatus - Status from the object evaluation 111 * ReturnObjectPtr - Pointer to the object returned from the 112 * evaluation of a method or object 113 * 114 * RETURN: Status 115 * 116 * DESCRIPTION: Check an ACPI name for a match in the predefined name list. 117 * 118 ******************************************************************************/ 119 120 ACPI_STATUS 121 AcpiNsCheckPredefinedNames ( 122 ACPI_NAMESPACE_NODE *Node, 123 UINT32 UserParamCount, 124 ACPI_STATUS ReturnStatus, 125 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 126 { 127 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 128 ACPI_STATUS Status = AE_OK; 129 const ACPI_PREDEFINED_INFO *Predefined; 130 char *Pathname; 131 ACPI_PREDEFINED_DATA *Data; 132 133 134 /* Match the name for this method/object against the predefined list */ 135 136 Predefined = AcpiNsCheckForPredefinedName (Node); 137 138 /* Get the full pathname to the object, for use in warning messages */ 139 140 Pathname = AcpiNsGetExternalPathname (Node); 141 if (!Pathname) 142 { 143 return (AE_OK); /* Could not get pathname, ignore */ 144 } 145 146 /* 147 * Check that the parameter count for this method matches the ASL 148 * definition. For predefined names, ensure that both the caller and 149 * the method itself are in accordance with the ACPI specification. 150 */ 151 AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined); 152 153 /* If not a predefined name, we cannot validate the return object */ 154 155 if (!Predefined) 156 { 157 goto Cleanup; 158 } 159 160 /* 161 * If the method failed or did not actually return an object, we cannot 162 * validate the return object 163 */ 164 if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE)) 165 { 166 goto Cleanup; 167 } 168 169 /* 170 * If there is no return value, check if we require a return value for 171 * this predefined name. Either one return value is expected, or none, 172 * for both methods and other objects. 173 * 174 * Exit now if there is no return object. Warning if one was expected. 175 */ 176 if (!ReturnObject) 177 { 178 if ((Predefined->Info.ExpectedBtypes) && 179 (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE))) 180 { 181 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 182 "Missing expected return value")); 183 184 Status = AE_AML_NO_RETURN_VALUE; 185 } 186 goto Cleanup; 187 } 188 189 /* 190 * Return value validation and possible repair. 191 * 192 * 1) Don't perform return value validation/repair if this feature 193 * has been disabled via a global option. 194 * 195 * 2) We have a return value, but if one wasn't expected, just exit, 196 * this is not a problem. For example, if the "Implicit Return" 197 * feature is enabled, methods will always return a value. 198 * 199 * 3) If the return value can be of any type, then we cannot perform 200 * any validation, just exit. 201 */ 202 if (AcpiGbl_DisableAutoRepair || 203 (!Predefined->Info.ExpectedBtypes) || 204 (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL)) 205 { 206 goto Cleanup; 207 } 208 209 /* Create the parameter data block for object validation */ 210 211 Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA)); 212 if (!Data) 213 { 214 goto Cleanup; 215 } 216 Data->Predefined = Predefined; 217 Data->Node = Node; 218 Data->NodeFlags = Node->Flags; 219 Data->Pathname = Pathname; 220 221 /* 222 * Check that the type of the main return object is what is expected 223 * for this predefined name 224 */ 225 Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr, 226 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT); 227 if (ACPI_FAILURE (Status)) 228 { 229 goto Exit; 230 } 231 232 /* 233 * For returned Package objects, check the type of all sub-objects. 234 * Note: Package may have been newly created by call above. 235 */ 236 if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE) 237 { 238 Data->ParentPackage = *ReturnObjectPtr; 239 Status = AcpiNsCheckPackage (Data, ReturnObjectPtr); 240 if (ACPI_FAILURE (Status)) 241 { 242 goto Exit; 243 } 244 } 245 246 /* 247 * The return object was OK, or it was successfully repaired above. 248 * Now make some additional checks such as verifying that package 249 * objects are sorted correctly (if required) or buffer objects have 250 * the correct data width (bytes vs. dwords). These repairs are 251 * performed on a per-name basis, i.e., the code is specific to 252 * particular predefined names. 253 */ 254 Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr); 255 256 Exit: 257 /* 258 * If the object validation failed or if we successfully repaired one 259 * or more objects, mark the parent node to suppress further warning 260 * messages during the next evaluation of the same method/object. 261 */ 262 if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED)) 263 { 264 Node->Flags |= ANOBJ_EVALUATED; 265 } 266 ACPI_FREE (Data); 267 268 Cleanup: 269 ACPI_FREE (Pathname); 270 return (Status); 271 } 272 273 274 /******************************************************************************* 275 * 276 * FUNCTION: AcpiNsCheckParameterCount 277 * 278 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 279 * Node - Namespace node for the method/object 280 * UserParamCount - Number of args passed in by the caller 281 * Predefined - Pointer to entry in predefined name table 282 * 283 * RETURN: None 284 * 285 * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a 286 * predefined name is what is expected (i.e., what is defined in 287 * the ACPI specification for this predefined name.) 288 * 289 ******************************************************************************/ 290 291 void 292 AcpiNsCheckParameterCount ( 293 char *Pathname, 294 ACPI_NAMESPACE_NODE *Node, 295 UINT32 UserParamCount, 296 const ACPI_PREDEFINED_INFO *Predefined) 297 { 298 UINT32 ParamCount; 299 UINT32 RequiredParamsCurrent; 300 UINT32 RequiredParamsOld; 301 302 303 /* Methods have 0-7 parameters. All other types have zero. */ 304 305 ParamCount = 0; 306 if (Node->Type == ACPI_TYPE_METHOD) 307 { 308 ParamCount = Node->Object->Method.ParamCount; 309 } 310 311 if (!Predefined) 312 { 313 /* 314 * Check the parameter count for non-predefined methods/objects. 315 * 316 * Warning if too few or too many arguments have been passed by the 317 * caller. An incorrect number of arguments may not cause the method 318 * to fail. However, the method will fail if there are too few 319 * arguments and the method attempts to use one of the missing ones. 320 */ 321 if (UserParamCount < ParamCount) 322 { 323 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 324 "Insufficient arguments - needs %u, found %u", 325 ParamCount, UserParamCount)); 326 } 327 else if (UserParamCount > ParamCount) 328 { 329 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 330 "Excess arguments - needs %u, found %u", 331 ParamCount, UserParamCount)); 332 } 333 return; 334 } 335 336 /* 337 * Validate the user-supplied parameter count. 338 * Allow two different legal argument counts (_SCP, etc.) 339 */ 340 RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F; 341 RequiredParamsOld = Predefined->Info.ParamCount >> 4; 342 343 if (UserParamCount != ACPI_UINT32_MAX) 344 { 345 if ((UserParamCount != RequiredParamsCurrent) && 346 (UserParamCount != RequiredParamsOld)) 347 { 348 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 349 "Parameter count mismatch - " 350 "caller passed %u, ACPI requires %u", 351 UserParamCount, RequiredParamsCurrent)); 352 } 353 } 354 355 /* 356 * Check that the ASL-defined parameter count is what is expected for 357 * this predefined name (parameter count as defined by the ACPI 358 * specification) 359 */ 360 if ((ParamCount != RequiredParamsCurrent) && 361 (ParamCount != RequiredParamsOld)) 362 { 363 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags, 364 "Parameter count mismatch - ASL declared %u, ACPI requires %u", 365 ParamCount, RequiredParamsCurrent)); 366 } 367 } 368 369 370 /******************************************************************************* 371 * 372 * FUNCTION: AcpiNsCheckForPredefinedName 373 * 374 * PARAMETERS: Node - Namespace node for the method/object 375 * 376 * RETURN: Pointer to entry in predefined table. NULL indicates not found. 377 * 378 * DESCRIPTION: Check an object name against the predefined object list. 379 * 380 ******************************************************************************/ 381 382 const ACPI_PREDEFINED_INFO * 383 AcpiNsCheckForPredefinedName ( 384 ACPI_NAMESPACE_NODE *Node) 385 { 386 const ACPI_PREDEFINED_INFO *ThisName; 387 388 389 /* Quick check for a predefined name, first character must be underscore */ 390 391 if (Node->Name.Ascii[0] != '_') 392 { 393 return (NULL); 394 } 395 396 /* Search info table for a predefined method/object name */ 397 398 ThisName = PredefinedNames; 399 while (ThisName->Info.Name[0]) 400 { 401 if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name)) 402 { 403 return (ThisName); 404 } 405 406 /* 407 * Skip next entry in the table if this name returns a Package 408 * (next entry contains the package info) 409 */ 410 if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) 411 { 412 ThisName++; 413 } 414 415 ThisName++; 416 } 417 418 return (NULL); /* Not found */ 419 } 420 421 422 /******************************************************************************* 423 * 424 * FUNCTION: AcpiNsCheckObjectType 425 * 426 * PARAMETERS: Data - Pointer to validation data structure 427 * ReturnObjectPtr - Pointer to the object returned from the 428 * evaluation of a method or object 429 * ExpectedBtypes - Bitmap of expected return type(s) 430 * PackageIndex - Index of object within parent package (if 431 * applicable - ACPI_NOT_PACKAGE_ELEMENT 432 * otherwise) 433 * 434 * RETURN: Status 435 * 436 * DESCRIPTION: Check the type of the return object against the expected object 437 * type(s). Use of Btype allows multiple expected object types. 438 * 439 ******************************************************************************/ 440 441 ACPI_STATUS 442 AcpiNsCheckObjectType ( 443 ACPI_PREDEFINED_DATA *Data, 444 ACPI_OPERAND_OBJECT **ReturnObjectPtr, 445 UINT32 ExpectedBtypes, 446 UINT32 PackageIndex) 447 { 448 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 449 ACPI_STATUS Status = AE_OK; 450 UINT32 ReturnBtype; 451 char TypeBuffer[48]; /* Room for 5 types */ 452 453 454 /* 455 * If we get a NULL ReturnObject here, it is a NULL package element. 456 * Since all extraneous NULL package elements were removed earlier by a 457 * call to AcpiNsRemoveNullElements, this is an unexpected NULL element. 458 * We will attempt to repair it. 459 */ 460 if (!ReturnObject) 461 { 462 Status = AcpiNsRepairNullElement (Data, ExpectedBtypes, 463 PackageIndex, ReturnObjectPtr); 464 if (ACPI_SUCCESS (Status)) 465 { 466 return (AE_OK); /* Repair was successful */ 467 } 468 goto TypeErrorExit; 469 } 470 471 /* A Namespace node should not get here, but make sure */ 472 473 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) 474 { 475 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 476 "Invalid return type - Found a Namespace node [%4.4s] type %s", 477 ReturnObject->Node.Name.Ascii, 478 AcpiUtGetTypeName (ReturnObject->Node.Type))); 479 return (AE_AML_OPERAND_TYPE); 480 } 481 482 /* 483 * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. 484 * The bitmapped type allows multiple possible return types. 485 * 486 * Note, the cases below must handle all of the possible types returned 487 * from all of the predefined names (including elements of returned 488 * packages) 489 */ 490 switch (ReturnObject->Common.Type) 491 { 492 case ACPI_TYPE_INTEGER: 493 ReturnBtype = ACPI_RTYPE_INTEGER; 494 break; 495 496 case ACPI_TYPE_BUFFER: 497 ReturnBtype = ACPI_RTYPE_BUFFER; 498 break; 499 500 case ACPI_TYPE_STRING: 501 ReturnBtype = ACPI_RTYPE_STRING; 502 break; 503 504 case ACPI_TYPE_PACKAGE: 505 ReturnBtype = ACPI_RTYPE_PACKAGE; 506 break; 507 508 case ACPI_TYPE_LOCAL_REFERENCE: 509 ReturnBtype = ACPI_RTYPE_REFERENCE; 510 break; 511 512 default: 513 /* Not one of the supported objects, must be incorrect */ 514 515 goto TypeErrorExit; 516 } 517 518 /* Is the object one of the expected types? */ 519 520 if (ReturnBtype & ExpectedBtypes) 521 { 522 /* For reference objects, check that the reference type is correct */ 523 524 if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) 525 { 526 Status = AcpiNsCheckReference (Data, ReturnObject); 527 } 528 529 return (Status); 530 } 531 532 /* Type mismatch -- attempt repair of the returned object */ 533 534 Status = AcpiNsRepairObject (Data, ExpectedBtypes, 535 PackageIndex, ReturnObjectPtr); 536 if (ACPI_SUCCESS (Status)) 537 { 538 return (AE_OK); /* Repair was successful */ 539 } 540 541 542 TypeErrorExit: 543 544 /* Create a string with all expected types for this predefined object */ 545 546 AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes); 547 548 if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) 549 { 550 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 551 "Return type mismatch - found %s, expected %s", 552 AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 553 } 554 else 555 { 556 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 557 "Return Package type mismatch at index %u - " 558 "found %s, expected %s", PackageIndex, 559 AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 560 } 561 562 return (AE_AML_OPERAND_TYPE); 563 } 564 565 566 /******************************************************************************* 567 * 568 * FUNCTION: AcpiNsCheckReference 569 * 570 * PARAMETERS: Data - Pointer to validation data structure 571 * ReturnObject - Object returned from the evaluation of a 572 * method or object 573 * 574 * RETURN: Status 575 * 576 * DESCRIPTION: Check a returned reference object for the correct reference 577 * type. The only reference type that can be returned from a 578 * predefined method is a named reference. All others are invalid. 579 * 580 ******************************************************************************/ 581 582 static ACPI_STATUS 583 AcpiNsCheckReference ( 584 ACPI_PREDEFINED_DATA *Data, 585 ACPI_OPERAND_OBJECT *ReturnObject) 586 { 587 588 /* 589 * Check the reference object for the correct reference type (opcode). 590 * The only type of reference that can be converted to an ACPI_OBJECT is 591 * a reference to a named object (reference class: NAME) 592 */ 593 if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME) 594 { 595 return (AE_OK); 596 } 597 598 ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 599 "Return type mismatch - unexpected reference object type [%s] %2.2X", 600 AcpiUtGetReferenceName (ReturnObject), 601 ReturnObject->Reference.Class)); 602 603 return (AE_AML_OPERAND_TYPE); 604 } 605 606 607 /******************************************************************************* 608 * 609 * FUNCTION: AcpiNsGetExpectedTypes 610 * 611 * PARAMETERS: Buffer - Pointer to where the string is returned 612 * ExpectedBtypes - Bitmap of expected return type(s) 613 * 614 * RETURN: Buffer is populated with type names. 615 * 616 * DESCRIPTION: Translate the expected types bitmap into a string of ascii 617 * names of expected types, for use in warning messages. 618 * 619 ******************************************************************************/ 620 621 static void 622 AcpiNsGetExpectedTypes ( 623 char *Buffer, 624 UINT32 ExpectedBtypes) 625 { 626 UINT32 ThisRtype; 627 UINT32 i; 628 UINT32 j; 629 630 631 j = 1; 632 Buffer[0] = 0; 633 ThisRtype = ACPI_RTYPE_INTEGER; 634 635 for (i = 0; i < ACPI_NUM_RTYPES; i++) 636 { 637 /* If one of the expected types, concatenate the name of this type */ 638 639 if (ExpectedBtypes & ThisRtype) 640 { 641 ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]); 642 j = 0; /* Use name separator from now on */ 643 } 644 ThisRtype <<= 1; /* Next Rtype */ 645 } 646 } 647