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