Branch data Line data Source code
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 - 2020, Intel Corp.
8 : : *
9 : : *****************************************************************************/
10 : :
11 : : #include <acpi/acpi.h>
12 : : #include "accommon.h"
13 : : #include "acinterp.h"
14 : : #include "amlcode.h"
15 : :
16 : : #define _COMPONENT ACPI_EXECUTER
17 : : ACPI_MODULE_NAME("exstoren")
18 : :
19 : : /*******************************************************************************
20 : : *
21 : : * FUNCTION: acpi_ex_resolve_object
22 : : *
23 : : * PARAMETERS: source_desc_ptr - Pointer to the source object
24 : : * target_type - Current type of the target
25 : : * walk_state - Current walk state
26 : : *
27 : : * RETURN: Status, resolved object in source_desc_ptr.
28 : : *
29 : : * DESCRIPTION: Resolve an object. If the object is a reference, dereference
30 : : * it and return the actual object in the source_desc_ptr.
31 : : *
32 : : ******************************************************************************/
33 : : acpi_status
34 : 510 : acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
35 : : acpi_object_type target_type,
36 : : struct acpi_walk_state *walk_state)
37 : : {
38 : 510 : union acpi_operand_object *source_desc = *source_desc_ptr;
39 : 510 : acpi_status status = AE_OK;
40 : :
41 : 510 : ACPI_FUNCTION_TRACE(ex_resolve_object);
42 : :
43 : : /* Ensure we have a Target that can be stored to */
44 : :
45 [ + - - ]: 510 : switch (target_type) {
46 : 510 : 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:
50 : : /*
51 : : * These cases all require only Integers or values that
52 : : * can be converted to Integers (Strings or Buffers)
53 : : */
54 : : case ACPI_TYPE_INTEGER:
55 : : case ACPI_TYPE_STRING:
56 : : case ACPI_TYPE_BUFFER:
57 : : /*
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.
61 : : */
62 [ - + ]: 510 : if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
63 : :
64 : : /* Resolve a reference object first */
65 : :
66 : 0 : status =
67 : 0 : acpi_ex_resolve_to_value(source_desc_ptr,
68 : : walk_state);
69 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
70 : : break;
71 : : }
72 : : }
73 : :
74 : : /* For copy_object, no further validation necessary */
75 : :
76 [ - + ]: 510 : if (walk_state->opcode == AML_COPY_OBJECT_OP) {
77 : : break;
78 : : }
79 : :
80 : : /* Must have a Integer, Buffer, or String */
81 : :
82 [ - + ]: 510 : if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
83 [ # # ]: 0 : (source_desc->common.type != ACPI_TYPE_BUFFER) &&
84 : 0 : (source_desc->common.type != ACPI_TYPE_STRING) &&
85 [ # # ]: 0 : !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
86 : : (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
87 : :
88 : : /* Conversion successful but still not a valid type */
89 : :
90 : 0 : ACPI_ERROR((AE_INFO,
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)));
94 : :
95 : 0 : status = AE_AML_OPERAND_TYPE;
96 : : }
97 : : break;
98 : :
99 : 0 : case ACPI_TYPE_LOCAL_ALIAS:
100 : : case ACPI_TYPE_LOCAL_METHOD_ALIAS:
101 : : /*
102 : : * All aliases should have been resolved earlier, during the
103 : : * operand resolution phase.
104 : : */
105 : 0 : ACPI_ERROR((AE_INFO, "Store into an unresolved Alias object"));
106 : 0 : status = AE_AML_INTERNAL;
107 : 0 : break;
108 : :
109 : : case ACPI_TYPE_PACKAGE:
110 : : default:
111 : : /*
112 : : * All other types than Alias and the various Fields come here,
113 : : * including the untyped case - ACPI_TYPE_ANY.
114 : : */
115 : : break;
116 : : }
117 : :
118 : 0 : return_ACPI_STATUS(status);
119 : : }
120 : :
121 : : /*******************************************************************************
122 : : *
123 : : * FUNCTION: acpi_ex_store_object_to_object
124 : : *
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
129 : : *
130 : : * RETURN: Status
131 : : *
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
135 : : * the target.
136 : : *
137 : : * The Assignment of an object to another (not named) object
138 : : * is handled here.
139 : : * The Source passed in will replace the current value (if any)
140 : : * with the input value.
141 : : *
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.
146 : : *
147 : : * This module allows destination types of Number, String,
148 : : * Buffer, and Package.
149 : : *
150 : : * Assumes parameters are already validated. NOTE: source_desc
151 : : * resolution (from a reference object) must be performed by
152 : : * the caller if necessary.
153 : : *
154 : : ******************************************************************************/
155 : :
156 : : acpi_status
157 : 0 : 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)
161 : : {
162 : 0 : union acpi_operand_object *actual_src_desc;
163 : 0 : acpi_status status = AE_OK;
164 : :
165 : 0 : ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_object, source_desc);
166 : :
167 : 0 : actual_src_desc = source_desc;
168 [ # # ]: 0 : if (!dest_desc) {
169 : : /*
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
173 : : */
174 : 0 : status =
175 : 0 : acpi_ut_copy_iobject_to_iobject(actual_src_desc, new_desc,
176 : : walk_state);
177 : 0 : return_ACPI_STATUS(status);
178 : : }
179 : :
180 [ # # ]: 0 : if (source_desc->common.type != dest_desc->common.type) {
181 : : /*
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.
185 : : *
186 : : * If no conversion performed, actual_src_desc = source_desc.
187 : : * Otherwise, actual_src_desc is a temporary object to hold the
188 : : * converted object.
189 : : */
190 : 0 : status = acpi_ex_convert_to_target_type(dest_desc->common.type,
191 : : source_desc,
192 : : &actual_src_desc,
193 : : walk_state);
194 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
195 : : return_ACPI_STATUS(status);
196 : : }
197 : :
198 [ # # ]: 0 : if (source_desc == actual_src_desc) {
199 : : /*
200 : : * No conversion was performed. Return the source_desc as the
201 : : * new object.
202 : : */
203 : 0 : *new_desc = source_desc;
204 : 0 : return_ACPI_STATUS(AE_OK);
205 : : }
206 : : }
207 : :
208 : : /*
209 : : * We now have two objects of identical types, and we can perform a
210 : : * copy of the *value* of the source object.
211 : : */
212 [ # # # # : 0 : switch (dest_desc->common.type) {
# ]
213 : 0 : case ACPI_TYPE_INTEGER:
214 : :
215 : 0 : dest_desc->integer.value = actual_src_desc->integer.value;
216 : :
217 : : /* Truncate value if we are executing from a 32-bit ACPI table */
218 : :
219 : 0 : (void)acpi_ex_truncate_for32bit_table(dest_desc);
220 : 0 : break;
221 : :
222 : 0 : case ACPI_TYPE_STRING:
223 : :
224 : 0 : status =
225 : 0 : acpi_ex_store_string_to_string(actual_src_desc, dest_desc);
226 : 0 : break;
227 : :
228 : 0 : case ACPI_TYPE_BUFFER:
229 : :
230 : 0 : status =
231 : 0 : acpi_ex_store_buffer_to_buffer(actual_src_desc, dest_desc);
232 : 0 : break;
233 : :
234 : 0 : case ACPI_TYPE_PACKAGE:
235 : :
236 : 0 : status =
237 : 0 : acpi_ut_copy_iobject_to_iobject(actual_src_desc, &dest_desc,
238 : : walk_state);
239 : 0 : break;
240 : :
241 : 0 : default:
242 : : /*
243 : : * All other types come here.
244 : : */
245 : 0 : ACPI_WARNING((AE_INFO, "Store into type [%s] not implemented",
246 : : acpi_ut_get_object_type_name(dest_desc)));
247 : :
248 : 0 : status = AE_NOT_IMPLEMENTED;
249 : 0 : break;
250 : : }
251 : :
252 [ # # ]: 0 : if (actual_src_desc != source_desc) {
253 : :
254 : : /* Delete the intermediate (temporary) source object */
255 : :
256 : 0 : acpi_ut_remove_reference(actual_src_desc);
257 : : }
258 : :
259 : 0 : *new_desc = dest_desc;
260 : 0 : return_ACPI_STATUS(status);
261 : : }
|