1193267Sjkim/****************************************************************************** 2193267Sjkim * 3193267Sjkim * Module Name: nspredef - Validation of ACPI predefined methods and objects 4193267Sjkim * 5193267Sjkim *****************************************************************************/ 6193267Sjkim 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 9193267Sjkim * All rights reserved. 10193267Sjkim * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25193267Sjkim * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29193267Sjkim * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43193267Sjkim 44197104Sjkim#define ACPI_CREATE_PREDEFINED_TABLE 45193267Sjkim 46193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 47193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 49193341Sjkim#include <contrib/dev/acpica/include/acpredef.h> 50193267Sjkim 51193267Sjkim 52193267Sjkim#define _COMPONENT ACPI_NAMESPACE 53193267Sjkim ACPI_MODULE_NAME ("nspredef") 54193267Sjkim 55193267Sjkim 56193267Sjkim/******************************************************************************* 57193267Sjkim * 58193267Sjkim * This module validates predefined ACPI objects that appear in the namespace, 59193267Sjkim * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this 60193267Sjkim * validation is to detect problems with BIOS-exposed predefined ACPI objects 61193267Sjkim * before the results are returned to the ACPI-related drivers. 62193267Sjkim * 63193267Sjkim * There are several areas that are validated: 64193267Sjkim * 65193267Sjkim * 1) The number of input arguments as defined by the method/object in the 66249663Sjkim * ASL is validated against the ACPI specification. 67193267Sjkim * 2) The type of the return object (if any) is validated against the ACPI 68249663Sjkim * specification. 69193267Sjkim * 3) For returned package objects, the count of package elements is 70249663Sjkim * validated, as well as the type of each package element. Nested 71249663Sjkim * packages are supported. 72193267Sjkim * 73193267Sjkim * For any problems found, a warning message is issued. 74193267Sjkim * 75193267Sjkim ******************************************************************************/ 76193267Sjkim 77197104Sjkim 78193267Sjkim/* Local prototypes */ 79193267Sjkim 80193267Sjkimstatic ACPI_STATUS 81193267SjkimAcpiNsCheckReference ( 82249663Sjkim ACPI_EVALUATE_INFO *Info, 83193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject); 84193267Sjkim 85246849Sjkimstatic UINT32 86246849SjkimAcpiNsGetBitmappedType ( 87246849Sjkim ACPI_OPERAND_OBJECT *ReturnObject); 88246849Sjkim 89246849Sjkim 90193267Sjkim/******************************************************************************* 91193267Sjkim * 92249663Sjkim * FUNCTION: AcpiNsCheckReturnValue 93193267Sjkim * 94193267Sjkim * PARAMETERS: Node - Namespace node for the method/object 95249663Sjkim * Info - Method execution information block 96197104Sjkim * UserParamCount - Number of parameters actually passed 97197104Sjkim * ReturnStatus - Status from the object evaluation 98193267Sjkim * ReturnObjectPtr - Pointer to the object returned from the 99193267Sjkim * evaluation of a method or object 100193267Sjkim * 101193267Sjkim * RETURN: Status 102193267Sjkim * 103249663Sjkim * DESCRIPTION: Check the value returned from a predefined name. 104193267Sjkim * 105193267Sjkim ******************************************************************************/ 106193267Sjkim 107193267SjkimACPI_STATUS 108249663SjkimAcpiNsCheckReturnValue ( 109193267Sjkim ACPI_NAMESPACE_NODE *Node, 110249663Sjkim ACPI_EVALUATE_INFO *Info, 111193267Sjkim UINT32 UserParamCount, 112193267Sjkim ACPI_STATUS ReturnStatus, 113193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 114193267Sjkim{ 115249663Sjkim ACPI_STATUS Status; 116193267Sjkim const ACPI_PREDEFINED_INFO *Predefined; 117193267Sjkim 118193267Sjkim 119193267Sjkim /* If not a predefined name, we cannot validate the return object */ 120193267Sjkim 121249663Sjkim Predefined = Info->Predefined; 122193267Sjkim if (!Predefined) 123193267Sjkim { 124249663Sjkim return (AE_OK); 125193267Sjkim } 126193267Sjkim 127193267Sjkim /* 128197104Sjkim * If the method failed or did not actually return an object, we cannot 129197104Sjkim * validate the return object 130193267Sjkim */ 131249663Sjkim if ((ReturnStatus != AE_OK) && 132249663Sjkim (ReturnStatus != AE_CTRL_RETURN_VALUE)) 133193267Sjkim { 134249663Sjkim return (AE_OK); 135193267Sjkim } 136193267Sjkim 137193267Sjkim /* 138228110Sjkim * Return value validation and possible repair. 139193267Sjkim * 140228110Sjkim * 1) Don't perform return value validation/repair if this feature 141228110Sjkim * has been disabled via a global option. 142228110Sjkim * 143228110Sjkim * 2) We have a return value, but if one wasn't expected, just exit, 144228110Sjkim * this is not a problem. For example, if the "Implicit Return" 145228110Sjkim * feature is enabled, methods will always return a value. 146228110Sjkim * 147228110Sjkim * 3) If the return value can be of any type, then we cannot perform 148228110Sjkim * any validation, just exit. 149193267Sjkim */ 150228110Sjkim if (AcpiGbl_DisableAutoRepair || 151228110Sjkim (!Predefined->Info.ExpectedBtypes) || 152197104Sjkim (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL)) 153193267Sjkim { 154249663Sjkim return (AE_OK); 155193267Sjkim } 156193267Sjkim 157193267Sjkim /* 158200553Sjkim * Check that the type of the main return object is what is expected 159200553Sjkim * for this predefined name 160193267Sjkim */ 161249663Sjkim Status = AcpiNsCheckObjectType (Info, ReturnObjectPtr, 162249663Sjkim Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT); 163193267Sjkim if (ACPI_FAILURE (Status)) 164193267Sjkim { 165200553Sjkim goto Exit; 166193267Sjkim } 167193267Sjkim 168200553Sjkim /* 169253690Sjkim * 170253690Sjkim * 4) If there is no return value and it is optional, just return 171253690Sjkim * AE_OK (_WAK). 172253690Sjkim */ 173253690Sjkim if (!(*ReturnObjectPtr)) 174253690Sjkim { 175253690Sjkim goto Exit; 176253690Sjkim } 177253690Sjkim 178253690Sjkim /* 179200553Sjkim * For returned Package objects, check the type of all sub-objects. 180200553Sjkim * Note: Package may have been newly created by call above. 181200553Sjkim */ 182200553Sjkim if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE) 183193267Sjkim { 184249663Sjkim Info->ParentPackage = *ReturnObjectPtr; 185249663Sjkim Status = AcpiNsCheckPackage (Info, ReturnObjectPtr); 186200553Sjkim if (ACPI_FAILURE (Status)) 187200553Sjkim { 188250838Sjkim /* We might be able to fix some errors */ 189250838Sjkim 190250838Sjkim if ((Status != AE_AML_OPERAND_TYPE) && 191250838Sjkim (Status != AE_AML_OPERAND_VALUE)) 192250838Sjkim { 193250838Sjkim goto Exit; 194250838Sjkim } 195200553Sjkim } 196193267Sjkim } 197193267Sjkim 198199337Sjkim /* 199200553Sjkim * The return object was OK, or it was successfully repaired above. 200200553Sjkim * Now make some additional checks such as verifying that package 201200553Sjkim * objects are sorted correctly (if required) or buffer objects have 202200553Sjkim * the correct data width (bytes vs. dwords). These repairs are 203200553Sjkim * performed on a per-name basis, i.e., the code is specific to 204200553Sjkim * particular predefined names. 205199337Sjkim */ 206249663Sjkim Status = AcpiNsComplexRepairs (Info, Node, Status, ReturnObjectPtr); 207197104Sjkim 208200553SjkimExit: 209197104Sjkim /* 210197104Sjkim * If the object validation failed or if we successfully repaired one 211197104Sjkim * or more objects, mark the parent node to suppress further warning 212197104Sjkim * messages during the next evaluation of the same method/object. 213197104Sjkim */ 214249663Sjkim if (ACPI_FAILURE (Status) || 215249663Sjkim (Info->ReturnFlags & ACPI_OBJECT_REPAIRED)) 216197104Sjkim { 217197104Sjkim Node->Flags |= ANOBJ_EVALUATED; 218197104Sjkim } 219197104Sjkim 220193267Sjkim return (Status); 221193267Sjkim} 222193267Sjkim 223193267Sjkim 224193267Sjkim/******************************************************************************* 225193267Sjkim * 226193267Sjkim * FUNCTION: AcpiNsCheckObjectType 227193267Sjkim * 228249663Sjkim * PARAMETERS: Info - Method execution information block 229193267Sjkim * ReturnObjectPtr - Pointer to the object returned from the 230193267Sjkim * evaluation of a method or object 231193267Sjkim * ExpectedBtypes - Bitmap of expected return type(s) 232193267Sjkim * PackageIndex - Index of object within parent package (if 233197104Sjkim * applicable - ACPI_NOT_PACKAGE_ELEMENT 234197104Sjkim * otherwise) 235193267Sjkim * 236193267Sjkim * RETURN: Status 237193267Sjkim * 238193267Sjkim * DESCRIPTION: Check the type of the return object against the expected object 239193267Sjkim * type(s). Use of Btype allows multiple expected object types. 240193267Sjkim * 241193267Sjkim ******************************************************************************/ 242193267Sjkim 243245582SjkimACPI_STATUS 244193267SjkimAcpiNsCheckObjectType ( 245249663Sjkim ACPI_EVALUATE_INFO *Info, 246193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr, 247193267Sjkim UINT32 ExpectedBtypes, 248193267Sjkim UINT32 PackageIndex) 249193267Sjkim{ 250193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 251193267Sjkim ACPI_STATUS Status = AE_OK; 252193267Sjkim char TypeBuffer[48]; /* Room for 5 types */ 253193267Sjkim 254193267Sjkim 255193267Sjkim /* A Namespace node should not get here, but make sure */ 256193267Sjkim 257246849Sjkim if (ReturnObject && 258246849Sjkim ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) 259193267Sjkim { 260249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 261197104Sjkim "Invalid return type - Found a Namespace node [%4.4s] type %s", 262197104Sjkim ReturnObject->Node.Name.Ascii, 263193267Sjkim AcpiUtGetTypeName (ReturnObject->Node.Type))); 264193267Sjkim return (AE_AML_OPERAND_TYPE); 265193267Sjkim } 266193267Sjkim 267193267Sjkim /* 268193267Sjkim * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. 269193267Sjkim * The bitmapped type allows multiple possible return types. 270193267Sjkim * 271193267Sjkim * Note, the cases below must handle all of the possible types returned 272193267Sjkim * from all of the predefined names (including elements of returned 273193267Sjkim * packages) 274193267Sjkim */ 275249663Sjkim Info->ReturnBtype = AcpiNsGetBitmappedType (ReturnObject); 276249663Sjkim if (Info->ReturnBtype == ACPI_RTYPE_ANY) 277193267Sjkim { 278193267Sjkim /* Not one of the supported objects, must be incorrect */ 279193267Sjkim goto TypeErrorExit; 280193267Sjkim } 281193267Sjkim 282246849Sjkim /* For reference objects, check that the reference type is correct */ 283193267Sjkim 284249663Sjkim if ((Info->ReturnBtype & ExpectedBtypes) == ACPI_RTYPE_REFERENCE) 285193267Sjkim { 286249663Sjkim Status = AcpiNsCheckReference (Info, ReturnObject); 287202771Sjkim return (Status); 288193267Sjkim } 289193267Sjkim 290246849Sjkim /* Attempt simple repair of the returned object if necessary */ 291193267Sjkim 292249663Sjkim Status = AcpiNsSimpleRepair (Info, ExpectedBtypes, 293249663Sjkim PackageIndex, ReturnObjectPtr); 294249663Sjkim if (ACPI_SUCCESS (Status)) 295249663Sjkim { 296249663Sjkim return (AE_OK); /* Successful repair */ 297249663Sjkim } 298193267Sjkim 299193267Sjkim 300193267SjkimTypeErrorExit: 301193267Sjkim 302193267Sjkim /* Create a string with all expected types for this predefined object */ 303193267Sjkim 304249112Sjkim AcpiUtGetExpectedReturnTypes (TypeBuffer, ExpectedBtypes); 305193267Sjkim 306253690Sjkim if (!ReturnObject) 307193267Sjkim { 308249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 309253690Sjkim "Expected return object of type %s", 310253690Sjkim TypeBuffer)); 311253690Sjkim } 312253690Sjkim else if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) 313253690Sjkim { 314253690Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 315197104Sjkim "Return type mismatch - found %s, expected %s", 316197104Sjkim AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 317193267Sjkim } 318193267Sjkim else 319193267Sjkim { 320249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 321197104Sjkim "Return Package type mismatch at index %u - " 322197104Sjkim "found %s, expected %s", PackageIndex, 323193267Sjkim AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 324193267Sjkim } 325193267Sjkim 326193267Sjkim return (AE_AML_OPERAND_TYPE); 327193267Sjkim} 328193267Sjkim 329193267Sjkim 330193267Sjkim/******************************************************************************* 331193267Sjkim * 332193267Sjkim * FUNCTION: AcpiNsCheckReference 333193267Sjkim * 334249663Sjkim * PARAMETERS: Info - Method execution information block 335193267Sjkim * ReturnObject - Object returned from the evaluation of a 336193267Sjkim * method or object 337193267Sjkim * 338193267Sjkim * RETURN: Status 339193267Sjkim * 340193267Sjkim * DESCRIPTION: Check a returned reference object for the correct reference 341193267Sjkim * type. The only reference type that can be returned from a 342193267Sjkim * predefined method is a named reference. All others are invalid. 343193267Sjkim * 344193267Sjkim ******************************************************************************/ 345193267Sjkim 346193267Sjkimstatic ACPI_STATUS 347193267SjkimAcpiNsCheckReference ( 348249663Sjkim ACPI_EVALUATE_INFO *Info, 349193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject) 350193267Sjkim{ 351193267Sjkim 352193267Sjkim /* 353193267Sjkim * Check the reference object for the correct reference type (opcode). 354193267Sjkim * The only type of reference that can be converted to an ACPI_OBJECT is 355193267Sjkim * a reference to a named object (reference class: NAME) 356193267Sjkim */ 357193267Sjkim if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME) 358193267Sjkim { 359193267Sjkim return (AE_OK); 360193267Sjkim } 361193267Sjkim 362249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 363197104Sjkim "Return type mismatch - unexpected reference object type [%s] %2.2X", 364197104Sjkim AcpiUtGetReferenceName (ReturnObject), 365193267Sjkim ReturnObject->Reference.Class)); 366193267Sjkim 367193267Sjkim return (AE_AML_OPERAND_TYPE); 368193267Sjkim} 369193267Sjkim 370193267Sjkim 371193267Sjkim/******************************************************************************* 372193267Sjkim * 373246849Sjkim * FUNCTION: AcpiNsGetBitmappedType 374246849Sjkim * 375246849Sjkim * PARAMETERS: ReturnObject - Object returned from method/obj evaluation 376246849Sjkim * 377246849Sjkim * RETURN: Object return type. ACPI_RTYPE_ANY indicates that the object 378246849Sjkim * type is not supported. ACPI_RTYPE_NONE indicates that no 379246849Sjkim * object was returned (ReturnObject is NULL). 380246849Sjkim * 381246849Sjkim * DESCRIPTION: Convert object type into a bitmapped object return type. 382246849Sjkim * 383246849Sjkim ******************************************************************************/ 384246849Sjkim 385246849Sjkimstatic UINT32 386246849SjkimAcpiNsGetBitmappedType ( 387246849Sjkim ACPI_OPERAND_OBJECT *ReturnObject) 388246849Sjkim{ 389246849Sjkim UINT32 ReturnBtype; 390246849Sjkim 391246849Sjkim 392246849Sjkim if (!ReturnObject) 393246849Sjkim { 394246849Sjkim return (ACPI_RTYPE_NONE); 395246849Sjkim } 396246849Sjkim 397246849Sjkim /* Map ACPI_OBJECT_TYPE to internal bitmapped type */ 398246849Sjkim 399246849Sjkim switch (ReturnObject->Common.Type) 400246849Sjkim { 401246849Sjkim case ACPI_TYPE_INTEGER: 402250838Sjkim 403246849Sjkim ReturnBtype = ACPI_RTYPE_INTEGER; 404246849Sjkim break; 405246849Sjkim 406246849Sjkim case ACPI_TYPE_BUFFER: 407250838Sjkim 408246849Sjkim ReturnBtype = ACPI_RTYPE_BUFFER; 409246849Sjkim break; 410246849Sjkim 411246849Sjkim case ACPI_TYPE_STRING: 412250838Sjkim 413246849Sjkim ReturnBtype = ACPI_RTYPE_STRING; 414246849Sjkim break; 415246849Sjkim 416246849Sjkim case ACPI_TYPE_PACKAGE: 417250838Sjkim 418246849Sjkim ReturnBtype = ACPI_RTYPE_PACKAGE; 419246849Sjkim break; 420246849Sjkim 421246849Sjkim case ACPI_TYPE_LOCAL_REFERENCE: 422250838Sjkim 423246849Sjkim ReturnBtype = ACPI_RTYPE_REFERENCE; 424246849Sjkim break; 425246849Sjkim 426246849Sjkim default: 427250838Sjkim 428246849Sjkim /* Not one of the supported objects, must be incorrect */ 429246849Sjkim 430246849Sjkim ReturnBtype = ACPI_RTYPE_ANY; 431246849Sjkim break; 432246849Sjkim } 433246849Sjkim 434246849Sjkim return (ReturnBtype); 435246849Sjkim} 436