1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /****************************************************************************** 3 * 4 * Module Name: dspkginit - Completion of deferred package initialization 5 * 6 * Copyright (C) 2000 - 2018, Intel Corp. 7 * 8 *****************************************************************************/ 9 10 #include <acpi/acpi.h> 11 #include "accommon.h" 12 #include "acnamesp.h" 13 #include "amlcode.h" 14 #include "acdispat.h" 15 #include "acinterp.h" 16 #include "acparser.h" 17 18 #define _COMPONENT ACPI_NAMESPACE 19 ACPI_MODULE_NAME("dspkginit") 20 21 /* Local prototypes */ 22 static void 23 acpi_ds_resolve_package_element(union acpi_operand_object **element); 24 25 /******************************************************************************* 26 * 27 * FUNCTION: acpi_ds_build_internal_package_obj 28 * 29 * PARAMETERS: walk_state - Current walk state 30 * op - Parser object to be translated 31 * element_count - Number of elements in the package - this is 32 * the num_elements argument to Package() 33 * obj_desc_ptr - Where the ACPI internal object is returned 34 * 35 * RETURN: Status 36 * 37 * DESCRIPTION: Translate a parser Op package object to the equivalent 38 * namespace object 39 * 40 * NOTE: The number of elements in the package will be always be the num_elements 41 * count, regardless of the number of elements in the package list. If 42 * num_elements is smaller, only that many package list elements are used. 43 * if num_elements is larger, the Package object is padded out with 44 * objects of type Uninitialized (as per ACPI spec.) 45 * 46 * Even though the ASL compilers do not allow num_elements to be smaller 47 * than the Package list length (for the fixed length package opcode), some 48 * BIOS code modifies the AML on the fly to adjust the num_elements, and 49 * this code compensates for that. This also provides compatibility with 50 * other AML interpreters. 51 * 52 ******************************************************************************/ 53 54 acpi_status 55 acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, 56 union acpi_parse_object *op, 57 u32 element_count, 58 union acpi_operand_object **obj_desc_ptr) 59 { 60 union acpi_parse_object *arg; 61 union acpi_parse_object *parent; 62 union acpi_operand_object *obj_desc = NULL; 63 acpi_status status = AE_OK; 64 u8 module_level_code = FALSE; 65 u16 reference_count; 66 u32 index; 67 u32 i; 68 69 ACPI_FUNCTION_TRACE(ds_build_internal_package_obj); 70 71 /* Check if we are executing module level code */ 72 73 if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) { 74 module_level_code = TRUE; 75 } 76 77 /* Find the parent of a possibly nested package */ 78 79 parent = op->common.parent; 80 while ((parent->common.aml_opcode == AML_PACKAGE_OP) || 81 (parent->common.aml_opcode == AML_VARIABLE_PACKAGE_OP)) { 82 parent = parent->common.parent; 83 } 84 85 /* 86 * If we are evaluating a Named package object of the form: 87 * Name (xxxx, Package) 88 * the package object already exists, otherwise it must be created. 89 */ 90 obj_desc = *obj_desc_ptr; 91 if (!obj_desc) { 92 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE); 93 *obj_desc_ptr = obj_desc; 94 if (!obj_desc) { 95 return_ACPI_STATUS(AE_NO_MEMORY); 96 } 97 98 obj_desc->package.node = parent->common.node; 99 } 100 101 if (obj_desc->package.flags & AOPOBJ_DATA_VALID) { /* Just in case */ 102 return_ACPI_STATUS(AE_OK); 103 } 104 105 /* 106 * Allocate the element array (array of pointers to the individual 107 * objects) if necessary. the count is based on the num_elements 108 * parameter. Add an extra pointer slot so that the list is always 109 * null terminated. 110 */ 111 if (!obj_desc->package.elements) { 112 obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) 113 element_count 114 + 115 1) * 116 sizeof(void 117 *)); 118 119 if (!obj_desc->package.elements) { 120 acpi_ut_delete_object_desc(obj_desc); 121 return_ACPI_STATUS(AE_NO_MEMORY); 122 } 123 124 obj_desc->package.count = element_count; 125 } 126 127 /* First arg is element count. Second arg begins the initializer list */ 128 129 arg = op->common.value.arg; 130 arg = arg->common.next; 131 132 /* 133 * If we are executing module-level code, we will defer the 134 * full resolution of the package elements in order to support 135 * forward references from the elements. This provides 136 * compatibility with other ACPI implementations. 137 */ 138 if (module_level_code) { 139 obj_desc->package.aml_start = walk_state->aml; 140 obj_desc->package.aml_length = 0; 141 142 ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE, 143 "%s: Deferring resolution of Package elements\n", 144 ACPI_GET_FUNCTION_NAME)); 145 } 146 147 /* 148 * Initialize the elements of the package, up to the num_elements count. 149 * Package is automatically padded with uninitialized (NULL) elements 150 * if num_elements is greater than the package list length. Likewise, 151 * Package is truncated if num_elements is less than the list length. 152 */ 153 for (i = 0; arg && (i < element_count); i++) { 154 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { 155 if (arg->common.node->type == ACPI_TYPE_METHOD) { 156 /* 157 * A method reference "looks" to the parser to be a method 158 * invocation, so we special case it here 159 */ 160 arg->common.aml_opcode = AML_INT_NAMEPATH_OP; 161 status = 162 acpi_ds_build_internal_object(walk_state, 163 arg, 164 &obj_desc-> 165 package. 166 elements[i]); 167 } else { 168 /* This package element is already built, just get it */ 169 170 obj_desc->package.elements[i] = 171 ACPI_CAST_PTR(union acpi_operand_object, 172 arg->common.node); 173 } 174 } else { 175 status = 176 acpi_ds_build_internal_object(walk_state, arg, 177 &obj_desc->package. 178 elements[i]); 179 if (status == AE_NOT_FOUND) { 180 ACPI_ERROR((AE_INFO, "%-48s", 181 "****DS namepath not found")); 182 } 183 184 if (!module_level_code) { 185 /* 186 * Initialize this package element. This function handles the 187 * resolution of named references within the package. 188 * Forward references from module-level code are deferred 189 * until all ACPI tables are loaded. 190 */ 191 acpi_ds_init_package_element(0, 192 obj_desc->package. 193 elements[i], NULL, 194 &obj_desc->package. 195 elements[i]); 196 } 197 } 198 199 if (*obj_desc_ptr) { 200 201 /* Existing package, get existing reference count */ 202 203 reference_count = 204 (*obj_desc_ptr)->common.reference_count; 205 if (reference_count > 1) { 206 207 /* Make new element ref count match original ref count */ 208 /* TBD: Probably need an acpi_ut_add_references function */ 209 210 for (index = 0; 211 index < ((u32)reference_count - 1); 212 index++) { 213 acpi_ut_add_reference((obj_desc-> 214 package. 215 elements[i])); 216 } 217 } 218 } 219 220 arg = arg->common.next; 221 } 222 223 /* Check for match between num_elements and actual length of package_list */ 224 225 if (arg) { 226 /* 227 * num_elements was exhausted, but there are remaining elements in 228 * the package_list. Truncate the package to num_elements. 229 * 230 * Note: technically, this is an error, from ACPI spec: "It is an 231 * error for NumElements to be less than the number of elements in 232 * the PackageList". However, we just print a message and no 233 * exception is returned. This provides compatibility with other 234 * ACPI implementations. Some firmware implementations will alter 235 * the num_elements on the fly, possibly creating this type of 236 * ill-formed package object. 237 */ 238 while (arg) { 239 /* 240 * We must delete any package elements that were created earlier 241 * and are not going to be used because of the package truncation. 242 */ 243 if (arg->common.node) { 244 acpi_ut_remove_reference(ACPI_CAST_PTR 245 (union 246 acpi_operand_object, 247 arg->common.node)); 248 arg->common.node = NULL; 249 } 250 251 /* Find out how many elements there really are */ 252 253 i++; 254 arg = arg->common.next; 255 } 256 257 ACPI_INFO(("Actual Package length (%u) is larger than " 258 "NumElements field (%u), truncated", 259 i, element_count)); 260 } else if (i < element_count) { 261 /* 262 * Arg list (elements) was exhausted, but we did not reach 263 * num_elements count. 264 * 265 * Note: this is not an error, the package is padded out 266 * with NULLs as per the ACPI specification. 267 */ 268 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, 269 "%s: Package List length (%u) smaller than NumElements " 270 "count (%u), padded with null elements\n", 271 ACPI_GET_FUNCTION_NAME, i, 272 element_count)); 273 } 274 275 /* Module-level packages will be resolved later */ 276 277 if (!module_level_code) { 278 obj_desc->package.flags |= AOPOBJ_DATA_VALID; 279 } 280 281 op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc); 282 return_ACPI_STATUS(status); 283 } 284 285 /******************************************************************************* 286 * 287 * FUNCTION: acpi_ds_init_package_element 288 * 289 * PARAMETERS: acpi_pkg_callback 290 * 291 * RETURN: Status 292 * 293 * DESCRIPTION: Resolve a named reference element within a package object 294 * 295 ******************************************************************************/ 296 297 acpi_status 298 acpi_ds_init_package_element(u8 object_type, 299 union acpi_operand_object *source_object, 300 union acpi_generic_state *state, void *context) 301 { 302 union acpi_operand_object **element_ptr; 303 304 ACPI_FUNCTION_TRACE(ds_init_package_element); 305 306 if (!source_object) { 307 return_ACPI_STATUS(AE_OK); 308 } 309 310 /* 311 * The following code is a bit of a hack to workaround a (current) 312 * limitation of the acpi_pkg_callback interface. We need a pointer 313 * to the location within the element array because a new object 314 * may be created and stored there. 315 */ 316 if (context) { 317 318 /* A direct call was made to this function */ 319 320 element_ptr = (union acpi_operand_object **)context; 321 } else { 322 /* Call came from acpi_ut_walk_package_tree */ 323 324 element_ptr = state->pkg.this_target_obj; 325 } 326 327 /* We are only interested in reference objects/elements */ 328 329 if (source_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { 330 331 /* Attempt to resolve the (named) reference to a namespace node */ 332 333 acpi_ds_resolve_package_element(element_ptr); 334 } else if (source_object->common.type == ACPI_TYPE_PACKAGE) { 335 source_object->package.flags |= AOPOBJ_DATA_VALID; 336 } 337 338 return_ACPI_STATUS(AE_OK); 339 } 340 341 /******************************************************************************* 342 * 343 * FUNCTION: acpi_ds_resolve_package_element 344 * 345 * PARAMETERS: element_ptr - Pointer to a reference object 346 * 347 * RETURN: Possible new element is stored to the indirect element_ptr 348 * 349 * DESCRIPTION: Resolve a package element that is a reference to a named 350 * object. 351 * 352 ******************************************************************************/ 353 354 static void 355 acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr) 356 { 357 acpi_status status; 358 acpi_status status2; 359 union acpi_generic_state scope_info; 360 union acpi_operand_object *element = *element_ptr; 361 struct acpi_namespace_node *resolved_node; 362 struct acpi_namespace_node *original_node; 363 char *external_path = ""; 364 acpi_object_type type; 365 366 ACPI_FUNCTION_TRACE(ds_resolve_package_element); 367 368 /* Check if reference element is already resolved */ 369 370 if (element->reference.resolved) { 371 ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE, 372 "%s: Package element is already resolved\n", 373 ACPI_GET_FUNCTION_NAME)); 374 375 return_VOID; 376 } 377 378 /* Element must be a reference object of correct type */ 379 380 scope_info.scope.node = element->reference.node; /* Prefix node */ 381 382 status = acpi_ns_lookup(&scope_info, (char *)element->reference.aml, 383 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 384 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 385 NULL, &resolved_node); 386 if (ACPI_FAILURE(status)) { 387 if ((status == AE_NOT_FOUND) 388 && acpi_gbl_ignore_package_resolution_errors) { 389 /* 390 * Optionally be silent about the NOT_FOUND case for the referenced 391 * name. Although this is potentially a serious problem, 392 * it can generate a lot of noise/errors on platforms whose 393 * firmware carries around a bunch of unused Package objects. 394 * To disable these errors, set this global to TRUE: 395 * acpi_gbl_ignore_package_resolution_errors 396 * 397 * If the AML actually tries to use such a package, the unresolved 398 * element(s) will be replaced with NULL elements. 399 */ 400 401 /* Referenced name not found, set the element to NULL */ 402 403 acpi_ut_remove_reference(*element_ptr); 404 *element_ptr = NULL; 405 return_VOID; 406 } 407 408 status2 = acpi_ns_externalize_name(ACPI_UINT32_MAX, 409 (char *)element->reference. 410 aml, NULL, &external_path); 411 412 ACPI_EXCEPTION((AE_INFO, status, 413 "While resolving a named reference package element - %s", 414 external_path)); 415 if (ACPI_SUCCESS(status2)) { 416 ACPI_FREE(external_path); 417 } 418 419 /* Could not resolve name, set the element to NULL */ 420 421 acpi_ut_remove_reference(*element_ptr); 422 *element_ptr = NULL; 423 return_VOID; 424 } else if (resolved_node->type == ACPI_TYPE_ANY) { 425 426 /* Named reference not resolved, return a NULL package element */ 427 428 ACPI_ERROR((AE_INFO, 429 "Could not resolve named package element [%4.4s] in [%4.4s]", 430 resolved_node->name.ascii, 431 scope_info.scope.node->name.ascii)); 432 *element_ptr = NULL; 433 return_VOID; 434 } 435 436 /* 437 * Special handling for Alias objects. We need resolved_node to point 438 * to the Alias target. This effectively "resolves" the alias. 439 */ 440 if (resolved_node->type == ACPI_TYPE_LOCAL_ALIAS) { 441 resolved_node = ACPI_CAST_PTR(struct acpi_namespace_node, 442 resolved_node->object); 443 } 444 445 /* Update the reference object */ 446 447 element->reference.resolved = TRUE; 448 element->reference.node = resolved_node; 449 type = element->reference.node->type; 450 451 /* 452 * Attempt to resolve the node to a value before we insert it into 453 * the package. If this is a reference to a common data type, 454 * resolve it immediately. According to the ACPI spec, package 455 * elements can only be "data objects" or method references. 456 * Attempt to resolve to an Integer, Buffer, String or Package. 457 * If cannot, return the named reference (for things like Devices, 458 * Methods, etc.) Buffer Fields and Fields will resolve to simple 459 * objects (int/buf/str/pkg). 460 * 461 * NOTE: References to things like Devices, Methods, Mutexes, etc. 462 * will remain as named references. This behavior is not described 463 * in the ACPI spec, but it appears to be an oversight. 464 */ 465 original_node = resolved_node; 466 status = acpi_ex_resolve_node_to_value(&resolved_node, NULL); 467 if (ACPI_FAILURE(status)) { 468 return_VOID; 469 } 470 471 switch (type) { 472 /* 473 * These object types are a result of named references, so we will 474 * leave them as reference objects. In other words, these types 475 * have no intrinsic "value". 476 */ 477 case ACPI_TYPE_DEVICE: 478 case ACPI_TYPE_THERMAL: 479 case ACPI_TYPE_METHOD: 480 break; 481 482 case ACPI_TYPE_MUTEX: 483 case ACPI_TYPE_POWER: 484 case ACPI_TYPE_PROCESSOR: 485 case ACPI_TYPE_EVENT: 486 case ACPI_TYPE_REGION: 487 488 /* acpi_ex_resolve_node_to_value gave these an extra reference */ 489 490 acpi_ut_remove_reference(original_node->object); 491 break; 492 493 default: 494 /* 495 * For all other types - the node was resolved to an actual 496 * operand object with a value, return the object. Remove 497 * a reference on the existing object. 498 */ 499 acpi_ut_remove_reference(element); 500 *element_ptr = (union acpi_operand_object *)resolved_node; 501 break; 502 } 503 504 return_VOID; 505 } 506