exstoren.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: exstoren - AML Interpreter object store support,
  5. * Store to Node (namespace object)
  6. *
  7. * Copyright (C) 2000 - 2022, Intel Corp.
  8. *
  9. *****************************************************************************/
  10. #include <acpi/acpi.h>
  11. #include "accommon.h"
  12. #include "acinterp.h"
  13. #include "amlcode.h"
  14. #define _COMPONENT ACPI_EXECUTER
  15. ACPI_MODULE_NAME("exstoren")
  16. /*******************************************************************************
  17. *
  18. * FUNCTION: acpi_ex_resolve_object
  19. *
  20. * PARAMETERS: source_desc_ptr - Pointer to the source object
  21. * target_type - Current type of the target
  22. * walk_state - Current walk state
  23. *
  24. * RETURN: Status, resolved object in source_desc_ptr.
  25. *
  26. * DESCRIPTION: Resolve an object. If the object is a reference, dereference
  27. * it and return the actual object in the source_desc_ptr.
  28. *
  29. ******************************************************************************/
  30. acpi_status
  31. acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
  32. acpi_object_type target_type,
  33. struct acpi_walk_state *walk_state)
  34. {
  35. union acpi_operand_object *source_desc = *source_desc_ptr;
  36. acpi_status status = AE_OK;
  37. ACPI_FUNCTION_TRACE(ex_resolve_object);
  38. /* Ensure we have a Target that can be stored to */
  39. switch (target_type) {
  40. case ACPI_TYPE_BUFFER_FIELD:
  41. case ACPI_TYPE_LOCAL_REGION_FIELD:
  42. case ACPI_TYPE_LOCAL_BANK_FIELD:
  43. case ACPI_TYPE_LOCAL_INDEX_FIELD:
  44. /*
  45. * These cases all require only Integers or values that
  46. * can be converted to Integers (Strings or Buffers)
  47. */
  48. case ACPI_TYPE_INTEGER:
  49. case ACPI_TYPE_STRING:
  50. case ACPI_TYPE_BUFFER:
  51. /*
  52. * Stores into a Field/Region or into a Integer/Buffer/String
  53. * are all essentially the same. This case handles the
  54. * "interchangeable" types Integer, String, and Buffer.
  55. */
  56. if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
  57. /* Resolve a reference object first */
  58. status =
  59. acpi_ex_resolve_to_value(source_desc_ptr,
  60. walk_state);
  61. if (ACPI_FAILURE(status)) {
  62. break;
  63. }
  64. }
  65. /* For copy_object, no further validation necessary */
  66. if (walk_state->opcode == AML_COPY_OBJECT_OP) {
  67. break;
  68. }
  69. /* Must have a Integer, Buffer, or String */
  70. if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
  71. (source_desc->common.type != ACPI_TYPE_BUFFER) &&
  72. (source_desc->common.type != ACPI_TYPE_STRING) &&
  73. !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
  74. (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
  75. /* Conversion successful but still not a valid type */
  76. ACPI_ERROR((AE_INFO,
  77. "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)",
  78. acpi_ut_get_object_type_name(source_desc),
  79. acpi_ut_get_type_name(target_type)));
  80. status = AE_AML_OPERAND_TYPE;
  81. }
  82. break;
  83. case ACPI_TYPE_LOCAL_ALIAS:
  84. case ACPI_TYPE_LOCAL_METHOD_ALIAS:
  85. /*
  86. * All aliases should have been resolved earlier, during the
  87. * operand resolution phase.
  88. */
  89. ACPI_ERROR((AE_INFO, "Store into an unresolved Alias object"));
  90. status = AE_AML_INTERNAL;
  91. break;
  92. case ACPI_TYPE_PACKAGE:
  93. default:
  94. /*
  95. * All other types than Alias and the various Fields come here,
  96. * including the untyped case - ACPI_TYPE_ANY.
  97. */
  98. break;
  99. }
  100. return_ACPI_STATUS(status);
  101. }
  102. /*******************************************************************************
  103. *
  104. * FUNCTION: acpi_ex_store_object_to_object
  105. *
  106. * PARAMETERS: source_desc - Object to store
  107. * dest_desc - Object to receive a copy of the source
  108. * new_desc - New object if dest_desc is obsoleted
  109. * walk_state - Current walk state
  110. *
  111. * RETURN: Status
  112. *
  113. * DESCRIPTION: "Store" an object to another object. This may include
  114. * converting the source type to the target type (implicit
  115. * conversion), and a copy of the value of the source to
  116. * the target.
  117. *
  118. * The Assignment of an object to another (not named) object
  119. * is handled here.
  120. * The Source passed in will replace the current value (if any)
  121. * with the input value.
  122. *
  123. * When storing into an object the data is converted to the
  124. * target object type then stored in the object. This means
  125. * that the target object type (for an initialized target) will
  126. * not be changed by a store operation.
  127. *
  128. * This module allows destination types of Number, String,
  129. * Buffer, and Package.
  130. *
  131. * Assumes parameters are already validated. NOTE: source_desc
  132. * resolution (from a reference object) must be performed by
  133. * the caller if necessary.
  134. *
  135. ******************************************************************************/
  136. acpi_status
  137. acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
  138. union acpi_operand_object *dest_desc,
  139. union acpi_operand_object **new_desc,
  140. struct acpi_walk_state *walk_state)
  141. {
  142. union acpi_operand_object *actual_src_desc;
  143. acpi_status status = AE_OK;
  144. ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_object, source_desc);
  145. actual_src_desc = source_desc;
  146. if (!dest_desc) {
  147. /*
  148. * There is no destination object (An uninitialized node or
  149. * package element), so we can simply copy the source object
  150. * creating a new destination object
  151. */
  152. status =
  153. acpi_ut_copy_iobject_to_iobject(actual_src_desc, new_desc,
  154. walk_state);
  155. return_ACPI_STATUS(status);
  156. }
  157. if (source_desc->common.type != dest_desc->common.type) {
  158. /*
  159. * The source type does not match the type of the destination.
  160. * Perform the "implicit conversion" of the source to the current type
  161. * of the target as per the ACPI specification.
  162. *
  163. * If no conversion performed, actual_src_desc = source_desc.
  164. * Otherwise, actual_src_desc is a temporary object to hold the
  165. * converted object.
  166. */
  167. status = acpi_ex_convert_to_target_type(dest_desc->common.type,
  168. source_desc,
  169. &actual_src_desc,
  170. walk_state);
  171. if (ACPI_FAILURE(status)) {
  172. return_ACPI_STATUS(status);
  173. }
  174. if (source_desc == actual_src_desc) {
  175. /*
  176. * No conversion was performed. Return the source_desc as the
  177. * new object.
  178. */
  179. *new_desc = source_desc;
  180. return_ACPI_STATUS(AE_OK);
  181. }
  182. }
  183. /*
  184. * We now have two objects of identical types, and we can perform a
  185. * copy of the *value* of the source object.
  186. */
  187. switch (dest_desc->common.type) {
  188. case ACPI_TYPE_INTEGER:
  189. dest_desc->integer.value = actual_src_desc->integer.value;
  190. /* Truncate value if we are executing from a 32-bit ACPI table */
  191. (void)acpi_ex_truncate_for32bit_table(dest_desc);
  192. break;
  193. case ACPI_TYPE_STRING:
  194. status =
  195. acpi_ex_store_string_to_string(actual_src_desc, dest_desc);
  196. break;
  197. case ACPI_TYPE_BUFFER:
  198. status =
  199. acpi_ex_store_buffer_to_buffer(actual_src_desc, dest_desc);
  200. break;
  201. case ACPI_TYPE_PACKAGE:
  202. status =
  203. acpi_ut_copy_iobject_to_iobject(actual_src_desc, &dest_desc,
  204. walk_state);
  205. break;
  206. default:
  207. /*
  208. * All other types come here.
  209. */
  210. ACPI_WARNING((AE_INFO, "Store into type [%s] not implemented",
  211. acpi_ut_get_object_type_name(dest_desc)));
  212. status = AE_NOT_IMPLEMENTED;
  213. break;
  214. }
  215. if (actual_src_desc != source_desc) {
  216. /* Delete the intermediate (temporary) source object */
  217. acpi_ut_remove_reference(actual_src_desc);
  218. }
  219. *new_desc = dest_desc;
  220. return_ACPI_STATUS(status);
  221. }