1 /****************************************************************************** 2 * 3 * Module Name: nspredef - Validation of ACPI predefined methods and objects 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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 AcpiNsCheckReference ( 82 ACPI_EVALUATE_INFO *Info, 83 ACPI_OPERAND_OBJECT *ReturnObject); 84 85 static UINT32 86 AcpiNsGetBitmappedType ( 87 ACPI_OPERAND_OBJECT *ReturnObject); 88 89 90 /******************************************************************************* 91 * 92 * FUNCTION: AcpiNsCheckReturnValue 93 * 94 * PARAMETERS: Node - Namespace node for the method/object 95 * Info - Method execution information block 96 * UserParamCount - Number of parameters actually passed 97 * ReturnStatus - Status from the object evaluation 98 * ReturnObjectPtr - Pointer to the object returned from the 99 * evaluation of a method or object 100 * 101 * RETURN: Status 102 * 103 * DESCRIPTION: Check the value returned from a predefined name. 104 * 105 ******************************************************************************/ 106 107 ACPI_STATUS 108 AcpiNsCheckReturnValue ( 109 ACPI_NAMESPACE_NODE *Node, 110 ACPI_EVALUATE_INFO *Info, 111 UINT32 UserParamCount, 112 ACPI_STATUS ReturnStatus, 113 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 114 { 115 ACPI_STATUS Status; 116 const ACPI_PREDEFINED_INFO *Predefined; 117 118 ACPI_FUNCTION_TRACE (NsCheckReturnValue); 119 120 /* If not a predefined name, we cannot validate the return object */ 121 122 Predefined = Info->Predefined; 123 if (!Predefined) 124 { 125 return_ACPI_STATUS (AE_OK); 126 } 127 128 /* 129 * If the method failed or did not actually return an object, we cannot 130 * validate the return object 131 */ 132 if ((ReturnStatus != AE_OK) && 133 (ReturnStatus != AE_CTRL_RETURN_VALUE)) 134 { 135 return_ACPI_STATUS (AE_OK); 136 } 137 138 /* 139 * Return value validation and possible repair. 140 * 141 * 1) Don't perform return value validation/repair if this feature 142 * has been disabled via a global option. 143 * 144 * 2) We have a return value, but if one wasn't expected, just exit, 145 * this is not a problem. For example, if the "Implicit Return" 146 * feature is enabled, methods will always return a value. 147 * 148 * 3) If the return value can be of any type, then we cannot perform 149 * any validation, just exit. 150 */ 151 if (AcpiGbl_DisableAutoRepair || 152 (!Predefined->Info.ExpectedBtypes) || 153 (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL)) 154 { 155 return_ACPI_STATUS (AE_OK); 156 } 157 158 /* 159 * Check that the type of the main return object is what is expected 160 * for this predefined name 161 */ 162 Status = AcpiNsCheckObjectType (Info, ReturnObjectPtr, 163 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT); 164 if (ACPI_FAILURE (Status)) 165 { 166 goto Exit; 167 } 168 169 /* 170 * 171 * 4) If there is no return value and it is optional, just return 172 * AE_OK (_WAK). 173 */ 174 if (!(*ReturnObjectPtr)) 175 { 176 goto Exit; 177 } 178 179 /* 180 * For returned Package objects, check the type of all sub-objects. 181 * Note: Package may have been newly created by call above. 182 */ 183 if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE) 184 { 185 Info->ParentPackage = *ReturnObjectPtr; 186 Status = AcpiNsCheckPackage (Info, ReturnObjectPtr); 187 if (ACPI_FAILURE (Status)) 188 { 189 /* We might be able to fix some errors */ 190 191 if ((Status != AE_AML_OPERAND_TYPE) && 192 (Status != AE_AML_OPERAND_VALUE)) 193 { 194 goto Exit; 195 } 196 } 197 } 198 199 /* 200 * The return object was OK, or it was successfully repaired above. 201 * Now make some additional checks such as verifying that package 202 * objects are sorted correctly (if required) or buffer objects have 203 * the correct data width (bytes vs. dwords). These repairs are 204 * performed on a per-name basis, i.e., the code is specific to 205 * particular predefined names. 206 */ 207 Status = AcpiNsComplexRepairs (Info, Node, Status, ReturnObjectPtr); 208 209 Exit: 210 /* 211 * If the object validation failed or if we successfully repaired one 212 * or more objects, mark the parent node to suppress further warning 213 * messages during the next evaluation of the same method/object. 214 */ 215 if (ACPI_FAILURE (Status) || 216 (Info->ReturnFlags & ACPI_OBJECT_REPAIRED)) 217 { 218 Node->Flags |= ANOBJ_EVALUATED; 219 } 220 221 return_ACPI_STATUS (Status); 222 } 223 224 225 /******************************************************************************* 226 * 227 * FUNCTION: AcpiNsCheckObjectType 228 * 229 * PARAMETERS: Info - Method execution information block 230 * ReturnObjectPtr - Pointer to the object returned from the 231 * evaluation of a method or object 232 * ExpectedBtypes - Bitmap of expected return type(s) 233 * PackageIndex - Index of object within parent package (if 234 * applicable - ACPI_NOT_PACKAGE_ELEMENT 235 * otherwise) 236 * 237 * RETURN: Status 238 * 239 * DESCRIPTION: Check the type of the return object against the expected object 240 * type(s). Use of Btype allows multiple expected object types. 241 * 242 ******************************************************************************/ 243 244 ACPI_STATUS 245 AcpiNsCheckObjectType ( 246 ACPI_EVALUATE_INFO *Info, 247 ACPI_OPERAND_OBJECT **ReturnObjectPtr, 248 UINT32 ExpectedBtypes, 249 UINT32 PackageIndex) 250 { 251 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 252 ACPI_STATUS Status = AE_OK; 253 char TypeBuffer[96]; /* Room for 10 types */ 254 255 256 /* A Namespace node should not get here, but make sure */ 257 258 if (ReturnObject && 259 ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) 260 { 261 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 262 "Invalid return type - Found a Namespace node [%4.4s] type %s", 263 ReturnObject->Node.Name.Ascii, 264 AcpiUtGetTypeName (ReturnObject->Node.Type))); 265 return (AE_AML_OPERAND_TYPE); 266 } 267 268 /* 269 * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. 270 * The bitmapped type allows multiple possible return types. 271 * 272 * Note, the cases below must handle all of the possible types returned 273 * from all of the predefined names (including elements of returned 274 * packages) 275 */ 276 Info->ReturnBtype = AcpiNsGetBitmappedType (ReturnObject); 277 if (Info->ReturnBtype == ACPI_RTYPE_ANY) 278 { 279 /* Not one of the supported objects, must be incorrect */ 280 goto TypeErrorExit; 281 } 282 283 /* For reference objects, check that the reference type is correct */ 284 285 if ((Info->ReturnBtype & ExpectedBtypes) == ACPI_RTYPE_REFERENCE) 286 { 287 Status = AcpiNsCheckReference (Info, ReturnObject); 288 return (Status); 289 } 290 291 /* Attempt simple repair of the returned object if necessary */ 292 293 Status = AcpiNsSimpleRepair (Info, ExpectedBtypes, 294 PackageIndex, ReturnObjectPtr); 295 if (ACPI_SUCCESS (Status)) 296 { 297 return (AE_OK); /* Successful repair */ 298 } 299 300 301 TypeErrorExit: 302 303 /* Create a string with all expected types for this predefined object */ 304 305 AcpiUtGetExpectedReturnTypes (TypeBuffer, ExpectedBtypes); 306 307 if (!ReturnObject) 308 { 309 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 310 "Expected return object of type %s", 311 TypeBuffer)); 312 } 313 else if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) 314 { 315 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 316 "Return type mismatch - found %s, expected %s", 317 AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 318 } 319 else 320 { 321 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 322 "Return Package type mismatch at index %u - " 323 "found %s, expected %s", PackageIndex, 324 AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 325 } 326 327 return (AE_AML_OPERAND_TYPE); 328 } 329 330 331 /******************************************************************************* 332 * 333 * FUNCTION: AcpiNsCheckReference 334 * 335 * PARAMETERS: Info - Method execution information block 336 * ReturnObject - Object returned from the evaluation of a 337 * method or object 338 * 339 * RETURN: Status 340 * 341 * DESCRIPTION: Check a returned reference object for the correct reference 342 * type. The only reference type that can be returned from a 343 * predefined method is a named reference. All others are invalid. 344 * 345 ******************************************************************************/ 346 347 static ACPI_STATUS 348 AcpiNsCheckReference ( 349 ACPI_EVALUATE_INFO *Info, 350 ACPI_OPERAND_OBJECT *ReturnObject) 351 { 352 353 /* 354 * Check the reference object for the correct reference type (opcode). 355 * The only type of reference that can be converted to an ACPI_OBJECT is 356 * a reference to a named object (reference class: NAME) 357 */ 358 if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME) 359 { 360 return (AE_OK); 361 } 362 363 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 364 "Return type mismatch - unexpected reference object type [%s] %2.2X", 365 AcpiUtGetReferenceName (ReturnObject), 366 ReturnObject->Reference.Class)); 367 368 return (AE_AML_OPERAND_TYPE); 369 } 370 371 372 /******************************************************************************* 373 * 374 * FUNCTION: AcpiNsGetBitmappedType 375 * 376 * PARAMETERS: ReturnObject - Object returned from method/obj evaluation 377 * 378 * RETURN: Object return type. ACPI_RTYPE_ANY indicates that the object 379 * type is not supported. ACPI_RTYPE_NONE indicates that no 380 * object was returned (ReturnObject is NULL). 381 * 382 * DESCRIPTION: Convert object type into a bitmapped object return type. 383 * 384 ******************************************************************************/ 385 386 static UINT32 387 AcpiNsGetBitmappedType ( 388 ACPI_OPERAND_OBJECT *ReturnObject) 389 { 390 UINT32 ReturnBtype; 391 392 393 if (!ReturnObject) 394 { 395 return (ACPI_RTYPE_NONE); 396 } 397 398 /* Map ACPI_OBJECT_TYPE to internal bitmapped type */ 399 400 switch (ReturnObject->Common.Type) 401 { 402 case ACPI_TYPE_INTEGER: 403 404 ReturnBtype = ACPI_RTYPE_INTEGER; 405 break; 406 407 case ACPI_TYPE_BUFFER: 408 409 ReturnBtype = ACPI_RTYPE_BUFFER; 410 break; 411 412 case ACPI_TYPE_STRING: 413 414 ReturnBtype = ACPI_RTYPE_STRING; 415 break; 416 417 case ACPI_TYPE_PACKAGE: 418 419 ReturnBtype = ACPI_RTYPE_PACKAGE; 420 break; 421 422 case ACPI_TYPE_LOCAL_REFERENCE: 423 424 ReturnBtype = ACPI_RTYPE_REFERENCE; 425 break; 426 427 default: 428 429 /* Not one of the supported objects, must be incorrect */ 430 431 ReturnBtype = ACPI_RTYPE_ANY; 432 break; 433 } 434 435 return (ReturnBtype); 436 } 437