1
2/******************************************************************************
3 *
4 * Module Name: exstoren - AML Interpreter object store support,
5 *                        Store to Node (namespace object)
6 *              $Revision: 1.1.1.1 $
7 *
8 *****************************************************************************/
9
10/*
11 *  Copyright (C) 2000, 2001 R. Byron Moore
12 *
13 *  This program is free software; you can redistribute it and/or modify
14 *  it under the terms of the GNU General Public License as published by
15 *  the Free Software Foundation; either version 2 of the License, or
16 *  (at your option) any later version.
17 *
18 *  This program is distributed in the hope that it will be useful,
19 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 *  GNU General Public License for more details.
22 *
23 *  You should have received a copy of the GNU General Public License
24 *  along with this program; if not, write to the Free Software
25 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 */
27
28
29#include "acpi.h"
30#include "acparser.h"
31#include "acdispat.h"
32#include "acinterp.h"
33#include "amlcode.h"
34#include "acnamesp.h"
35#include "actables.h"
36
37
38#define _COMPONENT          ACPI_EXECUTER
39	 MODULE_NAME         ("exstoren")
40
41
42/*******************************************************************************
43 *
44 * FUNCTION:    Acpi_ex_resolve_object
45 *
46 * PARAMETERS:  Source_desc_ptr     - Pointer to the source object
47 *              Target_type         - Current type of the target
48 *              Walk_state          - Current walk state
49 *
50 * RETURN:      Status, resolved object in Source_desc_ptr.
51 *
52 * DESCRIPTION: Resolve an object.  If the object is a reference, dereference
53 *              it and return the actual object in the Source_desc_ptr.
54 *
55 ******************************************************************************/
56
57acpi_status
58acpi_ex_resolve_object (
59	acpi_operand_object     **source_desc_ptr,
60	acpi_object_type8       target_type,
61	acpi_walk_state         *walk_state)
62{
63	acpi_operand_object     *source_desc = *source_desc_ptr;
64	acpi_status             status = AE_OK;
65
66
67	FUNCTION_TRACE ("Ex_resolve_object");
68
69
70	/*
71	 * Ensure we have a Source that can be stored in the target
72	 */
73	switch (target_type) {
74
75	/* This case handles the "interchangeable" types Integer, String, and Buffer. */
76
77	/*
78	 * These cases all require only Integers or values that
79	 * can be converted to Integers (Strings or Buffers)
80	 */
81	case ACPI_TYPE_BUFFER_FIELD:
82	case INTERNAL_TYPE_REGION_FIELD:
83	case INTERNAL_TYPE_BANK_FIELD:
84	case INTERNAL_TYPE_INDEX_FIELD:
85
86	/*
87	 * Stores into a Field/Region or into a Buffer/String
88	 * are all essentially the same.
89	 */
90	case ACPI_TYPE_INTEGER:
91	case ACPI_TYPE_STRING:
92	case ACPI_TYPE_BUFFER:
93
94
95		/* TBD: FIX - check for source==REF, resolve, then check type */
96
97		/*
98		 * If Source_desc is not a valid type, try to resolve it to one.
99		 */
100		if ((source_desc->common.type != ACPI_TYPE_INTEGER)    &&
101			(source_desc->common.type != ACPI_TYPE_BUFFER)     &&
102			(source_desc->common.type != ACPI_TYPE_STRING)) {
103			/*
104			 * Initially not a valid type, convert
105			 */
106			status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state);
107			if (ACPI_SUCCESS (status) &&
108				(source_desc->common.type != ACPI_TYPE_INTEGER)    &&
109				(source_desc->common.type != ACPI_TYPE_BUFFER)     &&
110				(source_desc->common.type != ACPI_TYPE_STRING)) {
111				/*
112				 * Conversion successful but still not a valid type
113				 */
114				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
115					"Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
116					acpi_ut_get_type_name ((*source_desc_ptr)->common.type),
117					acpi_ut_get_type_name (target_type)));
118				status = AE_AML_OPERAND_TYPE;
119			}
120		}
121		break;
122
123
124	case INTERNAL_TYPE_ALIAS:
125
126		/*
127		 * Aliases are resolved by Acpi_ex_prep_operands
128		 */
129		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into Alias - should never happen\n"));
130		status = AE_AML_INTERNAL;
131		break;
132
133
134	case ACPI_TYPE_PACKAGE:
135	default:
136
137		/*
138		 * All other types than Alias and the various Fields come here,
139		 * including the untyped case - ACPI_TYPE_ANY.
140		 */
141		break;
142	}
143
144	return_ACPI_STATUS (status);
145}
146
147
148/*******************************************************************************
149 *
150 * FUNCTION:    Acpi_ex_store_object
151 *
152 * PARAMETERS:  Source_desc         - Object to store
153 *              Target_type         - Current type of the target
154 *              Target_desc_ptr     - Pointer to the target
155 *              Walk_state          - Current walk state
156 *
157 * RETURN:      Status
158 *
159 * DESCRIPTION: "Store" an object to another object.  This may include
160 *              converting the source type to the target type (implicit
161 *              conversion), and a copy of the value of the source to
162 *              the target.
163 *
164 ******************************************************************************/
165
166acpi_status
167acpi_ex_store_object (
168	acpi_operand_object     *source_desc,
169	acpi_object_type8       target_type,
170	acpi_operand_object     **target_desc_ptr,
171	acpi_walk_state         *walk_state)
172{
173	acpi_operand_object     *target_desc = *target_desc_ptr;
174	acpi_status             status = AE_OK;
175
176
177	FUNCTION_TRACE ("Ex_store_object");
178
179
180	/*
181	 * Perform the "implicit conversion" of the source to the current type
182	 * of the target - As per the ACPI specification.
183	 *
184	 * If no conversion performed, Source_desc is left alone, otherwise it
185	 * is updated with a new object.
186	 */
187	status = acpi_ex_convert_to_target_type (target_type, &source_desc, walk_state);
188	if (ACPI_FAILURE (status)) {
189		return_ACPI_STATUS (status);
190	}
191
192	/*
193	 * We now have two objects of identical types, and we can perform a
194	 * copy of the *value* of the source object.
195	 */
196	switch (target_type) {
197	case ACPI_TYPE_ANY:
198	case INTERNAL_TYPE_DEF_ANY:
199
200		/*
201		 * The target namespace node is uninitialized (has no target object),
202		 * and will take on the type of the source object
203		 */
204		*target_desc_ptr = source_desc;
205		break;
206
207
208	case ACPI_TYPE_INTEGER:
209
210		target_desc->integer.value = source_desc->integer.value;
211
212		/* Truncate value if we are executing from a 32-bit ACPI table */
213
214		acpi_ex_truncate_for32bit_table (target_desc, walk_state);
215		break;
216
217	case ACPI_TYPE_STRING:
218
219		status = acpi_ex_copy_string_to_string (source_desc, target_desc);
220		break;
221
222
223	case ACPI_TYPE_BUFFER:
224
225		status = acpi_ex_copy_buffer_to_buffer (source_desc, target_desc);
226		break;
227
228
229	case ACPI_TYPE_PACKAGE:
230
231		/*
232		 * TBD: [Unhandled] Not real sure what to do here
233		 */
234		status = AE_NOT_IMPLEMENTED;
235		break;
236
237
238	default:
239
240		/*
241		 * All other types come here.
242		 */
243		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into type %s not implemented\n",
244			acpi_ut_get_type_name (target_type)));
245
246		status = AE_NOT_IMPLEMENTED;
247		break;
248	}
249
250
251	return_ACPI_STATUS (status);
252}
253
254
255