1 /****************************************************************************** 2 * 3 * Module Name: nsrepair - Repair for objects returned by predefined methods 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acnamesp.h" 47 #include "acinterp.h" 48 #include "acpredef.h" 49 #include "amlresrc.h" 50 51 #define _COMPONENT ACPI_NAMESPACE 52 ACPI_MODULE_NAME("nsrepair") 53 54 /******************************************************************************* 55 * 56 * This module attempts to repair or convert objects returned by the 57 * predefined methods to an object type that is expected, as per the ACPI 58 * specification. The need for this code is dictated by the many machines that 59 * return incorrect types for the standard predefined methods. Performing these 60 * conversions here, in one place, eliminates the need for individual ACPI 61 * device drivers to do the same. Note: Most of these conversions are different 62 * than the internal object conversion routines used for implicit object 63 * conversion. 64 * 65 * The following conversions can be performed as necessary: 66 * 67 * Integer -> String 68 * Integer -> Buffer 69 * String -> Integer 70 * String -> Buffer 71 * Buffer -> Integer 72 * Buffer -> String 73 * Buffer -> Package of Integers 74 * Package -> Package of one Package 75 * 76 * Additional conversions that are available: 77 * Convert a null return or zero return value to an end_tag descriptor 78 * Convert an ASCII string to a Unicode buffer 79 * 80 * An incorrect standalone object is wrapped with required outer package 81 * 82 * Additional possible repairs: 83 * Required package elements that are NULL replaced by Integer/String/Buffer 84 * 85 ******************************************************************************/ 86 /* Local prototypes */ 87 static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct 88 acpi_namespace_node 89 *node, 90 u32 91 return_btype, 92 u32 93 package_index); 94 95 /* 96 * Special but simple repairs for some names. 97 * 98 * 2nd argument: Unexpected types that can be repaired 99 */ 100 static const struct acpi_simple_repair_info acpi_object_repair_info[] = { 101 /* Resource descriptor conversions */ 102 103 {"_CRS", 104 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | 105 ACPI_RTYPE_NONE, 106 ACPI_NOT_PACKAGE_ELEMENT, 107 acpi_ns_convert_to_resource}, 108 {"_DMA", 109 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | 110 ACPI_RTYPE_NONE, 111 ACPI_NOT_PACKAGE_ELEMENT, 112 acpi_ns_convert_to_resource}, 113 {"_PRS", 114 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | 115 ACPI_RTYPE_NONE, 116 ACPI_NOT_PACKAGE_ELEMENT, 117 acpi_ns_convert_to_resource}, 118 119 /* Object reference conversions */ 120 121 {"_DEP", ACPI_RTYPE_STRING, ACPI_ALL_PACKAGE_ELEMENTS, 122 acpi_ns_convert_to_reference}, 123 124 /* Unicode conversions */ 125 126 {"_MLS", ACPI_RTYPE_STRING, 1, 127 acpi_ns_convert_to_unicode}, 128 {"_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 129 ACPI_NOT_PACKAGE_ELEMENT, 130 acpi_ns_convert_to_unicode}, 131 {{0, 0, 0, 0}, 0, 0, NULL} /* Table terminator */ 132 }; 133 134 /******************************************************************************* 135 * 136 * FUNCTION: acpi_ns_simple_repair 137 * 138 * PARAMETERS: info - Method execution information block 139 * expected_btypes - Object types expected 140 * package_index - Index of object within parent package (if 141 * applicable - ACPI_NOT_PACKAGE_ELEMENT 142 * otherwise) 143 * return_object_ptr - Pointer to the object returned from the 144 * evaluation of a method or object 145 * 146 * RETURN: Status. AE_OK if repair was successful. 147 * 148 * DESCRIPTION: Attempt to repair/convert a return object of a type that was 149 * not expected. 150 * 151 ******************************************************************************/ 152 153 acpi_status 154 acpi_ns_simple_repair(struct acpi_evaluate_info *info, 155 u32 expected_btypes, 156 u32 package_index, 157 union acpi_operand_object **return_object_ptr) 158 { 159 union acpi_operand_object *return_object = *return_object_ptr; 160 union acpi_operand_object *new_object = NULL; 161 acpi_status status; 162 const struct acpi_simple_repair_info *predefined; 163 164 ACPI_FUNCTION_NAME(ns_simple_repair); 165 166 /* 167 * Special repairs for certain names that are in the repair table. 168 * Check if this name is in the list of repairable names. 169 */ 170 predefined = acpi_ns_match_simple_repair(info->node, 171 info->return_btype, 172 package_index); 173 if (predefined) { 174 if (!return_object) { 175 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, 176 ACPI_WARN_ALWAYS, 177 "Missing expected return value")); 178 } 179 180 status = predefined->object_converter(info->node, return_object, 181 &new_object); 182 if (ACPI_FAILURE(status)) { 183 184 /* A fatal error occurred during a conversion */ 185 186 ACPI_EXCEPTION((AE_INFO, status, 187 "During return object analysis")); 188 return (status); 189 } 190 if (new_object) { 191 goto object_repaired; 192 } 193 } 194 195 /* 196 * Do not perform simple object repair unless the return type is not 197 * expected. 198 */ 199 if (info->return_btype & expected_btypes) { 200 return (AE_OK); 201 } 202 203 /* 204 * At this point, we know that the type of the returned object was not 205 * one of the expected types for this predefined name. Attempt to 206 * repair the object by converting it to one of the expected object 207 * types for this predefined name. 208 */ 209 210 /* 211 * If there is no return value, check if we require a return value for 212 * this predefined name. Either one return value is expected, or none, 213 * for both methods and other objects. 214 * 215 * Try to fix if there was no return object. Warning if failed to fix. 216 */ 217 if (!return_object) { 218 if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) { 219 if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { 220 ACPI_WARN_PREDEFINED((AE_INFO, 221 info->full_pathname, 222 ACPI_WARN_ALWAYS, 223 "Found unexpected NULL package element")); 224 225 status = 226 acpi_ns_repair_null_element(info, 227 expected_btypes, 228 package_index, 229 return_object_ptr); 230 if (ACPI_SUCCESS(status)) { 231 return (AE_OK); /* Repair was successful */ 232 } 233 } else { 234 ACPI_WARN_PREDEFINED((AE_INFO, 235 info->full_pathname, 236 ACPI_WARN_ALWAYS, 237 "Missing expected return value")); 238 } 239 240 return (AE_AML_NO_RETURN_VALUE); 241 } 242 } 243 244 if (expected_btypes & ACPI_RTYPE_INTEGER) { 245 status = acpi_ns_convert_to_integer(return_object, &new_object); 246 if (ACPI_SUCCESS(status)) { 247 goto object_repaired; 248 } 249 } 250 if (expected_btypes & ACPI_RTYPE_STRING) { 251 status = acpi_ns_convert_to_string(return_object, &new_object); 252 if (ACPI_SUCCESS(status)) { 253 goto object_repaired; 254 } 255 } 256 if (expected_btypes & ACPI_RTYPE_BUFFER) { 257 status = acpi_ns_convert_to_buffer(return_object, &new_object); 258 if (ACPI_SUCCESS(status)) { 259 goto object_repaired; 260 } 261 } 262 if (expected_btypes & ACPI_RTYPE_PACKAGE) { 263 /* 264 * A package is expected. We will wrap the existing object with a 265 * new package object. It is often the case that if a variable-length 266 * package is required, but there is only a single object needed, the 267 * BIOS will return that object instead of wrapping it with a Package 268 * object. Note: after the wrapping, the package will be validated 269 * for correct contents (expected object type or types). 270 */ 271 status = 272 acpi_ns_wrap_with_package(info, return_object, &new_object); 273 if (ACPI_SUCCESS(status)) { 274 /* 275 * The original object just had its reference count 276 * incremented for being inserted into the new package. 277 */ 278 *return_object_ptr = new_object; /* New Package object */ 279 info->return_flags |= ACPI_OBJECT_REPAIRED; 280 return (AE_OK); 281 } 282 } 283 284 /* We cannot repair this object */ 285 286 return (AE_AML_OPERAND_TYPE); 287 288 object_repaired: 289 290 /* Object was successfully repaired */ 291 292 if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { 293 294 /* Update reference count of new object */ 295 296 if (!(info->return_flags & ACPI_OBJECT_WRAPPED)) { 297 new_object->common.reference_count = 298 return_object->common.reference_count; 299 } 300 301 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 302 "%s: Converted %s to expected %s at Package index %u\n", 303 info->full_pathname, 304 acpi_ut_get_object_type_name(return_object), 305 acpi_ut_get_object_type_name(new_object), 306 package_index)); 307 } else { 308 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 309 "%s: Converted %s to expected %s\n", 310 info->full_pathname, 311 acpi_ut_get_object_type_name(return_object), 312 acpi_ut_get_object_type_name(new_object))); 313 } 314 315 /* Delete old object, install the new return object */ 316 317 acpi_ut_remove_reference(return_object); 318 *return_object_ptr = new_object; 319 info->return_flags |= ACPI_OBJECT_REPAIRED; 320 return (AE_OK); 321 } 322 323 /****************************************************************************** 324 * 325 * FUNCTION: acpi_ns_match_simple_repair 326 * 327 * PARAMETERS: node - Namespace node for the method/object 328 * return_btype - Object type that was returned 329 * package_index - Index of object within parent package (if 330 * applicable - ACPI_NOT_PACKAGE_ELEMENT 331 * otherwise) 332 * 333 * RETURN: Pointer to entry in repair table. NULL indicates not found. 334 * 335 * DESCRIPTION: Check an object name against the repairable object list. 336 * 337 *****************************************************************************/ 338 339 static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct 340 acpi_namespace_node 341 *node, 342 u32 343 return_btype, 344 u32 345 package_index) 346 { 347 const struct acpi_simple_repair_info *this_name; 348 349 /* Search info table for a repairable predefined method/object name */ 350 351 this_name = acpi_object_repair_info; 352 while (this_name->object_converter) { 353 if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) { 354 355 /* Check if we can actually repair this name/type combination */ 356 357 if ((return_btype & this_name->unexpected_btypes) && 358 (this_name->package_index == 359 ACPI_ALL_PACKAGE_ELEMENTS 360 || package_index == this_name->package_index)) { 361 return (this_name); 362 } 363 364 return (NULL); 365 } 366 367 this_name++; 368 } 369 370 return (NULL); /* Name was not found in the repair table */ 371 } 372 373 /******************************************************************************* 374 * 375 * FUNCTION: acpi_ns_repair_null_element 376 * 377 * PARAMETERS: info - Method execution information block 378 * expected_btypes - Object types expected 379 * package_index - Index of object within parent package (if 380 * applicable - ACPI_NOT_PACKAGE_ELEMENT 381 * otherwise) 382 * return_object_ptr - Pointer to the object returned from the 383 * evaluation of a method or object 384 * 385 * RETURN: Status. AE_OK if repair was successful. 386 * 387 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. 388 * 389 ******************************************************************************/ 390 391 acpi_status 392 acpi_ns_repair_null_element(struct acpi_evaluate_info *info, 393 u32 expected_btypes, 394 u32 package_index, 395 union acpi_operand_object **return_object_ptr) 396 { 397 union acpi_operand_object *return_object = *return_object_ptr; 398 union acpi_operand_object *new_object; 399 400 ACPI_FUNCTION_NAME(ns_repair_null_element); 401 402 /* No repair needed if return object is non-NULL */ 403 404 if (return_object) { 405 return (AE_OK); 406 } 407 408 /* 409 * Attempt to repair a NULL element of a Package object. This applies to 410 * predefined names that return a fixed-length package and each element 411 * is required. It does not apply to variable-length packages where NULL 412 * elements are allowed, especially at the end of the package. 413 */ 414 if (expected_btypes & ACPI_RTYPE_INTEGER) { 415 416 /* Need an integer - create a zero-value integer */ 417 418 new_object = acpi_ut_create_integer_object((u64)0); 419 } else if (expected_btypes & ACPI_RTYPE_STRING) { 420 421 /* Need a string - create a NULL string */ 422 423 new_object = acpi_ut_create_string_object(0); 424 } else if (expected_btypes & ACPI_RTYPE_BUFFER) { 425 426 /* Need a buffer - create a zero-length buffer */ 427 428 new_object = acpi_ut_create_buffer_object(0); 429 } else { 430 /* Error for all other expected types */ 431 432 return (AE_AML_OPERAND_TYPE); 433 } 434 435 if (!new_object) { 436 return (AE_NO_MEMORY); 437 } 438 439 /* Set the reference count according to the parent Package object */ 440 441 new_object->common.reference_count = 442 info->parent_package->common.reference_count; 443 444 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 445 "%s: Converted NULL package element to expected %s at index %u\n", 446 info->full_pathname, 447 acpi_ut_get_object_type_name(new_object), 448 package_index)); 449 450 *return_object_ptr = new_object; 451 info->return_flags |= ACPI_OBJECT_REPAIRED; 452 return (AE_OK); 453 } 454 455 /****************************************************************************** 456 * 457 * FUNCTION: acpi_ns_remove_null_elements 458 * 459 * PARAMETERS: info - Method execution information block 460 * package_type - An acpi_return_package_types value 461 * obj_desc - A Package object 462 * 463 * RETURN: None. 464 * 465 * DESCRIPTION: Remove all NULL package elements from packages that contain 466 * a variable number of subpackages. For these types of 467 * packages, NULL elements can be safely removed. 468 * 469 *****************************************************************************/ 470 471 void 472 acpi_ns_remove_null_elements(struct acpi_evaluate_info *info, 473 u8 package_type, 474 union acpi_operand_object *obj_desc) 475 { 476 union acpi_operand_object **source; 477 union acpi_operand_object **dest; 478 u32 count; 479 u32 new_count; 480 u32 i; 481 482 ACPI_FUNCTION_NAME(ns_remove_null_elements); 483 484 /* 485 * We can safely remove all NULL elements from these package types: 486 * PTYPE1_VAR packages contain a variable number of simple data types. 487 * PTYPE2 packages contain a variable number of subpackages. 488 */ 489 switch (package_type) { 490 case ACPI_PTYPE1_VAR: 491 case ACPI_PTYPE2: 492 case ACPI_PTYPE2_COUNT: 493 case ACPI_PTYPE2_PKG_COUNT: 494 case ACPI_PTYPE2_FIXED: 495 case ACPI_PTYPE2_MIN: 496 case ACPI_PTYPE2_REV_FIXED: 497 case ACPI_PTYPE2_FIX_VAR: 498 break; 499 500 default: 501 case ACPI_PTYPE2_VAR_VAR: 502 case ACPI_PTYPE1_FIXED: 503 case ACPI_PTYPE1_OPTION: 504 return; 505 } 506 507 count = obj_desc->package.count; 508 new_count = count; 509 510 source = obj_desc->package.elements; 511 dest = source; 512 513 /* Examine all elements of the package object, remove nulls */ 514 515 for (i = 0; i < count; i++) { 516 if (!*source) { 517 new_count--; 518 } else { 519 *dest = *source; 520 dest++; 521 } 522 523 source++; 524 } 525 526 /* Update parent package if any null elements were removed */ 527 528 if (new_count < count) { 529 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 530 "%s: Found and removed %u NULL elements\n", 531 info->full_pathname, (count - new_count))); 532 533 /* NULL terminate list and update the package count */ 534 535 *dest = NULL; 536 obj_desc->package.count = new_count; 537 } 538 } 539 540 /******************************************************************************* 541 * 542 * FUNCTION: acpi_ns_wrap_with_package 543 * 544 * PARAMETERS: info - Method execution information block 545 * original_object - Pointer to the object to repair. 546 * obj_desc_ptr - The new package object is returned here 547 * 548 * RETURN: Status, new object in *obj_desc_ptr 549 * 550 * DESCRIPTION: Repair a common problem with objects that are defined to 551 * return a variable-length Package of sub-objects. If there is 552 * only one sub-object, some BIOS code mistakenly simply declares 553 * the single object instead of a Package with one sub-object. 554 * This function attempts to repair this error by wrapping a 555 * Package object around the original object, creating the 556 * correct and expected Package with one sub-object. 557 * 558 * Names that can be repaired in this manner include: 559 * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, 560 * _BCL, _DOD, _FIX, _Sx 561 * 562 ******************************************************************************/ 563 564 acpi_status 565 acpi_ns_wrap_with_package(struct acpi_evaluate_info *info, 566 union acpi_operand_object *original_object, 567 union acpi_operand_object **obj_desc_ptr) 568 { 569 union acpi_operand_object *pkg_obj_desc; 570 571 ACPI_FUNCTION_NAME(ns_wrap_with_package); 572 573 /* 574 * Create the new outer package and populate it. The new 575 * package will have a single element, the lone sub-object. 576 */ 577 pkg_obj_desc = acpi_ut_create_package_object(1); 578 if (!pkg_obj_desc) { 579 return (AE_NO_MEMORY); 580 } 581 582 pkg_obj_desc->package.elements[0] = original_object; 583 584 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 585 "%s: Wrapped %s with expected Package object\n", 586 info->full_pathname, 587 acpi_ut_get_object_type_name(original_object))); 588 589 /* Return the new object in the object pointer */ 590 591 *obj_desc_ptr = pkg_obj_desc; 592 info->return_flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; 593 return (AE_OK); 594 } 595