psxface.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: psxface - Parser external interfaces
  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 "acdispat.h"
  13. #include "acinterp.h"
  14. #include "actables.h"
  15. #include "acnamesp.h"
  16. #define _COMPONENT ACPI_PARSER
  17. ACPI_MODULE_NAME("psxface")
  18. /* Local Prototypes */
  19. static void
  20. acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
  21. /*******************************************************************************
  22. *
  23. * FUNCTION: acpi_debug_trace
  24. *
  25. * PARAMETERS: method_name - Valid ACPI name string
  26. * debug_level - Optional level mask. 0 to use default
  27. * debug_layer - Optional layer mask. 0 to use default
  28. * flags - bit 1: one shot(1) or persistent(0)
  29. *
  30. * RETURN: Status
  31. *
  32. * DESCRIPTION: External interface to enable debug tracing during control
  33. * method execution
  34. *
  35. ******************************************************************************/
  36. acpi_status
  37. acpi_debug_trace(const char *name, u32 debug_level, u32 debug_layer, u32 flags)
  38. {
  39. acpi_status status;
  40. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  41. if (ACPI_FAILURE(status)) {
  42. return (status);
  43. }
  44. acpi_gbl_trace_method_name = name;
  45. acpi_gbl_trace_flags = flags;
  46. acpi_gbl_trace_dbg_level = debug_level;
  47. acpi_gbl_trace_dbg_layer = debug_layer;
  48. status = AE_OK;
  49. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  50. return (status);
  51. }
  52. /*******************************************************************************
  53. *
  54. * FUNCTION: acpi_ps_execute_method
  55. *
  56. * PARAMETERS: info - Method info block, contains:
  57. * node - Method Node to execute
  58. * obj_desc - Method object
  59. * parameters - List of parameters to pass to the method,
  60. * terminated by NULL. Params itself may be
  61. * NULL if no parameters are being passed.
  62. * return_object - Where to put method's return value (if
  63. * any). If NULL, no value is returned.
  64. * parameter_type - Type of Parameter list
  65. * return_object - Where to put method's return value (if
  66. * any). If NULL, no value is returned.
  67. * pass_number - Parse or execute pass
  68. *
  69. * RETURN: Status
  70. *
  71. * DESCRIPTION: Execute a control method
  72. *
  73. ******************************************************************************/
  74. acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
  75. {
  76. acpi_status status;
  77. union acpi_parse_object *op;
  78. struct acpi_walk_state *walk_state;
  79. ACPI_FUNCTION_TRACE(ps_execute_method);
  80. /* Quick validation of DSDT header */
  81. acpi_tb_check_dsdt_header();
  82. /* Validate the Info and method Node */
  83. if (!info || !info->node) {
  84. return_ACPI_STATUS(AE_NULL_ENTRY);
  85. }
  86. /* Init for new method, wait on concurrency semaphore */
  87. status =
  88. acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
  89. if (ACPI_FAILURE(status)) {
  90. return_ACPI_STATUS(status);
  91. }
  92. /*
  93. * The caller "owns" the parameters, so give each one an extra reference
  94. */
  95. acpi_ps_update_parameter_list(info, REF_INCREMENT);
  96. /*
  97. * Execute the method. Performs parse simultaneously
  98. */
  99. ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
  100. "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
  101. info->node->name.ascii, info->node, info->obj_desc));
  102. /* Create and init a Root Node */
  103. op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
  104. if (!op) {
  105. status = AE_NO_MEMORY;
  106. goto cleanup;
  107. }
  108. /* Create and initialize a new walk state */
  109. info->pass_number = ACPI_IMODE_EXECUTE;
  110. walk_state =
  111. acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
  112. NULL, NULL);
  113. if (!walk_state) {
  114. status = AE_NO_MEMORY;
  115. goto cleanup;
  116. }
  117. status = acpi_ds_init_aml_walk(walk_state, op, info->node,
  118. info->obj_desc->method.aml_start,
  119. info->obj_desc->method.aml_length, info,
  120. info->pass_number);
  121. if (ACPI_FAILURE(status)) {
  122. acpi_ds_delete_walk_state(walk_state);
  123. goto cleanup;
  124. }
  125. walk_state->method_pathname = info->full_pathname;
  126. walk_state->method_is_nested = FALSE;
  127. if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
  128. walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
  129. }
  130. /* Invoke an internal method if necessary */
  131. if (info->obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) {
  132. status =
  133. info->obj_desc->method.dispatch.implementation(walk_state);
  134. info->return_object = walk_state->return_desc;
  135. /* Cleanup states */
  136. acpi_ds_scope_stack_clear(walk_state);
  137. acpi_ps_cleanup_scope(&walk_state->parser_state);
  138. acpi_ds_terminate_control_method(walk_state->method_desc,
  139. walk_state);
  140. acpi_ds_delete_walk_state(walk_state);
  141. goto cleanup;
  142. }
  143. /*
  144. * Start method evaluation with an implicit return of zero.
  145. * This is done for Windows compatibility.
  146. */
  147. if (acpi_gbl_enable_interpreter_slack) {
  148. walk_state->implicit_return_obj =
  149. acpi_ut_create_integer_object((u64) 0);
  150. if (!walk_state->implicit_return_obj) {
  151. status = AE_NO_MEMORY;
  152. acpi_ds_delete_walk_state(walk_state);
  153. goto cleanup;
  154. }
  155. }
  156. /* Parse the AML */
  157. status = acpi_ps_parse_aml(walk_state);
  158. /* walk_state was deleted by parse_aml */
  159. cleanup:
  160. acpi_ps_delete_parse_tree(op);
  161. /* Take away the extra reference that we gave the parameters above */
  162. acpi_ps_update_parameter_list(info, REF_DECREMENT);
  163. /* Exit now if error above */
  164. if (ACPI_FAILURE(status)) {
  165. return_ACPI_STATUS(status);
  166. }
  167. /*
  168. * If the method has returned an object, signal this to the caller with
  169. * a control exception code
  170. */
  171. if (info->return_object) {
  172. ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
  173. info->return_object));
  174. ACPI_DUMP_STACK_ENTRY(info->return_object);
  175. status = AE_CTRL_RETURN_VALUE;
  176. }
  177. return_ACPI_STATUS(status);
  178. }
  179. /*******************************************************************************
  180. *
  181. * FUNCTION: acpi_ps_execute_table
  182. *
  183. * PARAMETERS: info - Method info block, contains:
  184. * node - Node to where the is entered into the
  185. * namespace
  186. * obj_desc - Pseudo method object describing the AML
  187. * code of the entire table
  188. * pass_number - Parse or execute pass
  189. *
  190. * RETURN: Status
  191. *
  192. * DESCRIPTION: Execute a table
  193. *
  194. ******************************************************************************/
  195. acpi_status acpi_ps_execute_table(struct acpi_evaluate_info *info)
  196. {
  197. acpi_status status;
  198. union acpi_parse_object *op = NULL;
  199. struct acpi_walk_state *walk_state = NULL;
  200. ACPI_FUNCTION_TRACE(ps_execute_table);
  201. /* Create and init a Root Node */
  202. op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
  203. if (!op) {
  204. status = AE_NO_MEMORY;
  205. goto cleanup;
  206. }
  207. /* Create and initialize a new walk state */
  208. walk_state =
  209. acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
  210. NULL, NULL);
  211. if (!walk_state) {
  212. status = AE_NO_MEMORY;
  213. goto cleanup;
  214. }
  215. status = acpi_ds_init_aml_walk(walk_state, op, info->node,
  216. info->obj_desc->method.aml_start,
  217. info->obj_desc->method.aml_length, info,
  218. info->pass_number);
  219. if (ACPI_FAILURE(status)) {
  220. goto cleanup;
  221. }
  222. walk_state->method_pathname = info->full_pathname;
  223. walk_state->method_is_nested = FALSE;
  224. if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
  225. walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
  226. }
  227. /* Info->Node is the default location to load the table */
  228. if (info->node && info->node != acpi_gbl_root_node) {
  229. status =
  230. acpi_ds_scope_stack_push(info->node, ACPI_TYPE_METHOD,
  231. walk_state);
  232. if (ACPI_FAILURE(status)) {
  233. goto cleanup;
  234. }
  235. }
  236. /*
  237. * Parse the AML, walk_state will be deleted by parse_aml
  238. */
  239. acpi_ex_enter_interpreter();
  240. status = acpi_ps_parse_aml(walk_state);
  241. acpi_ex_exit_interpreter();
  242. walk_state = NULL;
  243. cleanup:
  244. if (walk_state) {
  245. acpi_ds_delete_walk_state(walk_state);
  246. }
  247. if (op) {
  248. acpi_ps_delete_parse_tree(op);
  249. }
  250. return_ACPI_STATUS(status);
  251. }
  252. /*******************************************************************************
  253. *
  254. * FUNCTION: acpi_ps_update_parameter_list
  255. *
  256. * PARAMETERS: info - See struct acpi_evaluate_info
  257. * (Used: parameter_type and Parameters)
  258. * action - Add or Remove reference
  259. *
  260. * RETURN: Status
  261. *
  262. * DESCRIPTION: Update reference count on all method parameter objects
  263. *
  264. ******************************************************************************/
  265. static void
  266. acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
  267. {
  268. u32 i;
  269. if (info->parameters) {
  270. /* Update reference count for each parameter */
  271. for (i = 0; info->parameters[i]; i++) {
  272. /* Ignore errors, just do them all */
  273. (void)acpi_ut_update_object_reference(info->
  274. parameters[i],
  275. action);
  276. }
  277. }
  278. }