dspkginit.c 15 KB

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