1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
4 * Module Name: exstoren - AML Interpreter object store support,
5 * Store to Node (namespace object)
7 * Copyright (C) 2000 - 2020, Intel Corp.
9 *****************************************************************************/
11 #include <acpi/acpi.h>
16 #define _COMPONENT ACPI_EXECUTER
17 ACPI_MODULE_NAME("exstoren")
19 /*******************************************************************************
21 * FUNCTION: acpi_ex_resolve_object
23 * PARAMETERS: source_desc_ptr - Pointer to the source object
24 * target_type - Current type of the target
25 * walk_state - Current walk state
27 * RETURN: Status, resolved object in source_desc_ptr.
29 * DESCRIPTION: Resolve an object. If the object is a reference, dereference
30 * it and return the actual object in the source_desc_ptr.
32 ******************************************************************************/
34 acpi_ex_resolve_object(union acpi_operand_object
**source_desc_ptr
,
35 acpi_object_type target_type
,
36 struct acpi_walk_state
*walk_state
)
38 union acpi_operand_object
*source_desc
= *source_desc_ptr
;
39 acpi_status status
= AE_OK
;
41 ACPI_FUNCTION_TRACE(ex_resolve_object
);
43 /* Ensure we have a Target that can be stored to */
45 switch (target_type
) {
46 case ACPI_TYPE_BUFFER_FIELD
:
47 case ACPI_TYPE_LOCAL_REGION_FIELD
:
48 case ACPI_TYPE_LOCAL_BANK_FIELD
:
49 case ACPI_TYPE_LOCAL_INDEX_FIELD
:
51 * These cases all require only Integers or values that
52 * can be converted to Integers (Strings or Buffers)
54 case ACPI_TYPE_INTEGER
:
55 case ACPI_TYPE_STRING
:
56 case ACPI_TYPE_BUFFER
:
58 * Stores into a Field/Region or into a Integer/Buffer/String
59 * are all essentially the same. This case handles the
60 * "interchangeable" types Integer, String, and Buffer.
62 if (source_desc
->common
.type
== ACPI_TYPE_LOCAL_REFERENCE
) {
64 /* Resolve a reference object first */
67 acpi_ex_resolve_to_value(source_desc_ptr
,
69 if (ACPI_FAILURE(status
)) {
74 /* For copy_object, no further validation necessary */
76 if (walk_state
->opcode
== AML_COPY_OBJECT_OP
) {
80 /* Must have a Integer, Buffer, or String */
82 if ((source_desc
->common
.type
!= ACPI_TYPE_INTEGER
) &&
83 (source_desc
->common
.type
!= ACPI_TYPE_BUFFER
) &&
84 (source_desc
->common
.type
!= ACPI_TYPE_STRING
) &&
85 !((source_desc
->common
.type
== ACPI_TYPE_LOCAL_REFERENCE
) &&
86 (source_desc
->reference
.class == ACPI_REFCLASS_TABLE
))) {
88 /* Conversion successful but still not a valid type */
91 "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)",
92 acpi_ut_get_object_type_name(source_desc
),
93 acpi_ut_get_type_name(target_type
)));
95 status
= AE_AML_OPERAND_TYPE
;
99 case ACPI_TYPE_LOCAL_ALIAS
:
100 case ACPI_TYPE_LOCAL_METHOD_ALIAS
:
102 * All aliases should have been resolved earlier, during the
103 * operand resolution phase.
105 ACPI_ERROR((AE_INFO
, "Store into an unresolved Alias object"));
106 status
= AE_AML_INTERNAL
;
109 case ACPI_TYPE_PACKAGE
:
112 * All other types than Alias and the various Fields come here,
113 * including the untyped case - ACPI_TYPE_ANY.
118 return_ACPI_STATUS(status
);
121 /*******************************************************************************
123 * FUNCTION: acpi_ex_store_object_to_object
125 * PARAMETERS: source_desc - Object to store
126 * dest_desc - Object to receive a copy of the source
127 * new_desc - New object if dest_desc is obsoleted
128 * walk_state - Current walk state
132 * DESCRIPTION: "Store" an object to another object. This may include
133 * converting the source type to the target type (implicit
134 * conversion), and a copy of the value of the source to
137 * The Assignment of an object to another (not named) object
139 * The Source passed in will replace the current value (if any)
140 * with the input value.
142 * When storing into an object the data is converted to the
143 * target object type then stored in the object. This means
144 * that the target object type (for an initialized target) will
145 * not be changed by a store operation.
147 * This module allows destination types of Number, String,
148 * Buffer, and Package.
150 * Assumes parameters are already validated. NOTE: source_desc
151 * resolution (from a reference object) must be performed by
152 * the caller if necessary.
154 ******************************************************************************/
157 acpi_ex_store_object_to_object(union acpi_operand_object
*source_desc
,
158 union acpi_operand_object
*dest_desc
,
159 union acpi_operand_object
**new_desc
,
160 struct acpi_walk_state
*walk_state
)
162 union acpi_operand_object
*actual_src_desc
;
163 acpi_status status
= AE_OK
;
165 ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_object
, source_desc
);
167 actual_src_desc
= source_desc
;
170 * There is no destination object (An uninitialized node or
171 * package element), so we can simply copy the source object
172 * creating a new destination object
175 acpi_ut_copy_iobject_to_iobject(actual_src_desc
, new_desc
,
177 return_ACPI_STATUS(status
);
180 if (source_desc
->common
.type
!= dest_desc
->common
.type
) {
182 * The source type does not match the type of the destination.
183 * Perform the "implicit conversion" of the source to the current type
184 * of the target as per the ACPI specification.
186 * If no conversion performed, actual_src_desc = source_desc.
187 * Otherwise, actual_src_desc is a temporary object to hold the
190 status
= acpi_ex_convert_to_target_type(dest_desc
->common
.type
,
194 if (ACPI_FAILURE(status
)) {
195 return_ACPI_STATUS(status
);
198 if (source_desc
== actual_src_desc
) {
200 * No conversion was performed. Return the source_desc as the
203 *new_desc
= source_desc
;
204 return_ACPI_STATUS(AE_OK
);
209 * We now have two objects of identical types, and we can perform a
210 * copy of the *value* of the source object.
212 switch (dest_desc
->common
.type
) {
213 case ACPI_TYPE_INTEGER
:
215 dest_desc
->integer
.value
= actual_src_desc
->integer
.value
;
217 /* Truncate value if we are executing from a 32-bit ACPI table */
219 (void)acpi_ex_truncate_for32bit_table(dest_desc
);
222 case ACPI_TYPE_STRING
:
225 acpi_ex_store_string_to_string(actual_src_desc
, dest_desc
);
228 case ACPI_TYPE_BUFFER
:
231 acpi_ex_store_buffer_to_buffer(actual_src_desc
, dest_desc
);
234 case ACPI_TYPE_PACKAGE
:
237 acpi_ut_copy_iobject_to_iobject(actual_src_desc
, &dest_desc
,
243 * All other types come here.
245 ACPI_WARNING((AE_INFO
, "Store into type [%s] not implemented",
246 acpi_ut_get_object_type_name(dest_desc
)));
248 status
= AE_NOT_IMPLEMENTED
;
252 if (actual_src_desc
!= source_desc
) {
254 /* Delete the intermediate (temporary) source object */
256 acpi_ut_remove_reference(actual_src_desc
);
259 *new_desc
= dest_desc
;
260 return_ACPI_STATUS(status
);