dsobject.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: dsobject - Dispatcher object management routines
  5. *
  6. * Copyright (C) 2000 - 2022, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #include "acparser.h"
  12. #include "amlcode.h"
  13. #include "acdispat.h"
  14. #include "acnamesp.h"
  15. #include "acinterp.h"
  16. #define _COMPONENT ACPI_DISPATCHER
  17. ACPI_MODULE_NAME("dsobject")
  18. /*******************************************************************************
  19. *
  20. * FUNCTION: acpi_ds_build_internal_object
  21. *
  22. * PARAMETERS: walk_state - Current walk state
  23. * op - Parser object to be translated
  24. * obj_desc_ptr - Where the ACPI internal object is returned
  25. *
  26. * RETURN: Status
  27. *
  28. * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
  29. * Simple objects are any objects other than a package object!
  30. *
  31. ******************************************************************************/
  32. acpi_status
  33. acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
  34. union acpi_parse_object *op,
  35. union acpi_operand_object **obj_desc_ptr)
  36. {
  37. union acpi_operand_object *obj_desc;
  38. acpi_status status;
  39. ACPI_FUNCTION_TRACE(ds_build_internal_object);
  40. *obj_desc_ptr = NULL;
  41. if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
  42. /*
  43. * This is a named object reference. If this name was
  44. * previously looked up in the namespace, it was stored in
  45. * this op. Otherwise, go ahead and look it up now
  46. */
  47. if (!op->common.node) {
  48. /* Check if we are resolving a named reference within a package */
  49. if ((op->common.parent->common.aml_opcode ==
  50. AML_PACKAGE_OP)
  51. || (op->common.parent->common.aml_opcode ==
  52. AML_VARIABLE_PACKAGE_OP)) {
  53. /*
  54. * We won't resolve package elements here, we will do this
  55. * after all ACPI tables are loaded into the namespace. This
  56. * behavior supports both forward references to named objects
  57. * and external references to objects in other tables.
  58. */
  59. goto create_new_object;
  60. } else {
  61. status = acpi_ns_lookup(walk_state->scope_info,
  62. op->common.value.string,
  63. ACPI_TYPE_ANY,
  64. ACPI_IMODE_EXECUTE,
  65. ACPI_NS_SEARCH_PARENT |
  66. ACPI_NS_DONT_OPEN_SCOPE,
  67. NULL,
  68. ACPI_CAST_INDIRECT_PTR
  69. (struct
  70. acpi_namespace_node,
  71. &(op->common.node)));
  72. if (ACPI_FAILURE(status)) {
  73. ACPI_ERROR_NAMESPACE(walk_state->
  74. scope_info,
  75. op->common.value.
  76. string, status);
  77. return_ACPI_STATUS(status);
  78. }
  79. }
  80. }
  81. }
  82. create_new_object:
  83. /* Create and init a new internal ACPI object */
  84. obj_desc = acpi_ut_create_internal_object((acpi_ps_get_opcode_info
  85. (op->common.aml_opcode))->
  86. object_type);
  87. if (!obj_desc) {
  88. return_ACPI_STATUS(AE_NO_MEMORY);
  89. }
  90. status =
  91. acpi_ds_init_object_from_op(walk_state, op, op->common.aml_opcode,
  92. &obj_desc);
  93. if (ACPI_FAILURE(status)) {
  94. acpi_ut_remove_reference(obj_desc);
  95. return_ACPI_STATUS(status);
  96. }
  97. /*
  98. * Handling for unresolved package reference elements.
  99. * These are elements that are namepaths.
  100. */
  101. if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
  102. (op->common.parent->common.aml_opcode == AML_VARIABLE_PACKAGE_OP)) {
  103. obj_desc->reference.resolved = TRUE;
  104. if ((op->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
  105. !obj_desc->reference.node) {
  106. /*
  107. * Name was unresolved above.
  108. * Get the prefix node for later lookup
  109. */
  110. obj_desc->reference.node =
  111. walk_state->scope_info->scope.node;
  112. obj_desc->reference.aml = op->common.aml;
  113. obj_desc->reference.resolved = FALSE;
  114. }
  115. }
  116. *obj_desc_ptr = obj_desc;
  117. return_ACPI_STATUS(status);
  118. }
  119. /*******************************************************************************
  120. *
  121. * FUNCTION: acpi_ds_build_internal_buffer_obj
  122. *
  123. * PARAMETERS: walk_state - Current walk state
  124. * op - Parser object to be translated
  125. * buffer_length - Length of the buffer
  126. * obj_desc_ptr - Where the ACPI internal object is returned
  127. *
  128. * RETURN: Status
  129. *
  130. * DESCRIPTION: Translate a parser Op package object to the equivalent
  131. * namespace object
  132. *
  133. ******************************************************************************/
  134. acpi_status
  135. acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
  136. union acpi_parse_object *op,
  137. u32 buffer_length,
  138. union acpi_operand_object **obj_desc_ptr)
  139. {
  140. union acpi_parse_object *arg;
  141. union acpi_operand_object *obj_desc;
  142. union acpi_parse_object *byte_list;
  143. u32 byte_list_length = 0;
  144. ACPI_FUNCTION_TRACE(ds_build_internal_buffer_obj);
  145. /*
  146. * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
  147. * The buffer object already exists (from the NS node), otherwise it must
  148. * be created.
  149. */
  150. obj_desc = *obj_desc_ptr;
  151. if (!obj_desc) {
  152. /* Create a new buffer object */
  153. obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
  154. *obj_desc_ptr = obj_desc;
  155. if (!obj_desc) {
  156. return_ACPI_STATUS(AE_NO_MEMORY);
  157. }
  158. }
  159. /*
  160. * Second arg is the buffer data (optional) byte_list can be either
  161. * individual bytes or a string initializer. In either case, a
  162. * byte_list appears in the AML.
  163. */
  164. arg = op->common.value.arg; /* skip first arg */
  165. byte_list = arg->named.next;
  166. if (byte_list) {
  167. if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) {
  168. ACPI_ERROR((AE_INFO,
  169. "Expecting bytelist, found AML opcode 0x%X in op %p",
  170. byte_list->common.aml_opcode, byte_list));
  171. acpi_ut_remove_reference(obj_desc);
  172. return (AE_TYPE);
  173. }
  174. byte_list_length = (u32) byte_list->common.value.integer;
  175. }
  176. /*
  177. * The buffer length (number of bytes) will be the larger of:
  178. * 1) The specified buffer length and
  179. * 2) The length of the initializer byte list
  180. */
  181. obj_desc->buffer.length = buffer_length;
  182. if (byte_list_length > buffer_length) {
  183. obj_desc->buffer.length = byte_list_length;
  184. }
  185. /* Allocate the buffer */
  186. if (obj_desc->buffer.length == 0) {
  187. obj_desc->buffer.pointer = NULL;
  188. ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  189. "Buffer defined with zero length in AML, creating\n"));
  190. } else {
  191. obj_desc->buffer.pointer =
  192. ACPI_ALLOCATE_ZEROED(obj_desc->buffer.length);
  193. if (!obj_desc->buffer.pointer) {
  194. acpi_ut_delete_object_desc(obj_desc);
  195. return_ACPI_STATUS(AE_NO_MEMORY);
  196. }
  197. /* Initialize buffer from the byte_list (if present) */
  198. if (byte_list) {
  199. memcpy(obj_desc->buffer.pointer, byte_list->named.data,
  200. byte_list_length);
  201. }
  202. }
  203. obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
  204. op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
  205. return_ACPI_STATUS(AE_OK);
  206. }
  207. /*******************************************************************************
  208. *
  209. * FUNCTION: acpi_ds_create_node
  210. *
  211. * PARAMETERS: walk_state - Current walk state
  212. * node - NS Node to be initialized
  213. * op - Parser object to be translated
  214. *
  215. * RETURN: Status
  216. *
  217. * DESCRIPTION: Create the object to be associated with a namespace node
  218. *
  219. ******************************************************************************/
  220. acpi_status
  221. acpi_ds_create_node(struct acpi_walk_state *walk_state,
  222. struct acpi_namespace_node *node,
  223. union acpi_parse_object *op)
  224. {
  225. acpi_status status;
  226. union acpi_operand_object *obj_desc;
  227. ACPI_FUNCTION_TRACE_PTR(ds_create_node, op);
  228. /*
  229. * Because of the execution pass through the non-control-method
  230. * parts of the table, we can arrive here twice. Only init
  231. * the named object node the first time through
  232. */
  233. if (acpi_ns_get_attached_object(node)) {
  234. return_ACPI_STATUS(AE_OK);
  235. }
  236. if (!op->common.value.arg) {
  237. /* No arguments, there is nothing to do */
  238. return_ACPI_STATUS(AE_OK);
  239. }
  240. /* Build an internal object for the argument(s) */
  241. status =
  242. acpi_ds_build_internal_object(walk_state, op->common.value.arg,
  243. &obj_desc);
  244. if (ACPI_FAILURE(status)) {
  245. return_ACPI_STATUS(status);
  246. }
  247. /* Re-type the object according to its argument */
  248. node->type = obj_desc->common.type;
  249. /* Attach obj to node */
  250. status = acpi_ns_attach_object(node, obj_desc, node->type);
  251. /* Remove local reference to the object */
  252. acpi_ut_remove_reference(obj_desc);
  253. return_ACPI_STATUS(status);
  254. }
  255. /*******************************************************************************
  256. *
  257. * FUNCTION: acpi_ds_init_object_from_op
  258. *
  259. * PARAMETERS: walk_state - Current walk state
  260. * op - Parser op used to init the internal object
  261. * opcode - AML opcode associated with the object
  262. * ret_obj_desc - Namespace object to be initialized
  263. *
  264. * RETURN: Status
  265. *
  266. * DESCRIPTION: Initialize a namespace object from a parser Op and its
  267. * associated arguments. The namespace object is a more compact
  268. * representation of the Op and its arguments.
  269. *
  270. ******************************************************************************/
  271. acpi_status
  272. acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
  273. union acpi_parse_object *op,
  274. u16 opcode,
  275. union acpi_operand_object **ret_obj_desc)
  276. {
  277. const struct acpi_opcode_info *op_info;
  278. union acpi_operand_object *obj_desc;
  279. acpi_status status = AE_OK;
  280. ACPI_FUNCTION_TRACE(ds_init_object_from_op);
  281. obj_desc = *ret_obj_desc;
  282. op_info = acpi_ps_get_opcode_info(opcode);
  283. if (op_info->class == AML_CLASS_UNKNOWN) {
  284. /* Unknown opcode */
  285. return_ACPI_STATUS(AE_TYPE);
  286. }
  287. /* Perform per-object initialization */
  288. switch (obj_desc->common.type) {
  289. case ACPI_TYPE_BUFFER:
  290. /*
  291. * Defer evaluation of Buffer term_arg operand
  292. */
  293. obj_desc->buffer.node =
  294. ACPI_CAST_PTR(struct acpi_namespace_node,
  295. walk_state->operands[0]);
  296. obj_desc->buffer.aml_start = op->named.data;
  297. obj_desc->buffer.aml_length = op->named.length;
  298. break;
  299. case ACPI_TYPE_PACKAGE:
  300. /*
  301. * Defer evaluation of Package term_arg operand and all
  302. * package elements. (01/2017): We defer the element
  303. * resolution to allow forward references from the package
  304. * in order to provide compatibility with other ACPI
  305. * implementations.
  306. */
  307. obj_desc->package.node =
  308. ACPI_CAST_PTR(struct acpi_namespace_node,
  309. walk_state->operands[0]);
  310. if (!op->named.data) {
  311. return_ACPI_STATUS(AE_OK);
  312. }
  313. obj_desc->package.aml_start = op->named.data;
  314. obj_desc->package.aml_length = op->named.length;
  315. break;
  316. case ACPI_TYPE_INTEGER:
  317. switch (op_info->type) {
  318. case AML_TYPE_CONSTANT:
  319. /*
  320. * Resolve AML Constants here - AND ONLY HERE!
  321. * All constants are integers.
  322. * We mark the integer with a flag that indicates that it started
  323. * life as a constant -- so that stores to constants will perform
  324. * as expected (noop). zero_op is used as a placeholder for optional
  325. * target operands.
  326. */
  327. obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
  328. switch (opcode) {
  329. case AML_ZERO_OP:
  330. obj_desc->integer.value = 0;
  331. break;
  332. case AML_ONE_OP:
  333. obj_desc->integer.value = 1;
  334. break;
  335. case AML_ONES_OP:
  336. obj_desc->integer.value = ACPI_UINT64_MAX;
  337. /* Truncate value if we are executing from a 32-bit ACPI table */
  338. (void)acpi_ex_truncate_for32bit_table(obj_desc);
  339. break;
  340. case AML_REVISION_OP:
  341. obj_desc->integer.value = ACPI_CA_VERSION;
  342. break;
  343. default:
  344. ACPI_ERROR((AE_INFO,
  345. "Unknown constant opcode 0x%X",
  346. opcode));
  347. status = AE_AML_OPERAND_TYPE;
  348. break;
  349. }
  350. break;
  351. case AML_TYPE_LITERAL:
  352. obj_desc->integer.value = op->common.value.integer;
  353. if (acpi_ex_truncate_for32bit_table(obj_desc)) {
  354. /* Warn if we found a 64-bit constant in a 32-bit table */
  355. ACPI_WARNING((AE_INFO,
  356. "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",
  357. ACPI_FORMAT_UINT64(op->common.
  358. value.integer),
  359. (u32)obj_desc->integer.value));
  360. }
  361. break;
  362. default:
  363. ACPI_ERROR((AE_INFO, "Unknown Integer type 0x%X",
  364. op_info->type));
  365. status = AE_AML_OPERAND_TYPE;
  366. break;
  367. }
  368. break;
  369. case ACPI_TYPE_STRING:
  370. obj_desc->string.pointer = op->common.value.string;
  371. obj_desc->string.length = (u32)strlen(op->common.value.string);
  372. /*
  373. * The string is contained in the ACPI table, don't ever try
  374. * to delete it
  375. */
  376. obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
  377. break;
  378. case ACPI_TYPE_METHOD:
  379. break;
  380. case ACPI_TYPE_LOCAL_REFERENCE:
  381. switch (op_info->type) {
  382. case AML_TYPE_LOCAL_VARIABLE:
  383. /* Local ID (0-7) is (AML opcode - base AML_FIRST_LOCAL_OP) */
  384. obj_desc->reference.value =
  385. ((u32)opcode) - AML_FIRST_LOCAL_OP;
  386. obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
  387. status =
  388. acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL,
  389. obj_desc->reference.
  390. value, walk_state,
  391. ACPI_CAST_INDIRECT_PTR
  392. (struct
  393. acpi_namespace_node,
  394. &obj_desc->reference.
  395. object));
  396. break;
  397. case AML_TYPE_METHOD_ARGUMENT:
  398. /* Arg ID (0-6) is (AML opcode - base AML_FIRST_ARG_OP) */
  399. obj_desc->reference.value =
  400. ((u32)opcode) - AML_FIRST_ARG_OP;
  401. obj_desc->reference.class = ACPI_REFCLASS_ARG;
  402. status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG,
  403. obj_desc->
  404. reference.value,
  405. walk_state,
  406. ACPI_CAST_INDIRECT_PTR
  407. (struct
  408. acpi_namespace_node,
  409. &obj_desc->
  410. reference.
  411. object));
  412. break;
  413. default: /* Object name or Debug object */
  414. switch (op->common.aml_opcode) {
  415. case AML_INT_NAMEPATH_OP:
  416. /* Node was saved in Op */
  417. obj_desc->reference.node = op->common.node;
  418. obj_desc->reference.class = ACPI_REFCLASS_NAME;
  419. if (op->common.node) {
  420. obj_desc->reference.object =
  421. op->common.node->object;
  422. }
  423. break;
  424. case AML_DEBUG_OP:
  425. obj_desc->reference.class = ACPI_REFCLASS_DEBUG;
  426. break;
  427. default:
  428. ACPI_ERROR((AE_INFO,
  429. "Unimplemented reference type for AML opcode: 0x%4.4X",
  430. opcode));
  431. return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
  432. }
  433. break;
  434. }
  435. break;
  436. default:
  437. ACPI_ERROR((AE_INFO, "Unimplemented data type: 0x%X",
  438. obj_desc->common.type));
  439. status = AE_AML_OPERAND_TYPE;
  440. break;
  441. }
  442. return_ACPI_STATUS(status);
  443. }