aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/executer
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/acpi/executer
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/acpi/executer')
-rw-r--r--drivers/acpi/executer/Makefile10
-rw-r--r--drivers/acpi/executer/exconfig.c487
-rw-r--r--drivers/acpi/executer/exconvrt.c708
-rw-r--r--drivers/acpi/executer/excreate.c646
-rw-r--r--drivers/acpi/executer/exdump.c793
-rw-r--r--drivers/acpi/executer/exfield.c367
-rw-r--r--drivers/acpi/executer/exfldio.c835
-rw-r--r--drivers/acpi/executer/exmisc.c738
-rw-r--r--drivers/acpi/executer/exmutex.c363
-rw-r--r--drivers/acpi/executer/exnames.c427
-rw-r--r--drivers/acpi/executer/exoparg1.c1013
-rw-r--r--drivers/acpi/executer/exoparg2.c608
-rw-r--r--drivers/acpi/executer/exoparg3.c256
-rw-r--r--drivers/acpi/executer/exoparg6.c336
-rw-r--r--drivers/acpi/executer/exprep.c530
-rw-r--r--drivers/acpi/executer/exregion.c528
-rw-r--r--drivers/acpi/executer/exresnte.c289
-rw-r--r--drivers/acpi/executer/exresolv.c546
-rw-r--r--drivers/acpi/executer/exresop.c661
-rw-r--r--drivers/acpi/executer/exstore.c536
-rw-r--r--drivers/acpi/executer/exstoren.c306
-rw-r--r--drivers/acpi/executer/exstorob.c216
-rw-r--r--drivers/acpi/executer/exsystem.c378
-rw-r--r--drivers/acpi/executer/exutils.c378
24 files changed, 11955 insertions, 0 deletions
diff --git a/drivers/acpi/executer/Makefile b/drivers/acpi/executer/Makefile
new file mode 100644
index 000000000000..e09998aa012f
--- /dev/null
+++ b/drivers/acpi/executer/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for all Linux ACPI interpreter subdirectories
3#
4
5obj-y := exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
6 exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\
7 excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
8 exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o
9
10EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
new file mode 100644
index 000000000000..ac3c061967f2
--- /dev/null
+++ b/drivers/acpi/executer/exconfig.c
@@ -0,0 +1,487 @@
1/******************************************************************************
2 *
3 * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <acpi/acpi.h>
46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h>
48#include <acpi/acnamesp.h>
49#include <acpi/acevents.h>
50#include <acpi/actables.h>
51#include <acpi/acdispat.h>
52
53
54#define _COMPONENT ACPI_EXECUTER
55 ACPI_MODULE_NAME ("exconfig")
56
57
58/*******************************************************************************
59 *
60 * FUNCTION: acpi_ex_add_table
61 *
62 * PARAMETERS: Table - Pointer to raw table
63 * parent_node - Where to load the table (scope)
64 * ddb_handle - Where to return the table handle.
65 *
66 * RETURN: Status
67 *
68 * DESCRIPTION: Common function to Install and Load an ACPI table with a
69 * returned table handle.
70 *
71 ******************************************************************************/
72
73acpi_status
74acpi_ex_add_table (
75 struct acpi_table_header *table,
76 struct acpi_namespace_node *parent_node,
77 union acpi_operand_object **ddb_handle)
78{
79 acpi_status status;
80 struct acpi_table_desc table_info;
81 union acpi_operand_object *obj_desc;
82
83
84 ACPI_FUNCTION_TRACE ("ex_add_table");
85
86
87 /* Create an object to be the table handle */
88
89 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
90 if (!obj_desc) {
91 return_ACPI_STATUS (AE_NO_MEMORY);
92 }
93
94 /* Install the new table into the local data structures */
95
96 ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc));
97
98 table_info.type = ACPI_TABLE_SSDT;
99 table_info.pointer = table;
100 table_info.length = (acpi_size) table->length;
101 table_info.allocation = ACPI_MEM_ALLOCATED;
102
103 status = acpi_tb_install_table (&table_info);
104 if (ACPI_FAILURE (status)) {
105 goto cleanup;
106 }
107
108 /* Add the table to the namespace */
109
110 status = acpi_ns_load_table (table_info.installed_desc, parent_node);
111 if (ACPI_FAILURE (status)) {
112 /* Uninstall table on error */
113
114 (void) acpi_tb_uninstall_table (table_info.installed_desc);
115 goto cleanup;
116 }
117
118 /* Init the table handle */
119
120 obj_desc->reference.opcode = AML_LOAD_OP;
121 obj_desc->reference.object = table_info.installed_desc;
122 *ddb_handle = obj_desc;
123 return_ACPI_STATUS (AE_OK);
124
125
126cleanup:
127 acpi_ut_remove_reference (obj_desc);
128 return_ACPI_STATUS (status);
129}
130
131
132/*******************************************************************************
133 *
134 * FUNCTION: acpi_ex_load_table_op
135 *
136 * PARAMETERS: walk_state - Current state with operands
137 * return_desc - Where to store the return object
138 *
139 * RETURN: Status
140 *
141 * DESCRIPTION: Load an ACPI table
142 *
143 ******************************************************************************/
144
145acpi_status
146acpi_ex_load_table_op (
147 struct acpi_walk_state *walk_state,
148 union acpi_operand_object **return_desc)
149{
150 acpi_status status;
151 union acpi_operand_object **operand = &walk_state->operands[0];
152 struct acpi_table_header *table;
153 struct acpi_namespace_node *parent_node;
154 struct acpi_namespace_node *start_node;
155 struct acpi_namespace_node *parameter_node = NULL;
156 union acpi_operand_object *ddb_handle;
157
158
159 ACPI_FUNCTION_TRACE ("ex_load_table_op");
160
161
162#if 0
163 /*
164 * Make sure that the signature does not match one of the tables that
165 * is already loaded.
166 */
167 status = acpi_tb_match_signature (operand[0]->string.pointer, NULL);
168 if (status == AE_OK) {
169 /* Signature matched -- don't allow override */
170
171 return_ACPI_STATUS (AE_ALREADY_EXISTS);
172 }
173#endif
174
175 /* Find the ACPI table */
176
177 status = acpi_tb_find_table (operand[0]->string.pointer,
178 operand[1]->string.pointer,
179 operand[2]->string.pointer, &table);
180 if (ACPI_FAILURE (status)) {
181 if (status != AE_NOT_FOUND) {
182 return_ACPI_STATUS (status);
183 }
184
185 /* Table not found, return an Integer=0 and AE_OK */
186
187 ddb_handle = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
188 if (!ddb_handle) {
189 return_ACPI_STATUS (AE_NO_MEMORY);
190 }
191
192 ddb_handle->integer.value = 0;
193 *return_desc = ddb_handle;
194
195 return_ACPI_STATUS (AE_OK);
196 }
197
198 /* Default nodes */
199
200 start_node = walk_state->scope_info->scope.node;
201 parent_node = acpi_gbl_root_node;
202
203 /* root_path (optional parameter) */
204
205 if (operand[3]->string.length > 0) {
206 /*
207 * Find the node referenced by the root_path_string. This is the
208 * location within the namespace where the table will be loaded.
209 */
210 status = acpi_ns_get_node_by_path (operand[3]->string.pointer, start_node,
211 ACPI_NS_SEARCH_PARENT, &parent_node);
212 if (ACPI_FAILURE (status)) {
213 return_ACPI_STATUS (status);
214 }
215 }
216
217 /* parameter_path (optional parameter) */
218
219 if (operand[4]->string.length > 0) {
220 if ((operand[4]->string.pointer[0] != '\\') &&
221 (operand[4]->string.pointer[0] != '^')) {
222 /*
223 * Path is not absolute, so it will be relative to the node
224 * referenced by the root_path_string (or the NS root if omitted)
225 */
226 start_node = parent_node;
227 }
228
229 /*
230 * Find the node referenced by the parameter_path_string
231 */
232 status = acpi_ns_get_node_by_path (operand[4]->string.pointer, start_node,
233 ACPI_NS_SEARCH_PARENT, &parameter_node);
234 if (ACPI_FAILURE (status)) {
235 return_ACPI_STATUS (status);
236 }
237 }
238
239 /* Load the table into the namespace */
240
241 status = acpi_ex_add_table (table, parent_node, &ddb_handle);
242 if (ACPI_FAILURE (status)) {
243 return_ACPI_STATUS (status);
244 }
245
246 /* Parameter Data (optional) */
247
248 if (parameter_node) {
249 /* Store the parameter data into the optional parameter object */
250
251 status = acpi_ex_store (operand[5], ACPI_CAST_PTR (union acpi_operand_object, parameter_node),
252 walk_state);
253 if (ACPI_FAILURE (status)) {
254 (void) acpi_ex_unload_table (ddb_handle);
255 return_ACPI_STATUS (status);
256 }
257 }
258
259 *return_desc = ddb_handle;
260 return_ACPI_STATUS (status);
261}
262
263
264/*******************************************************************************
265 *
266 * FUNCTION: acpi_ex_load_op
267 *
268 * PARAMETERS: obj_desc - Region or Field where the table will be
269 * obtained
270 * Target - Where a handle to the table will be stored
271 * walk_state - Current state
272 *
273 * RETURN: Status
274 *
275 * DESCRIPTION: Load an ACPI table from a field or operation region
276 *
277 ******************************************************************************/
278
279acpi_status
280acpi_ex_load_op (
281 union acpi_operand_object *obj_desc,
282 union acpi_operand_object *target,
283 struct acpi_walk_state *walk_state)
284{
285 acpi_status status;
286 union acpi_operand_object *ddb_handle;
287 union acpi_operand_object *buffer_desc = NULL;
288 struct acpi_table_header *table_ptr = NULL;
289 acpi_physical_address address;
290 struct acpi_table_header table_header;
291 u32 i;
292
293 ACPI_FUNCTION_TRACE ("ex_load_op");
294
295
296 /* Object can be either an op_region or a Field */
297
298 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
299 case ACPI_TYPE_REGION:
300
301 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n",
302 obj_desc, acpi_ut_get_object_type_name (obj_desc)));
303
304 /*
305 * If the Region Address and Length have not been previously evaluated,
306 * evaluate them now and save the results.
307 */
308 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
309 status = acpi_ds_get_region_arguments (obj_desc);
310 if (ACPI_FAILURE (status)) {
311 return_ACPI_STATUS (status);
312 }
313 }
314
315 /* Get the base physical address of the region */
316
317 address = obj_desc->region.address;
318
319 /* Get the table length from the table header */
320
321 table_header.length = 0;
322 for (i = 0; i < 8; i++) {
323 status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
324 (acpi_physical_address) (i + address), 8,
325 ((u8 *) &table_header) + i);
326 if (ACPI_FAILURE (status)) {
327 return_ACPI_STATUS (status);
328 }
329 }
330
331 /* Sanity check the table length */
332
333 if (table_header.length < sizeof (struct acpi_table_header)) {
334 return_ACPI_STATUS (AE_BAD_HEADER);
335 }
336
337 /* Allocate a buffer for the entire table */
338
339 table_ptr = ACPI_MEM_ALLOCATE (table_header.length);
340 if (!table_ptr) {
341 return_ACPI_STATUS (AE_NO_MEMORY);
342 }
343
344 /* Get the entire table from the op region */
345
346 for (i = 0; i < table_header.length; i++) {
347 status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
348 (acpi_physical_address) (i + address), 8,
349 ((u8 *) table_ptr + i));
350 if (ACPI_FAILURE (status)) {
351 goto cleanup;
352 }
353 }
354 break;
355
356
357 case ACPI_TYPE_LOCAL_REGION_FIELD:
358 case ACPI_TYPE_LOCAL_BANK_FIELD:
359 case ACPI_TYPE_LOCAL_INDEX_FIELD:
360
361 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Field %p %s\n",
362 obj_desc, acpi_ut_get_object_type_name (obj_desc)));
363
364 /*
365 * The length of the field must be at least as large as the table.
366 * Read the entire field and thus the entire table. Buffer is
367 * allocated during the read.
368 */
369 status = acpi_ex_read_data_from_field (walk_state, obj_desc, &buffer_desc);
370 if (ACPI_FAILURE (status)) {
371 goto cleanup;
372 }
373
374 table_ptr = ACPI_CAST_PTR (struct acpi_table_header, buffer_desc->buffer.pointer);
375
376 /* Sanity check the table length */
377
378 if (table_ptr->length < sizeof (struct acpi_table_header)) {
379 return_ACPI_STATUS (AE_BAD_HEADER);
380 }
381 break;
382
383
384 default:
385 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
386 }
387
388 /* The table must be either an SSDT or a PSDT */
389
390 if ((!ACPI_STRNCMP (table_ptr->signature,
391 acpi_gbl_table_data[ACPI_TABLE_PSDT].signature,
392 acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) &&
393 (!ACPI_STRNCMP (table_ptr->signature,
394 acpi_gbl_table_data[ACPI_TABLE_SSDT].signature,
395 acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) {
396 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
397 "Table has invalid signature [%4.4s], must be SSDT or PSDT\n",
398 table_ptr->signature));
399 status = AE_BAD_SIGNATURE;
400 goto cleanup;
401 }
402
403 /* Install the new table into the local data structures */
404
405 status = acpi_ex_add_table (table_ptr, acpi_gbl_root_node, &ddb_handle);
406 if (ACPI_FAILURE (status)) {
407 goto cleanup;
408 }
409
410 /* Store the ddb_handle into the Target operand */
411
412 status = acpi_ex_store (ddb_handle, target, walk_state);
413 if (ACPI_FAILURE (status)) {
414 (void) acpi_ex_unload_table (ddb_handle);
415 }
416
417 return_ACPI_STATUS (status);
418
419
420cleanup:
421
422 if (buffer_desc) {
423 acpi_ut_remove_reference (buffer_desc);
424 }
425 else {
426 ACPI_MEM_FREE (table_ptr);
427 }
428 return_ACPI_STATUS (status);
429}
430
431
432/*******************************************************************************
433 *
434 * FUNCTION: acpi_ex_unload_table
435 *
436 * PARAMETERS: ddb_handle - Handle to a previously loaded table
437 *
438 * RETURN: Status
439 *
440 * DESCRIPTION: Unload an ACPI table
441 *
442 ******************************************************************************/
443
444acpi_status
445acpi_ex_unload_table (
446 union acpi_operand_object *ddb_handle)
447{
448 acpi_status status = AE_OK;
449 union acpi_operand_object *table_desc = ddb_handle;
450 struct acpi_table_desc *table_info;
451
452
453 ACPI_FUNCTION_TRACE ("ex_unload_table");
454
455
456 /*
457 * Validate the handle
458 * Although the handle is partially validated in acpi_ex_reconfiguration(),
459 * when it calls acpi_ex_resolve_operands(), the handle is more completely
460 * validated here.
461 */
462 if ((!ddb_handle) ||
463 (ACPI_GET_DESCRIPTOR_TYPE (ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
464 (ACPI_GET_OBJECT_TYPE (ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
465 return_ACPI_STATUS (AE_BAD_PARAMETER);
466 }
467
468 /* Get the actual table descriptor from the ddb_handle */
469
470 table_info = (struct acpi_table_desc *) table_desc->reference.object;
471
472 /*
473 * Delete the entire namespace under this table Node
474 * (Offset contains the table_id)
475 */
476 acpi_ns_delete_namespace_by_owner (table_info->table_id);
477
478 /* Delete the table itself */
479
480 (void) acpi_tb_uninstall_table (table_info->installed_desc);
481
482 /* Delete the table descriptor (ddb_handle) */
483
484 acpi_ut_remove_reference (table_desc);
485 return_ACPI_STATUS (status);
486}
487
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
new file mode 100644
index 000000000000..df7ba1219bf6
--- /dev/null
+++ b/drivers/acpi/executer/exconvrt.c
@@ -0,0 +1,708 @@
1/******************************************************************************
2 *
3 * Module Name: exconvrt - Object conversion routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <acpi/acpi.h>
46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h>
48
49
50#define _COMPONENT ACPI_EXECUTER
51 ACPI_MODULE_NAME ("exconvrt")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ex_convert_to_integer
57 *
58 * PARAMETERS: obj_desc - Object to be converted. Must be an
59 * Integer, Buffer, or String
60 * result_desc - Where the new Integer object is returned
61 * Flags - Used for string conversion
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Convert an ACPI Object to an integer.
66 *
67 ******************************************************************************/
68
69acpi_status
70acpi_ex_convert_to_integer (
71 union acpi_operand_object *obj_desc,
72 union acpi_operand_object **result_desc,
73 u32 flags)
74{
75 union acpi_operand_object *return_desc;
76 u8 *pointer;
77 acpi_integer result;
78 u32 i;
79 u32 count;
80 acpi_status status;
81
82
83 ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_integer", obj_desc);
84
85
86 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
87 case ACPI_TYPE_INTEGER:
88
89 /* No conversion necessary */
90
91 *result_desc = obj_desc;
92 return_ACPI_STATUS (AE_OK);
93
94 case ACPI_TYPE_BUFFER:
95 case ACPI_TYPE_STRING:
96
97 /* Note: Takes advantage of common buffer/string fields */
98
99 pointer = obj_desc->buffer.pointer;
100 count = obj_desc->buffer.length;
101 break;
102
103 default:
104 return_ACPI_STATUS (AE_TYPE);
105 }
106
107 /*
108 * Convert the buffer/string to an integer. Note that both buffers and
109 * strings are treated as raw data - we don't convert ascii to hex for
110 * strings.
111 *
112 * There are two terminating conditions for the loop:
113 * 1) The size of an integer has been reached, or
114 * 2) The end of the buffer or string has been reached
115 */
116 result = 0;
117
118 /*
119 * String conversion is different than Buffer conversion
120 */
121 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
122 case ACPI_TYPE_STRING:
123
124 /*
125 * Convert string to an integer - for most cases, the string must be
126 * hexadecimal as per the ACPI specification. The only exception (as
127 * of ACPI 3.0) is that the to_integer() operator allows both decimal
128 * and hexadecimal strings (hex prefixed with "0x").
129 */
130 status = acpi_ut_strtoul64 ((char *) pointer, flags, &result);
131 if (ACPI_FAILURE (status)) {
132 return_ACPI_STATUS (status);
133 }
134 break;
135
136
137 case ACPI_TYPE_BUFFER:
138
139 /* Check for zero-length buffer */
140
141 if (!count) {
142 return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
143 }
144
145 /* Transfer no more than an integer's worth of data */
146
147 if (count > acpi_gbl_integer_byte_width) {
148 count = acpi_gbl_integer_byte_width;
149 }
150
151 /*
152 * Convert buffer to an integer - we simply grab enough raw data
153 * from the buffer to fill an integer
154 */
155 for (i = 0; i < count; i++) {
156 /*
157 * Get next byte and shift it into the Result.
158 * Little endian is used, meaning that the first byte of the buffer
159 * is the LSB of the integer
160 */
161 result |= (((acpi_integer) pointer[i]) << (i * 8));
162 }
163 break;
164
165
166 default:
167 /* No other types can get here */
168 break;
169 }
170
171 /*
172 * Create a new integer
173 */
174 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
175 if (!return_desc) {
176 return_ACPI_STATUS (AE_NO_MEMORY);
177 }
178
179 /* Save the Result */
180
181 return_desc->integer.value = result;
182 acpi_ex_truncate_for32bit_table (return_desc);
183 *result_desc = return_desc;
184 return_ACPI_STATUS (AE_OK);
185}
186
187
188/*******************************************************************************
189 *
190 * FUNCTION: acpi_ex_convert_to_buffer
191 *
192 * PARAMETERS: obj_desc - Object to be converted. Must be an
193 * Integer, Buffer, or String
194 * result_desc - Where the new buffer object is returned
195 *
196 * RETURN: Status
197 *
198 * DESCRIPTION: Convert an ACPI Object to a Buffer
199 *
200 ******************************************************************************/
201
202acpi_status
203acpi_ex_convert_to_buffer (
204 union acpi_operand_object *obj_desc,
205 union acpi_operand_object **result_desc)
206{
207 union acpi_operand_object *return_desc;
208 u8 *new_buf;
209
210
211 ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_buffer", obj_desc);
212
213
214 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
215 case ACPI_TYPE_BUFFER:
216
217 /* No conversion necessary */
218
219 *result_desc = obj_desc;
220 return_ACPI_STATUS (AE_OK);
221
222
223 case ACPI_TYPE_INTEGER:
224
225 /*
226 * Create a new Buffer object.
227 * Need enough space for one integer
228 */
229 return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
230 if (!return_desc) {
231 return_ACPI_STATUS (AE_NO_MEMORY);
232 }
233
234 /* Copy the integer to the buffer, LSB first */
235
236 new_buf = return_desc->buffer.pointer;
237 ACPI_MEMCPY (new_buf,
238 &obj_desc->integer.value,
239 acpi_gbl_integer_byte_width);
240 break;
241
242
243 case ACPI_TYPE_STRING:
244
245 /*
246 * Create a new Buffer object
247 * Size will be the string length
248 *
249 * NOTE: Add one to the string length to include the null terminator.
250 * The ACPI spec is unclear on this subject, but there is existing
251 * ASL/AML code that depends on the null being transferred to the new
252 * buffer.
253 */
254 return_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length + 1);
255 if (!return_desc) {
256 return_ACPI_STATUS (AE_NO_MEMORY);
257 }
258
259 /* Copy the string to the buffer */
260
261 new_buf = return_desc->buffer.pointer;
262 ACPI_STRNCPY ((char *) new_buf, (char *) obj_desc->string.pointer,
263 obj_desc->string.length);
264 break;
265
266
267 default:
268 return_ACPI_STATUS (AE_TYPE);
269 }
270
271 /* Mark buffer initialized */
272
273 return_desc->common.flags |= AOPOBJ_DATA_VALID;
274 *result_desc = return_desc;
275 return_ACPI_STATUS (AE_OK);
276}
277
278
279/*******************************************************************************
280 *
281 * FUNCTION: acpi_ex_convert_to_ascii
282 *
283 * PARAMETERS: Integer - Value to be converted
284 * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
285 * String - Where the string is returned
286 * data_width - Size of data item to be converted, in bytes
287 *
288 * RETURN: Actual string length
289 *
290 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
291 *
292 ******************************************************************************/
293
294u32
295acpi_ex_convert_to_ascii (
296 acpi_integer integer,
297 u16 base,
298 u8 *string,
299 u8 data_width)
300{
301 acpi_integer digit;
302 acpi_native_uint i;
303 acpi_native_uint j;
304 acpi_native_uint k = 0;
305 acpi_native_uint hex_length;
306 acpi_native_uint decimal_length;
307 u32 remainder;
308 u8 supress_zeros;
309
310
311 ACPI_FUNCTION_ENTRY ();
312
313
314 switch (base) {
315 case 10:
316
317 /* Setup max length for the decimal number */
318
319 switch (data_width) {
320 case 1:
321 decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
322 break;
323
324 case 4:
325 decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
326 break;
327
328 case 8:
329 default:
330 decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
331 break;
332 }
333
334 supress_zeros = TRUE; /* No leading zeros */
335 remainder = 0;
336
337 for (i = decimal_length; i > 0; i--) {
338 /* Divide by nth factor of 10 */
339
340 digit = integer;
341 for (j = 0; j < i; j++) {
342 (void) acpi_ut_short_divide (digit, 10, &digit, &remainder);
343 }
344
345 /* Handle leading zeros */
346
347 if (remainder != 0) {
348 supress_zeros = FALSE;
349 }
350
351 if (!supress_zeros) {
352 string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
353 k++;
354 }
355 }
356 break;
357
358 case 16:
359
360 hex_length = ACPI_MUL_2 (data_width); /* 2 ascii hex chars per data byte */
361
362 for (i = 0, j = (hex_length-1); i < hex_length; i++, j--) {
363 /* Get one hex digit, most significant digits first */
364
365 string[k] = (u8) acpi_ut_hex_to_ascii_char (integer, ACPI_MUL_4 (j));
366 k++;
367 }
368 break;
369
370 default:
371 return (0);
372 }
373
374 /*
375 * Since leading zeros are supressed, we must check for the case where
376 * the integer equals 0
377 *
378 * Finally, null terminate the string and return the length
379 */
380 if (!k) {
381 string [0] = ACPI_ASCII_ZERO;
382 k = 1;
383 }
384
385 string [k] = 0;
386 return ((u32) k);
387}
388
389
390/*******************************************************************************
391 *
392 * FUNCTION: acpi_ex_convert_to_string
393 *
394 * PARAMETERS: obj_desc - Object to be converted. Must be an
395 * Integer, Buffer, or String
396 * result_desc - Where the string object is returned
397 * Type - String flags (base and conversion type)
398 *
399 * RETURN: Status
400 *
401 * DESCRIPTION: Convert an ACPI Object to a string
402 *
403 ******************************************************************************/
404
405acpi_status
406acpi_ex_convert_to_string (
407 union acpi_operand_object *obj_desc,
408 union acpi_operand_object **result_desc,
409 u32 type)
410{
411 union acpi_operand_object *return_desc;
412 u8 *new_buf;
413 u32 i;
414 u32 string_length = 0;
415 u16 base = 16;
416 u8 separator = ',';
417
418
419 ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc);
420
421
422 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
423 case ACPI_TYPE_STRING:
424
425 /* No conversion necessary */
426
427 *result_desc = obj_desc;
428 return_ACPI_STATUS (AE_OK);
429
430
431 case ACPI_TYPE_INTEGER:
432
433 switch (type) {
434 case ACPI_EXPLICIT_CONVERT_DECIMAL:
435
436 /* Make room for maximum decimal number */
437
438 string_length = ACPI_MAX_DECIMAL_DIGITS;
439 base = 10;
440 break;
441
442 default:
443
444 /* Two hex string characters for each integer byte */
445
446 string_length = ACPI_MUL_2 (acpi_gbl_integer_byte_width);
447 break;
448 }
449
450 /*
451 * Create a new String
452 * Need enough space for one ASCII integer (plus null terminator)
453 */
454 return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
455 if (!return_desc) {
456 return_ACPI_STATUS (AE_NO_MEMORY);
457 }
458
459 new_buf = return_desc->buffer.pointer;
460
461 /* Convert integer to string */
462
463 string_length = acpi_ex_convert_to_ascii (obj_desc->integer.value, base,
464 new_buf, acpi_gbl_integer_byte_width);
465
466 /* Null terminate at the correct place */
467
468 return_desc->string.length = string_length;
469 new_buf [string_length] = 0;
470 break;
471
472
473 case ACPI_TYPE_BUFFER:
474
475 /* Setup string length, base, and separator */
476
477 switch (type) {
478 case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string operator */
479 /*
480 * From ACPI: "If Data is a buffer, it is converted to a string of
481 * decimal values separated by commas."
482 */
483 base = 10;
484
485 /*
486 * Calculate the final string length. Individual string values
487 * are variable length (include separator for each)
488 */
489 for (i = 0; i < obj_desc->buffer.length; i++) {
490 if (obj_desc->buffer.pointer[i] >= 100) {
491 string_length += 4;
492 }
493 else if (obj_desc->buffer.pointer[i] >= 10) {
494 string_length += 3;
495 }
496 else {
497 string_length += 2;
498 }
499 }
500 break;
501
502 case ACPI_IMPLICIT_CONVERT_HEX:
503 /*
504 * From the ACPI spec:
505 *"The entire contents of the buffer are converted to a string of
506 * two-character hexadecimal numbers, each separated by a space."
507 */
508 separator = ' ';
509 string_length = (obj_desc->buffer.length * 3);
510 break;
511
512 case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string operator */
513 /*
514 * From ACPI: "If Data is a buffer, it is converted to a string of
515 * hexadecimal values separated by commas."
516 */
517 string_length = (obj_desc->buffer.length * 3);
518 break;
519
520 default:
521 return_ACPI_STATUS (AE_BAD_PARAMETER);
522 }
523
524 /*
525 * Perform the conversion.
526 * (-1 because of extra separator included in string_length from above)
527 */
528 string_length--;
529 if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ {
530 return_ACPI_STATUS (AE_AML_STRING_LIMIT);
531 }
532
533 /*
534 * Create a new string object and string buffer
535 */
536 return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
537 if (!return_desc) {
538 return_ACPI_STATUS (AE_NO_MEMORY);
539 }
540
541 new_buf = return_desc->buffer.pointer;
542
543 /*
544 * Convert buffer bytes to hex or decimal values
545 * (separated by commas or spaces)
546 */
547 for (i = 0; i < obj_desc->buffer.length; i++) {
548 new_buf += acpi_ex_convert_to_ascii (
549 (acpi_integer) obj_desc->buffer.pointer[i], base,
550 new_buf, 1);
551 *new_buf++ = separator; /* each separated by a comma or space */
552 }
553
554 /* Null terminate the string (overwrites final comma/space from above) */
555
556 new_buf--;
557 *new_buf = 0;
558 break;
559
560 default:
561 return_ACPI_STATUS (AE_TYPE);
562 }
563
564 *result_desc = return_desc;
565 return_ACPI_STATUS (AE_OK);
566}
567
568
569/*******************************************************************************
570 *
571 * FUNCTION: acpi_ex_convert_to_target_type
572 *
573 * PARAMETERS: destination_type - Current type of the destination
574 * source_desc - Source object to be converted.
575 * result_desc - Where the converted object is returned
576 * walk_state - Current method state
577 *
578 * RETURN: Status
579 *
580 * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
581 *
582 ******************************************************************************/
583
584acpi_status
585acpi_ex_convert_to_target_type (
586 acpi_object_type destination_type,
587 union acpi_operand_object *source_desc,
588 union acpi_operand_object **result_desc,
589 struct acpi_walk_state *walk_state)
590{
591 acpi_status status = AE_OK;
592
593
594 ACPI_FUNCTION_TRACE ("ex_convert_to_target_type");
595
596
597 /* Default behavior */
598
599 *result_desc = source_desc;
600
601 /*
602 * If required by the target,
603 * perform implicit conversion on the source before we store it.
604 */
605 switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)) {
606 case ARGI_SIMPLE_TARGET:
607 case ARGI_FIXED_TARGET:
608 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
609
610 switch (destination_type) {
611 case ACPI_TYPE_LOCAL_REGION_FIELD:
612 /*
613 * Named field can always handle conversions
614 */
615 break;
616
617 default:
618 /* No conversion allowed for these types */
619
620 if (destination_type != ACPI_GET_OBJECT_TYPE (source_desc)) {
621 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
622 "Explicit operator, will store (%s) over existing type (%s)\n",
623 acpi_ut_get_object_type_name (source_desc),
624 acpi_ut_get_type_name (destination_type)));
625 status = AE_TYPE;
626 }
627 }
628 break;
629
630
631 case ARGI_TARGETREF:
632
633 switch (destination_type) {
634 case ACPI_TYPE_INTEGER:
635 case ACPI_TYPE_BUFFER_FIELD:
636 case ACPI_TYPE_LOCAL_BANK_FIELD:
637 case ACPI_TYPE_LOCAL_INDEX_FIELD:
638 /*
639 * These types require an Integer operand. We can convert
640 * a Buffer or a String to an Integer if necessary.
641 */
642 status = acpi_ex_convert_to_integer (source_desc, result_desc,
643 16);
644 break;
645
646
647 case ACPI_TYPE_STRING:
648
649 /*
650 * The operand must be a String. We can convert an
651 * Integer or Buffer if necessary
652 */
653 status = acpi_ex_convert_to_string (source_desc, result_desc,
654 ACPI_IMPLICIT_CONVERT_HEX);
655 break;
656
657
658 case ACPI_TYPE_BUFFER:
659
660 /*
661 * The operand must be a Buffer. We can convert an
662 * Integer or String if necessary
663 */
664 status = acpi_ex_convert_to_buffer (source_desc, result_desc);
665 break;
666
667
668 default:
669 ACPI_REPORT_ERROR (("Bad destination type during conversion: %X\n",
670 destination_type));
671 status = AE_AML_INTERNAL;
672 break;
673 }
674 break;
675
676
677 case ARGI_REFERENCE:
678 /*
679 * create_xxxx_field cases - we are storing the field object into the name
680 */
681 break;
682
683
684 default:
685 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
686 "Unknown Target type ID 0x%X Op %s dest_type %s\n",
687 GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args),
688 walk_state->op_info->name, acpi_ut_get_type_name (destination_type)));
689
690 ACPI_REPORT_ERROR (("Bad Target Type (ARGI): %X\n",
691 GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)))
692 status = AE_AML_INTERNAL;
693 }
694
695 /*
696 * Source-to-Target conversion semantics:
697 *
698 * If conversion to the target type cannot be performed, then simply
699 * overwrite the target with the new object and type.
700 */
701 if (status == AE_TYPE) {
702 status = AE_OK;
703 }
704
705 return_ACPI_STATUS (status);
706}
707
708
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
new file mode 100644
index 000000000000..d94c260dac6d
--- /dev/null
+++ b/drivers/acpi/executer/excreate.c
@@ -0,0 +1,646 @@
1/******************************************************************************
2 *
3 * Module Name: excreate - Named object creation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <acpi/acpi.h>
46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h>
48#include <acpi/acnamesp.h>
49#include <acpi/acevents.h>
50#include <acpi/actables.h>
51
52
53#define _COMPONENT ACPI_EXECUTER
54 ACPI_MODULE_NAME ("excreate")
55
56
57#ifndef ACPI_NO_METHOD_EXECUTION
58/*****************************************************************************
59 *
60 * FUNCTION: acpi_ex_create_alias
61 *
62 * PARAMETERS: walk_state - Current state, contains operands
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Create a new named alias
67 *
68 ****************************************************************************/
69
70acpi_status
71acpi_ex_create_alias (
72 struct acpi_walk_state *walk_state)
73{
74 struct acpi_namespace_node *target_node;
75 struct acpi_namespace_node *alias_node;
76 acpi_status status = AE_OK;
77
78
79 ACPI_FUNCTION_TRACE ("ex_create_alias");
80
81
82 /* Get the source/alias operands (both namespace nodes) */
83
84 alias_node = (struct acpi_namespace_node *) walk_state->operands[0];
85 target_node = (struct acpi_namespace_node *) walk_state->operands[1];
86
87 if ((target_node->type == ACPI_TYPE_LOCAL_ALIAS) ||
88 (target_node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
89 /*
90 * Dereference an existing alias so that we don't create a chain
91 * of aliases. With this code, we guarantee that an alias is
92 * always exactly one level of indirection away from the
93 * actual aliased name.
94 */
95 target_node = ACPI_CAST_PTR (struct acpi_namespace_node, target_node->object);
96 }
97
98 /*
99 * For objects that can never change (i.e., the NS node will
100 * permanently point to the same object), we can simply attach
101 * the object to the new NS node. For other objects (such as
102 * Integers, buffers, etc.), we have to point the Alias node
103 * to the original Node.
104 */
105 switch (target_node->type) {
106 case ACPI_TYPE_INTEGER:
107 case ACPI_TYPE_STRING:
108 case ACPI_TYPE_BUFFER:
109 case ACPI_TYPE_PACKAGE:
110 case ACPI_TYPE_BUFFER_FIELD:
111
112 /*
113 * The new alias has the type ALIAS and points to the original
114 * NS node, not the object itself. This is because for these
115 * types, the object can change dynamically via a Store.
116 */
117 alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
118 alias_node->object = ACPI_CAST_PTR (union acpi_operand_object, target_node);
119 break;
120
121 case ACPI_TYPE_METHOD:
122
123 /*
124 * The new alias has the type ALIAS and points to the original
125 * NS node, not the object itself. This is because for these
126 * types, the object can change dynamically via a Store.
127 */
128 alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
129 alias_node->object = ACPI_CAST_PTR (union acpi_operand_object, target_node);
130 break;
131
132 default:
133
134 /* Attach the original source object to the new Alias Node */
135
136 /*
137 * The new alias assumes the type of the target, and it points
138 * to the same object. The reference count of the object has an
139 * additional reference to prevent deletion out from under either the
140 * target node or the alias Node
141 */
142 status = acpi_ns_attach_object (alias_node,
143 acpi_ns_get_attached_object (target_node),
144 target_node->type);
145 break;
146 }
147
148 /* Since both operands are Nodes, we don't need to delete them */
149
150 return_ACPI_STATUS (status);
151}
152
153
154/*****************************************************************************
155 *
156 * FUNCTION: acpi_ex_create_event
157 *
158 * PARAMETERS: walk_state - Current state
159 *
160 * RETURN: Status
161 *
162 * DESCRIPTION: Create a new event object
163 *
164 ****************************************************************************/
165
166acpi_status
167acpi_ex_create_event (
168 struct acpi_walk_state *walk_state)
169{
170 acpi_status status;
171 union acpi_operand_object *obj_desc;
172
173
174 ACPI_FUNCTION_TRACE ("ex_create_event");
175
176
177 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_EVENT);
178 if (!obj_desc) {
179 status = AE_NO_MEMORY;
180 goto cleanup;
181 }
182
183 /*
184 * Create the actual OS semaphore, with zero initial units -- meaning
185 * that the event is created in an unsignalled state
186 */
187 status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0,
188 &obj_desc->event.semaphore);
189 if (ACPI_FAILURE (status)) {
190 goto cleanup;
191 }
192
193 /* Attach object to the Node */
194
195 status = acpi_ns_attach_object ((struct acpi_namespace_node *) walk_state->operands[0],
196 obj_desc, ACPI_TYPE_EVENT);
197
198cleanup:
199 /*
200 * Remove local reference to the object (on error, will cause deletion
201 * of both object and semaphore if present.)
202 */
203 acpi_ut_remove_reference (obj_desc);
204 return_ACPI_STATUS (status);
205}
206
207
208/*****************************************************************************
209 *
210 * FUNCTION: acpi_ex_create_mutex
211 *
212 * PARAMETERS: walk_state - Current state
213 *
214 * RETURN: Status
215 *
216 * DESCRIPTION: Create a new mutex object
217 *
218 * Mutex (Name[0], sync_level[1])
219 *
220 ****************************************************************************/
221
222acpi_status
223acpi_ex_create_mutex (
224 struct acpi_walk_state *walk_state)
225{
226 acpi_status status = AE_OK;
227 union acpi_operand_object *obj_desc;
228
229
230 ACPI_FUNCTION_TRACE_PTR ("ex_create_mutex", ACPI_WALK_OPERANDS);
231
232
233 /* Create the new mutex object */
234
235 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_MUTEX);
236 if (!obj_desc) {
237 status = AE_NO_MEMORY;
238 goto cleanup;
239 }
240
241 /*
242 * Create the actual OS semaphore.
243 * One unit max to make it a mutex, with one initial unit to allow
244 * the mutex to be acquired.
245 */
246 status = acpi_os_create_semaphore (1, 1, &obj_desc->mutex.semaphore);
247 if (ACPI_FAILURE (status)) {
248 goto cleanup;
249 }
250
251 /* Init object and attach to NS node */
252
253 obj_desc->mutex.sync_level = (u8) walk_state->operands[1]->integer.value;
254 obj_desc->mutex.node = (struct acpi_namespace_node *) walk_state->operands[0];
255
256 status = acpi_ns_attach_object (obj_desc->mutex.node,
257 obj_desc, ACPI_TYPE_MUTEX);
258
259
260cleanup:
261 /*
262 * Remove local reference to the object (on error, will cause deletion
263 * of both object and semaphore if present.)
264 */
265 acpi_ut_remove_reference (obj_desc);
266 return_ACPI_STATUS (status);
267}
268
269
270/*****************************************************************************
271 *
272 * FUNCTION: acpi_ex_create_region
273 *
274 * PARAMETERS: aml_start - Pointer to the region declaration AML
275 * aml_length - Max length of the declaration AML
276 * Operands - List of operands for the opcode
277 * walk_state - Current state
278 *
279 * RETURN: Status
280 *
281 * DESCRIPTION: Create a new operation region object
282 *
283 ****************************************************************************/
284
285acpi_status
286acpi_ex_create_region (
287 u8 *aml_start,
288 u32 aml_length,
289 u8 region_space,
290 struct acpi_walk_state *walk_state)
291{
292 acpi_status status;
293 union acpi_operand_object *obj_desc;
294 struct acpi_namespace_node *node;
295 union acpi_operand_object *region_obj2;
296
297
298 ACPI_FUNCTION_TRACE ("ex_create_region");
299
300
301 /* Get the Namespace Node */
302
303 node = walk_state->op->common.node;
304
305 /*
306 * If the region object is already attached to this node,
307 * just return
308 */
309 if (acpi_ns_get_attached_object (node)) {
310 return_ACPI_STATUS (AE_OK);
311 }
312
313 /*
314 * Space ID must be one of the predefined IDs, or in the user-defined
315 * range
316 */
317 if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) &&
318 (region_space < ACPI_USER_REGION_BEGIN)) {
319 ACPI_REPORT_ERROR (("Invalid address_space type %X\n", region_space));
320 return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
321 }
322
323 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
324 acpi_ut_get_region_name (region_space), region_space));
325
326 /* Create the region descriptor */
327
328 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION);
329 if (!obj_desc) {
330 status = AE_NO_MEMORY;
331 goto cleanup;
332 }
333
334 /*
335 * Remember location in AML stream of address & length
336 * operands since they need to be evaluated at run time.
337 */
338 region_obj2 = obj_desc->common.next_object;
339 region_obj2->extra.aml_start = aml_start;
340 region_obj2->extra.aml_length = aml_length;
341
342 /* Init the region from the operands */
343
344 obj_desc->region.space_id = region_space;
345 obj_desc->region.address = 0;
346 obj_desc->region.length = 0;
347 obj_desc->region.node = node;
348
349 /* Install the new region object in the parent Node */
350
351 status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_REGION);
352
353
354cleanup:
355
356 /* Remove local reference to the object */
357
358 acpi_ut_remove_reference (obj_desc);
359 return_ACPI_STATUS (status);
360}
361
362
363/*****************************************************************************
364 *
365 * FUNCTION: acpi_ex_create_table_region
366 *
367 * PARAMETERS: walk_state - Current state
368 *
369 * RETURN: Status
370 *
371 * DESCRIPTION: Create a new data_table_region object
372 *
373 ****************************************************************************/
374
375acpi_status
376acpi_ex_create_table_region (
377 struct acpi_walk_state *walk_state)
378{
379 acpi_status status;
380 union acpi_operand_object **operand = &walk_state->operands[0];
381 union acpi_operand_object *obj_desc;
382 struct acpi_namespace_node *node;
383 struct acpi_table_header *table;
384 union acpi_operand_object *region_obj2;
385
386
387 ACPI_FUNCTION_TRACE ("ex_create_table_region");
388
389
390 /* Get the Node from the object stack */
391
392 node = walk_state->op->common.node;
393
394 /*
395 * If the region object is already attached to this node,
396 * just return
397 */
398 if (acpi_ns_get_attached_object (node)) {
399 return_ACPI_STATUS (AE_OK);
400 }
401
402 /* Find the ACPI table */
403
404 status = acpi_tb_find_table (operand[1]->string.pointer,
405 operand[2]->string.pointer,
406 operand[3]->string.pointer, &table);
407 if (ACPI_FAILURE (status)) {
408 return_ACPI_STATUS (status);
409 }
410
411 /* Create the region descriptor */
412
413 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION);
414 if (!obj_desc) {
415 return_ACPI_STATUS (AE_NO_MEMORY);
416 }
417
418 region_obj2 = obj_desc->common.next_object;
419 region_obj2->extra.region_context = NULL;
420
421 /* Init the region from the operands */
422
423 obj_desc->region.space_id = REGION_DATA_TABLE;
424 obj_desc->region.address = (acpi_physical_address) ACPI_TO_INTEGER (table);
425 obj_desc->region.length = table->length;
426 obj_desc->region.node = node;
427 obj_desc->region.flags = AOPOBJ_DATA_VALID;
428
429 /* Install the new region object in the parent Node */
430
431 status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_REGION);
432 if (ACPI_FAILURE (status)) {
433 goto cleanup;
434 }
435
436 status = acpi_ev_initialize_region (obj_desc, FALSE);
437 if (ACPI_FAILURE (status)) {
438 if (status == AE_NOT_EXIST) {
439 status = AE_OK;
440 }
441 else {
442 goto cleanup;
443 }
444 }
445
446 obj_desc->region.flags |= AOPOBJ_SETUP_COMPLETE;
447
448
449cleanup:
450
451 /* Remove local reference to the object */
452
453 acpi_ut_remove_reference (obj_desc);
454 return_ACPI_STATUS (status);
455}
456
457
458/*****************************************************************************
459 *
460 * FUNCTION: acpi_ex_create_processor
461 *
462 * PARAMETERS: walk_state - Current state
463 *
464 * RETURN: Status
465 *
466 * DESCRIPTION: Create a new processor object and populate the fields
467 *
468 * Processor (Name[0], cpu_iD[1], pblock_addr[2], pblock_length[3])
469 *
470 ****************************************************************************/
471
472acpi_status
473acpi_ex_create_processor (
474 struct acpi_walk_state *walk_state)
475{
476 union acpi_operand_object **operand = &walk_state->operands[0];
477 union acpi_operand_object *obj_desc;
478 acpi_status status;
479
480
481 ACPI_FUNCTION_TRACE_PTR ("ex_create_processor", walk_state);
482
483
484 /* Create the processor object */
485
486 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PROCESSOR);
487 if (!obj_desc) {
488 return_ACPI_STATUS (AE_NO_MEMORY);
489 }
490
491 /*
492 * Initialize the processor object from the operands
493 */
494 obj_desc->processor.proc_id = (u8) operand[1]->integer.value;
495 obj_desc->processor.address = (acpi_io_address) operand[2]->integer.value;
496 obj_desc->processor.length = (u8) operand[3]->integer.value;
497
498 /* Install the processor object in the parent Node */
499
500 status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
501 obj_desc, ACPI_TYPE_PROCESSOR);
502
503 /* Remove local reference to the object */
504
505 acpi_ut_remove_reference (obj_desc);
506 return_ACPI_STATUS (status);
507}
508
509
510/*****************************************************************************
511 *
512 * FUNCTION: acpi_ex_create_power_resource
513 *
514 * PARAMETERS: walk_state - Current state
515 *
516 * RETURN: Status
517 *
518 * DESCRIPTION: Create a new power_resource object and populate the fields
519 *
520 * power_resource (Name[0], system_level[1], resource_order[2])
521 *
522 ****************************************************************************/
523
524acpi_status
525acpi_ex_create_power_resource (
526 struct acpi_walk_state *walk_state)
527{
528 union acpi_operand_object **operand = &walk_state->operands[0];
529 acpi_status status;
530 union acpi_operand_object *obj_desc;
531
532
533 ACPI_FUNCTION_TRACE_PTR ("ex_create_power_resource", walk_state);
534
535
536 /* Create the power resource object */
537
538 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_POWER);
539 if (!obj_desc) {
540 return_ACPI_STATUS (AE_NO_MEMORY);
541 }
542
543 /* Initialize the power object from the operands */
544
545 obj_desc->power_resource.system_level = (u8) operand[1]->integer.value;
546 obj_desc->power_resource.resource_order = (u16) operand[2]->integer.value;
547
548 /* Install the power resource object in the parent Node */
549
550 status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
551 obj_desc, ACPI_TYPE_POWER);
552
553 /* Remove local reference to the object */
554
555 acpi_ut_remove_reference (obj_desc);
556 return_ACPI_STATUS (status);
557}
558
559#endif
560
561/*****************************************************************************
562 *
563 * FUNCTION: acpi_ex_create_method
564 *
565 * PARAMETERS: aml_start - First byte of the method's AML
566 * aml_length - AML byte count for this method
567 * walk_state - Current state
568 *
569 * RETURN: Status
570 *
571 * DESCRIPTION: Create a new method object
572 *
573 ****************************************************************************/
574
575acpi_status
576acpi_ex_create_method (
577 u8 *aml_start,
578 u32 aml_length,
579 struct acpi_walk_state *walk_state)
580{
581 union acpi_operand_object **operand = &walk_state->operands[0];
582 union acpi_operand_object *obj_desc;
583 acpi_status status;
584 u8 method_flags;
585
586
587 ACPI_FUNCTION_TRACE_PTR ("ex_create_method", walk_state);
588
589
590 /* Create a new method object */
591
592 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_METHOD);
593 if (!obj_desc) {
594 return_ACPI_STATUS (AE_NO_MEMORY);
595 }
596
597 /* Save the method's AML pointer and length */
598
599 obj_desc->method.aml_start = aml_start;
600 obj_desc->method.aml_length = aml_length;
601
602 /*
603 * Disassemble the method flags. Split off the Arg Count
604 * for efficiency
605 */
606 method_flags = (u8) operand[1]->integer.value;
607
608 obj_desc->method.method_flags = (u8) (method_flags & ~AML_METHOD_ARG_COUNT);
609 obj_desc->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT);
610
611 /*
612 * Get the concurrency count. If required, a semaphore will be
613 * created for this method when it is parsed.
614 */
615 if (acpi_gbl_all_methods_serialized) {
616 obj_desc->method.concurrency = 1;
617 obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;
618 }
619 else if (method_flags & AML_METHOD_SERIALIZED) {
620 /*
621 * ACPI 1.0: Concurrency = 1
622 * ACPI 2.0: Concurrency = (sync_level (in method declaration) + 1)
623 */
624 obj_desc->method.concurrency = (u8)
625 (((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1);
626 }
627 else {
628 obj_desc->method.concurrency = ACPI_INFINITE_CONCURRENCY;
629 }
630
631 /* Attach the new object to the method Node */
632
633 status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
634 obj_desc, ACPI_TYPE_METHOD);
635
636 /* Remove local reference to the object */
637
638 acpi_ut_remove_reference (obj_desc);
639
640 /* Remove a reference to the operand */
641
642 acpi_ut_remove_reference (operand[1]);
643 return_ACPI_STATUS (status);
644}
645
646
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
new file mode 100644
index 000000000000..e2f7c32f28de
--- /dev/null
+++ b/drivers/acpi/executer/exdump.c
@@ -0,0 +1,793 @@
1/******************************************************************************
2 *
3 * Module Name: exdump - Interpreter debug output routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <acpi/acpi.h>
46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h>
48#include <acpi/acnamesp.h>
49#include <acpi/acparser.h>
50
51#define _COMPONENT ACPI_EXECUTER
52 ACPI_MODULE_NAME ("exdump")
53
54
55/*
56 * The following routines are used for debug output only
57 */
58#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
59
60/*****************************************************************************
61 *
62 * FUNCTION: acpi_ex_dump_operand
63 *
64 * PARAMETERS: *obj_desc - Pointer to entry to be dumped
65 *
66 * RETURN: None
67 *
68 * DESCRIPTION: Dump an operand object
69 *
70 ****************************************************************************/
71
72void
73acpi_ex_dump_operand (
74 union acpi_operand_object *obj_desc,
75 u32 depth)
76{
77 u32 length;
78 u32 index;
79
80
81 ACPI_FUNCTION_NAME ("ex_dump_operand")
82
83
84 if (!((ACPI_LV_EXEC & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
85 return;
86 }
87
88 if (!obj_desc) {
89 /*
90 * This could be a null element of a package
91 */
92 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Null Object Descriptor\n"));
93 return;
94 }
95
96 if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
97 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is a NS Node: ", obj_desc));
98 ACPI_DUMP_ENTRY (obj_desc, ACPI_LV_EXEC);
99 return;
100 }
101
102 if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
103 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
104 "%p is not a node or operand object: [%s]\n",
105 obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
106 ACPI_DUMP_BUFFER (obj_desc, sizeof (union acpi_operand_object));
107 return;
108 }
109
110 /* obj_desc is a valid object */
111
112 if (depth > 0) {
113 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%*s[%u] %p ",
114 depth, " ", depth, obj_desc));
115 }
116 else {
117 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
118 }
119
120 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
121 case ACPI_TYPE_LOCAL_REFERENCE:
122
123 switch (obj_desc->reference.opcode) {
124 case AML_DEBUG_OP:
125
126 acpi_os_printf ("Reference: Debug\n");
127 break;
128
129
130 case AML_NAME_OP:
131
132 ACPI_DUMP_PATHNAME (obj_desc->reference.object,
133 "Reference: Name: ", ACPI_LV_INFO, _COMPONENT);
134 ACPI_DUMP_ENTRY (obj_desc->reference.object, ACPI_LV_INFO);
135 break;
136
137
138 case AML_INDEX_OP:
139
140 acpi_os_printf ("Reference: Index %p\n",
141 obj_desc->reference.object);
142 break;
143
144
145 case AML_REF_OF_OP:
146
147 acpi_os_printf ("Reference: (ref_of) %p\n",
148 obj_desc->reference.object);
149 break;
150
151
152 case AML_ARG_OP:
153
154 acpi_os_printf ("Reference: Arg%d",
155 obj_desc->reference.offset);
156
157 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
158 /* Value is an Integer */
159
160 acpi_os_printf (" value is [%8.8X%8.8x]",
161 ACPI_FORMAT_UINT64 (obj_desc->integer.value));
162 }
163
164 acpi_os_printf ("\n");
165 break;
166
167
168 case AML_LOCAL_OP:
169
170 acpi_os_printf ("Reference: Local%d",
171 obj_desc->reference.offset);
172
173 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
174
175 /* Value is an Integer */
176
177 acpi_os_printf (" value is [%8.8X%8.8x]",
178 ACPI_FORMAT_UINT64 (obj_desc->integer.value));
179 }
180
181 acpi_os_printf ("\n");
182 break;
183
184
185 case AML_INT_NAMEPATH_OP:
186
187 acpi_os_printf ("Reference.Node->Name %X\n",
188 obj_desc->reference.node->name.integer);
189 break;
190
191
192 default:
193
194 /* Unknown opcode */
195
196 acpi_os_printf ("Unknown Reference opcode=%X\n",
197 obj_desc->reference.opcode);
198 break;
199
200 }
201 break;
202
203
204 case ACPI_TYPE_BUFFER:
205
206 acpi_os_printf ("Buffer len %X @ %p \n",
207 obj_desc->buffer.length, obj_desc->buffer.pointer);
208
209 length = obj_desc->buffer.length;
210 if (length > 64) {
211 length = 64;
212 }
213
214 /* Debug only -- dump the buffer contents */
215
216 if (obj_desc->buffer.pointer) {
217 acpi_os_printf ("Buffer Contents: ");
218
219 for (index = 0; index < length; index++) {
220 acpi_os_printf (" %02x", obj_desc->buffer.pointer[index]);
221 }
222 acpi_os_printf ("\n");
223 }
224 break;
225
226
227 case ACPI_TYPE_INTEGER:
228
229 acpi_os_printf ("Integer %8.8X%8.8X\n",
230 ACPI_FORMAT_UINT64 (obj_desc->integer.value));
231 break;
232
233
234 case ACPI_TYPE_PACKAGE:
235
236 acpi_os_printf ("Package [Len %X] element_array %p\n",
237 obj_desc->package.count, obj_desc->package.elements);
238
239 /*
240 * If elements exist, package element pointer is valid,
241 * and debug_level exceeds 1, dump package's elements.
242 */
243 if (obj_desc->package.count &&
244 obj_desc->package.elements &&
245 acpi_dbg_level > 1) {
246 for (index = 0; index < obj_desc->package.count; index++) {
247 acpi_ex_dump_operand (obj_desc->package.elements[index], depth+1);
248 }
249 }
250 break;
251
252
253 case ACPI_TYPE_REGION:
254
255 acpi_os_printf ("Region %s (%X)",
256 acpi_ut_get_region_name (obj_desc->region.space_id),
257 obj_desc->region.space_id);
258
259 /*
260 * If the address and length have not been evaluated,
261 * don't print them.
262 */
263 if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) {
264 acpi_os_printf ("\n");
265 }
266 else {
267 acpi_os_printf (" base %8.8X%8.8X Length %X\n",
268 ACPI_FORMAT_UINT64 (obj_desc->region.address),
269 obj_desc->region.length);
270 }
271 break;
272
273
274 case ACPI_TYPE_STRING:
275
276 acpi_os_printf ("String length %X @ %p ",
277 obj_desc->string.length, obj_desc->string.pointer);
278 acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
279 acpi_os_printf ("\n");
280 break;
281
282
283 case ACPI_TYPE_LOCAL_BANK_FIELD:
284
285 acpi_os_printf ("bank_field\n");
286 break;
287
288
289 case ACPI_TYPE_LOCAL_REGION_FIELD:
290
291 acpi_os_printf (
292 "region_field: Bits=%X acc_width=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
293 obj_desc->field.bit_length, obj_desc->field.access_byte_width,
294 obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
295 obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
296 obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset);
297 acpi_ex_dump_operand (obj_desc->field.region_obj, depth+1);
298 break;
299
300
301 case ACPI_TYPE_LOCAL_INDEX_FIELD:
302
303 acpi_os_printf ("index_field\n");
304 break;
305
306
307 case ACPI_TYPE_BUFFER_FIELD:
308
309 acpi_os_printf (
310 "buffer_field: %X bits at byte %X bit %X of \n",
311 obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset,
312 obj_desc->buffer_field.start_field_bit_offset);
313
314 if (!obj_desc->buffer_field.buffer_obj) {
315 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*NULL* \n"));
316 }
317 else if (ACPI_GET_OBJECT_TYPE (obj_desc->buffer_field.buffer_obj) != ACPI_TYPE_BUFFER) {
318 acpi_os_printf ("*not a Buffer* \n");
319 }
320 else {
321 acpi_ex_dump_operand (obj_desc->buffer_field.buffer_obj, depth+1);
322 }
323 break;
324
325
326 case ACPI_TYPE_EVENT:
327
328 acpi_os_printf ("Event\n");
329 break;
330
331
332 case ACPI_TYPE_METHOD:
333
334 acpi_os_printf (
335 "Method(%X) @ %p:%X\n",
336 obj_desc->method.param_count,
337 obj_desc->method.aml_start, obj_desc->method.aml_length);
338 break;
339
340
341 case ACPI_TYPE_MUTEX:
342
343 acpi_os_printf ("Mutex\n");
344 break;
345
346
347 case ACPI_TYPE_DEVICE:
348
349 acpi_os_printf ("Device\n");
350 break;
351
352
353 case ACPI_TYPE_POWER:
354
355 acpi_os_printf ("Power\n");
356 break;
357
358
359 case ACPI_TYPE_PROCESSOR:
360
361 acpi_os_printf ("Processor\n");
362 break;
363
364
365 case ACPI_TYPE_THERMAL:
366
367 acpi_os_printf ("Thermal\n");
368 break;
369
370
371 default:
372 /* Unknown Type */
373
374 acpi_os_printf ("Unknown Type %X\n", ACPI_GET_OBJECT_TYPE (obj_desc));
375 break;
376 }
377
378 return;
379}
380
381
382/*****************************************************************************
383 *
384 * FUNCTION: acpi_ex_dump_operands
385 *
386 * PARAMETERS: Operands - Operand list
387 * interpreter_mode - Load or Exec
388 * Ident - Identification
389 * num_levels - # of stack entries to dump above line
390 * Note - Output notation
391 * module_name - Caller's module name
392 * line_number - Caller's invocation line number
393 *
394 * DESCRIPTION: Dump the object stack
395 *
396 ****************************************************************************/
397
398void
399acpi_ex_dump_operands (
400 union acpi_operand_object **operands,
401 acpi_interpreter_mode interpreter_mode,
402 char *ident,
403 u32 num_levels,
404 char *note,
405 char *module_name,
406 u32 line_number)
407{
408 acpi_native_uint i;
409
410
411 ACPI_FUNCTION_NAME ("ex_dump_operands");
412
413
414 if (!ident) {
415 ident = "?";
416 }
417
418 if (!note) {
419 note = "?";
420 }
421
422 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
423 "************* Operand Stack Contents (Opcode [%s], %d Operands)\n",
424 ident, num_levels));
425
426 if (num_levels == 0) {
427 num_levels = 1;
428 }
429
430 /* Dump the operand stack starting at the top */
431
432 for (i = 0; num_levels > 0; i--, num_levels--) {
433 acpi_ex_dump_operand (operands[i], 0);
434 }
435
436 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
437 "************* Stack dump from %s(%d), %s\n",
438 module_name, line_number, note));
439 return;
440}
441
442
443#ifdef ACPI_FUTURE_USAGE
444
445/*****************************************************************************
446 *
447 * FUNCTION: acpi_ex_out*
448 *
449 * PARAMETERS: Title - Descriptive text
450 * Value - Value to be displayed
451 *
452 * DESCRIPTION: Object dump output formatting functions. These functions
453 * reduce the number of format strings required and keeps them
454 * all in one place for easy modification.
455 *
456 ****************************************************************************/
457
458void
459acpi_ex_out_string (
460 char *title,
461 char *value)
462{
463 acpi_os_printf ("%20s : %s\n", title, value);
464}
465
466void
467acpi_ex_out_pointer (
468 char *title,
469 void *value)
470{
471 acpi_os_printf ("%20s : %p\n", title, value);
472}
473
474void
475acpi_ex_out_integer (
476 char *title,
477 u32 value)
478{
479 acpi_os_printf ("%20s : %X\n", title, value);
480}
481
482void
483acpi_ex_out_address (
484 char *title,
485 acpi_physical_address value)
486{
487
488#if ACPI_MACHINE_WIDTH == 16
489 acpi_os_printf ("%20s : %p\n", title, value);
490#else
491 acpi_os_printf ("%20s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64 (value));
492#endif
493}
494
495
496/*****************************************************************************
497 *
498 * FUNCTION: acpi_ex_dump_node
499 *
500 * PARAMETERS: *Node - Descriptor to dump
501 * Flags - Force display
502 *
503 * DESCRIPTION: Dumps the members of the given.Node
504 *
505 ****************************************************************************/
506
507void
508acpi_ex_dump_node (
509 struct acpi_namespace_node *node,
510 u32 flags)
511{
512
513 ACPI_FUNCTION_ENTRY ();
514
515
516 if (!flags) {
517 if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
518 return;
519 }
520 }
521
522 acpi_os_printf ("%20s : %4.4s\n", "Name", acpi_ut_get_node_name (node));
523 acpi_ex_out_string ("Type", acpi_ut_get_type_name (node->type));
524 acpi_ex_out_integer ("Flags", node->flags);
525 acpi_ex_out_integer ("Owner Id", node->owner_id);
526 acpi_ex_out_integer ("Reference Count", node->reference_count);
527 acpi_ex_out_pointer ("Attached Object", acpi_ns_get_attached_object (node));
528 acpi_ex_out_pointer ("child_list", node->child);
529 acpi_ex_out_pointer ("next_peer", node->peer);
530 acpi_ex_out_pointer ("Parent", acpi_ns_get_parent_node (node));
531}
532
533
534/*****************************************************************************
535 *
536 * FUNCTION: acpi_ex_dump_object_descriptor
537 *
538 * PARAMETERS: *Object - Descriptor to dump
539 * Flags - Force display
540 *
541 * DESCRIPTION: Dumps the members of the object descriptor given.
542 *
543 ****************************************************************************/
544
545void
546acpi_ex_dump_object_descriptor (
547 union acpi_operand_object *obj_desc,
548 u32 flags)
549{
550 u32 i;
551
552
553 ACPI_FUNCTION_TRACE ("ex_dump_object_descriptor");
554
555
556 if (!flags) {
557 if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
558 return_VOID;
559 }
560 }
561
562 if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
563 acpi_ex_dump_node ((struct acpi_namespace_node *) obj_desc, flags);
564 acpi_os_printf ("\nAttached Object (%p):\n",
565 ((struct acpi_namespace_node *) obj_desc)->object);
566 acpi_ex_dump_object_descriptor (
567 ((struct acpi_namespace_node *) obj_desc)->object, flags);
568 return_VOID;
569 }
570
571 if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
572 acpi_os_printf (
573 "ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n",
574 obj_desc, acpi_ut_get_descriptor_name (obj_desc));
575 return_VOID;
576 }
577
578 /* Common Fields */
579
580 acpi_ex_out_string ("Type", acpi_ut_get_object_type_name (obj_desc));
581 acpi_ex_out_integer ("Reference Count", obj_desc->common.reference_count);
582 acpi_ex_out_integer ("Flags", obj_desc->common.flags);
583
584 /* Object-specific Fields */
585
586 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
587 case ACPI_TYPE_INTEGER:
588
589 acpi_os_printf ("%20s : %8.8X%8.8X\n", "Value",
590 ACPI_FORMAT_UINT64 (obj_desc->integer.value));
591 break;
592
593
594 case ACPI_TYPE_STRING:
595
596 acpi_ex_out_integer ("Length", obj_desc->string.length);
597
598 acpi_os_printf ("%20s : %p ", "Pointer", obj_desc->string.pointer);
599 acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
600 acpi_os_printf ("\n");
601 break;
602
603
604 case ACPI_TYPE_BUFFER:
605
606 acpi_ex_out_integer ("Length", obj_desc->buffer.length);
607 acpi_ex_out_pointer ("Pointer", obj_desc->buffer.pointer);
608 ACPI_DUMP_BUFFER (obj_desc->buffer.pointer, obj_desc->buffer.length);
609 break;
610
611
612 case ACPI_TYPE_PACKAGE:
613
614 acpi_ex_out_integer ("Flags", obj_desc->package.flags);
615 acpi_ex_out_integer ("Count", obj_desc->package.count);
616 acpi_ex_out_pointer ("Elements", obj_desc->package.elements);
617
618 /* Dump the package contents */
619
620 if (obj_desc->package.count > 0) {
621 acpi_os_printf ("\nPackage Contents:\n");
622 for (i = 0; i < obj_desc->package.count; i++) {
623 acpi_os_printf ("[%.3d] %p", i, obj_desc->package.elements[i]);
624 if (obj_desc->package.elements[i]) {
625 acpi_os_printf (" %s",
626 acpi_ut_get_object_type_name (obj_desc->package.elements[i]));
627 }
628 acpi_os_printf ("\n");
629 }
630 }
631 break;
632
633
634 case ACPI_TYPE_DEVICE:
635
636 acpi_ex_out_pointer ("Handler", obj_desc->device.handler);
637 acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify);
638 acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify);
639 break;
640
641
642 case ACPI_TYPE_EVENT:
643
644 acpi_ex_out_pointer ("Semaphore", obj_desc->event.semaphore);
645 break;
646
647
648 case ACPI_TYPE_METHOD:
649
650 acpi_ex_out_integer ("param_count", obj_desc->method.param_count);
651 acpi_ex_out_integer ("Concurrency", obj_desc->method.concurrency);
652 acpi_ex_out_pointer ("Semaphore", obj_desc->method.semaphore);
653 acpi_ex_out_integer ("owning_id", obj_desc->method.owning_id);
654 acpi_ex_out_integer ("aml_length", obj_desc->method.aml_length);
655 acpi_ex_out_pointer ("aml_start", obj_desc->method.aml_start);
656 break;
657
658
659 case ACPI_TYPE_MUTEX:
660
661 acpi_ex_out_integer ("sync_level", obj_desc->mutex.sync_level);
662 acpi_ex_out_pointer ("owner_thread", obj_desc->mutex.owner_thread);
663 acpi_ex_out_integer ("acquire_depth", obj_desc->mutex.acquisition_depth);
664 acpi_ex_out_pointer ("Semaphore", obj_desc->mutex.semaphore);
665 break;
666
667
668 case ACPI_TYPE_REGION:
669
670 acpi_ex_out_integer ("space_id", obj_desc->region.space_id);
671 acpi_ex_out_integer ("Flags", obj_desc->region.flags);
672 acpi_ex_out_address ("Address", obj_desc->region.address);
673 acpi_ex_out_integer ("Length", obj_desc->region.length);
674 acpi_ex_out_pointer ("Handler", obj_desc->region.handler);
675 acpi_ex_out_pointer ("Next", obj_desc->region.next);
676 break;
677
678
679 case ACPI_TYPE_POWER:
680
681 acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level);
682 acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order);
683 acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify);
684 acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify);
685 break;
686
687
688 case ACPI_TYPE_PROCESSOR:
689
690 acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id);
691 acpi_ex_out_integer ("Length", obj_desc->processor.length);
692 acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address);
693 acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify);
694 acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify);
695 acpi_ex_out_pointer ("Handler", obj_desc->processor.handler);
696 break;
697
698
699 case ACPI_TYPE_THERMAL:
700
701 acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify);
702 acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify);
703 acpi_ex_out_pointer ("Handler", obj_desc->thermal_zone.handler);
704 break;
705
706
707 case ACPI_TYPE_BUFFER_FIELD:
708 case ACPI_TYPE_LOCAL_REGION_FIELD:
709 case ACPI_TYPE_LOCAL_BANK_FIELD:
710 case ACPI_TYPE_LOCAL_INDEX_FIELD:
711
712 acpi_ex_out_integer ("field_flags", obj_desc->common_field.field_flags);
713 acpi_ex_out_integer ("access_byte_width",obj_desc->common_field.access_byte_width);
714 acpi_ex_out_integer ("bit_length", obj_desc->common_field.bit_length);
715 acpi_ex_out_integer ("fld_bit_offset", obj_desc->common_field.start_field_bit_offset);
716 acpi_ex_out_integer ("base_byte_offset", obj_desc->common_field.base_byte_offset);
717 acpi_ex_out_pointer ("parent_node", obj_desc->common_field.node);
718
719 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
720 case ACPI_TYPE_BUFFER_FIELD:
721 acpi_ex_out_pointer ("buffer_obj", obj_desc->buffer_field.buffer_obj);
722 break;
723
724 case ACPI_TYPE_LOCAL_REGION_FIELD:
725 acpi_ex_out_pointer ("region_obj", obj_desc->field.region_obj);
726 break;
727
728 case ACPI_TYPE_LOCAL_BANK_FIELD:
729 acpi_ex_out_integer ("Value", obj_desc->bank_field.value);
730 acpi_ex_out_pointer ("region_obj", obj_desc->bank_field.region_obj);
731 acpi_ex_out_pointer ("bank_obj", obj_desc->bank_field.bank_obj);
732 break;
733
734 case ACPI_TYPE_LOCAL_INDEX_FIELD:
735 acpi_ex_out_integer ("Value", obj_desc->index_field.value);
736 acpi_ex_out_pointer ("Index", obj_desc->index_field.index_obj);
737 acpi_ex_out_pointer ("Data", obj_desc->index_field.data_obj);
738 break;
739
740 default:
741 /* All object types covered above */
742 break;
743 }
744 break;
745
746
747 case ACPI_TYPE_LOCAL_REFERENCE:
748
749 acpi_ex_out_integer ("target_type", obj_desc->reference.target_type);
750 acpi_ex_out_string ("Opcode", (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name);
751 acpi_ex_out_integer ("Offset", obj_desc->reference.offset);
752 acpi_ex_out_pointer ("obj_desc", obj_desc->reference.object);
753 acpi_ex_out_pointer ("Node", obj_desc->reference.node);
754 acpi_ex_out_pointer ("Where", obj_desc->reference.where);
755 break;
756
757
758 case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
759
760 acpi_ex_out_integer ("space_id", obj_desc->address_space.space_id);
761 acpi_ex_out_pointer ("Next", obj_desc->address_space.next);
762 acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list);
763 acpi_ex_out_pointer ("Node", obj_desc->address_space.node);
764 acpi_ex_out_pointer ("Context", obj_desc->address_space.context);
765 break;
766
767
768 case ACPI_TYPE_LOCAL_NOTIFY:
769
770 acpi_ex_out_pointer ("Node", obj_desc->notify.node);
771 acpi_ex_out_pointer ("Context", obj_desc->notify.context);
772 break;
773
774
775 case ACPI_TYPE_LOCAL_ALIAS:
776 case ACPI_TYPE_LOCAL_METHOD_ALIAS:
777 case ACPI_TYPE_LOCAL_EXTRA:
778 case ACPI_TYPE_LOCAL_DATA:
779 default:
780
781 acpi_os_printf (
782 "ex_dump_object_descriptor: Display not implemented for object type %s\n",
783 acpi_ut_get_object_type_name (obj_desc));
784 break;
785 }
786
787 return_VOID;
788}
789
790#endif /* ACPI_FUTURE_USAGE */
791
792#endif
793
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
new file mode 100644
index 000000000000..be7f2124fa02
--- /dev/null
+++ b/drivers/acpi/executer/exfield.c
@@ -0,0 +1,367 @@
1/******************************************************************************
2 *
3 * Module Name: exfield - ACPI AML (p-code) execution - field manipulation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <acpi/acpi.h>
46#include <acpi/acdispat.h>
47#include <acpi/acinterp.h>
48
49
50#define _COMPONENT ACPI_EXECUTER
51 ACPI_MODULE_NAME ("exfield")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ex_read_data_from_field
57 *
58 * PARAMETERS: walk_state - Current execution state
59 * obj_desc - The named field
60 * ret_buffer_desc - Where the return data object is stored
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Read from a named field. Returns either an Integer or a
65 * Buffer, depending on the size of the field.
66 *
67 ******************************************************************************/
68
69acpi_status
70acpi_ex_read_data_from_field (
71 struct acpi_walk_state *walk_state,
72 union acpi_operand_object *obj_desc,
73 union acpi_operand_object **ret_buffer_desc)
74{
75 acpi_status status;
76 union acpi_operand_object *buffer_desc;
77 acpi_size length;
78 void *buffer;
79 u8 locked;
80
81
82 ACPI_FUNCTION_TRACE_PTR ("ex_read_data_from_field", obj_desc);
83
84
85 /* Parameter validation */
86
87 if (!obj_desc) {
88 return_ACPI_STATUS (AE_AML_NO_OPERAND);
89 }
90
91 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
92 /*
93 * If the buffer_field arguments have not been previously evaluated,
94 * evaluate them now and save the results.
95 */
96 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
97 status = acpi_ds_get_buffer_field_arguments (obj_desc);
98 if (ACPI_FAILURE (status)) {
99 return_ACPI_STATUS (status);
100 }
101 }
102 }
103 else if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) &&
104 (obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_SMBUS)) {
105 /*
106 * This is an SMBus read. We must create a buffer to hold the data
107 * and directly access the region handler.
108 */
109 buffer_desc = acpi_ut_create_buffer_object (ACPI_SMBUS_BUFFER_SIZE);
110 if (!buffer_desc) {
111 return_ACPI_STATUS (AE_NO_MEMORY);
112 }
113
114 /* Lock entire transaction if requested */
115
116 locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
117
118 /*
119 * Perform the read.
120 * Note: Smbus protocol value is passed in upper 16-bits of Function
121 */
122 status = acpi_ex_access_region (obj_desc, 0,
123 ACPI_CAST_PTR (acpi_integer, buffer_desc->buffer.pointer),
124 ACPI_READ | (obj_desc->field.attribute << 16));
125 acpi_ex_release_global_lock (locked);
126 goto exit;
127 }
128
129 /*
130 * Allocate a buffer for the contents of the field.
131 *
132 * If the field is larger than the size of an acpi_integer, create
133 * a BUFFER to hold it. Otherwise, use an INTEGER. This allows
134 * the use of arithmetic operators on the returned value if the
135 * field size is equal or smaller than an Integer.
136 *
137 * Note: Field.length is in bits.
138 */
139 length = (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->field.bit_length);
140 if (length > acpi_gbl_integer_byte_width) {
141 /* Field is too large for an Integer, create a Buffer instead */
142
143 buffer_desc = acpi_ut_create_buffer_object (length);
144 if (!buffer_desc) {
145 return_ACPI_STATUS (AE_NO_MEMORY);
146 }
147 buffer = buffer_desc->buffer.pointer;
148 }
149 else {
150 /* Field will fit within an Integer (normal case) */
151
152 buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
153 if (!buffer_desc) {
154 return_ACPI_STATUS (AE_NO_MEMORY);
155 }
156
157 length = acpi_gbl_integer_byte_width;
158 buffer_desc->integer.value = 0;
159 buffer = &buffer_desc->integer.value;
160 }
161
162 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
163 "field_read [TO]: Obj %p, Type %X, Buf %p, byte_len %X\n",
164 obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, (u32) length));
165 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
166 "field_read [FROM]: bit_len %X, bit_off %X, byte_off %X\n",
167 obj_desc->common_field.bit_length,
168 obj_desc->common_field.start_field_bit_offset,
169 obj_desc->common_field.base_byte_offset));
170
171 /* Lock entire transaction if requested */
172
173 locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
174
175 /* Read from the field */
176
177 status = acpi_ex_extract_from_field (obj_desc, buffer, (u32) length);
178 acpi_ex_release_global_lock (locked);
179
180
181exit:
182 if (ACPI_FAILURE (status)) {
183 acpi_ut_remove_reference (buffer_desc);
184 }
185 else if (ret_buffer_desc) {
186 *ret_buffer_desc = buffer_desc;
187 }
188
189 return_ACPI_STATUS (status);
190}
191
192
193/*******************************************************************************
194 *
195 * FUNCTION: acpi_ex_write_data_to_field
196 *
197 * PARAMETERS: source_desc - Contains data to write
198 * obj_desc - The named field
199 *
200 * RETURN: Status
201 *
202 * DESCRIPTION: Write to a named field
203 *
204 ******************************************************************************/
205
206acpi_status
207acpi_ex_write_data_to_field (
208 union acpi_operand_object *source_desc,
209 union acpi_operand_object *obj_desc,
210 union acpi_operand_object **result_desc)
211{
212 acpi_status status;
213 u32 length;
214 u32 required_length;
215 void *buffer;
216 void *new_buffer;
217 u8 locked;
218 union acpi_operand_object *buffer_desc;
219
220
221 ACPI_FUNCTION_TRACE_PTR ("ex_write_data_to_field", obj_desc);
222
223
224 /* Parameter validation */
225
226 if (!source_desc || !obj_desc) {
227 return_ACPI_STATUS (AE_AML_NO_OPERAND);
228 }
229
230 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
231 /*
232 * If the buffer_field arguments have not been previously evaluated,
233 * evaluate them now and save the results.
234 */
235 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
236 status = acpi_ds_get_buffer_field_arguments (obj_desc);
237 if (ACPI_FAILURE (status)) {
238 return_ACPI_STATUS (status);
239 }
240 }
241 }
242 else if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) &&
243 (obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_SMBUS)) {
244 /*
245 * This is an SMBus write. We will bypass the entire field mechanism
246 * and handoff the buffer directly to the handler.
247 *
248 * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
249 */
250 if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
251 ACPI_REPORT_ERROR (("SMBus write requires Buffer, found type %s\n",
252 acpi_ut_get_object_type_name (source_desc)));
253 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
254 }
255
256 if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) {
257 ACPI_REPORT_ERROR (("SMBus write requires Buffer of length %X, found length %X\n",
258 ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length));
259 return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
260 }
261
262 buffer_desc = acpi_ut_create_buffer_object (ACPI_SMBUS_BUFFER_SIZE);
263 if (!buffer_desc) {
264 return_ACPI_STATUS (AE_NO_MEMORY);
265 }
266
267 buffer = buffer_desc->buffer.pointer;
268 ACPI_MEMCPY (buffer, source_desc->buffer.pointer, ACPI_SMBUS_BUFFER_SIZE);
269
270 /* Lock entire transaction if requested */
271
272 locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
273
274 /*
275 * Perform the write (returns status and perhaps data in the same buffer)
276 * Note: SMBus protocol type is passed in upper 16-bits of Function.
277 */
278 status = acpi_ex_access_region (obj_desc, 0,
279 (acpi_integer *) buffer,
280 ACPI_WRITE | (obj_desc->field.attribute << 16));
281 acpi_ex_release_global_lock (locked);
282
283 *result_desc = buffer_desc;
284 return_ACPI_STATUS (status);
285 }
286
287 /*
288 * Get a pointer to the data to be written
289 */
290 switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
291 case ACPI_TYPE_INTEGER:
292 buffer = &source_desc->integer.value;
293 length = sizeof (source_desc->integer.value);
294 break;
295
296 case ACPI_TYPE_BUFFER:
297 buffer = source_desc->buffer.pointer;
298 length = source_desc->buffer.length;
299 break;
300
301 case ACPI_TYPE_STRING:
302 buffer = source_desc->string.pointer;
303 length = source_desc->string.length;
304 break;
305
306 default:
307 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
308 }
309
310 /*
311 * We must have a buffer that is at least as long as the field
312 * we are writing to. This is because individual fields are
313 * indivisible and partial writes are not supported -- as per
314 * the ACPI specification.
315 */
316 new_buffer = NULL;
317 required_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length);
318
319 if (length < required_length) {
320 /* We need to create a new buffer */
321
322 new_buffer = ACPI_MEM_CALLOCATE (required_length);
323 if (!new_buffer) {
324 return_ACPI_STATUS (AE_NO_MEMORY);
325 }
326
327 /*
328 * Copy the original data to the new buffer, starting
329 * at Byte zero. All unused (upper) bytes of the
330 * buffer will be 0.
331 */
332 ACPI_MEMCPY ((char *) new_buffer, (char *) buffer, length);
333 buffer = new_buffer;
334 length = required_length;
335 }
336
337 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
338 "field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n",
339 source_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (source_desc)),
340 ACPI_GET_OBJECT_TYPE (source_desc), buffer, length));
341 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
342 "field_write [TO]: Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n",
343 obj_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)),
344 ACPI_GET_OBJECT_TYPE (obj_desc),
345 obj_desc->common_field.bit_length,
346 obj_desc->common_field.start_field_bit_offset,
347 obj_desc->common_field.base_byte_offset));
348
349 /* Lock entire transaction if requested */
350
351 locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
352
353 /* Write to the field */
354
355 status = acpi_ex_insert_into_field (obj_desc, buffer, length);
356 acpi_ex_release_global_lock (locked);
357
358 /* Free temporary buffer if we used one */
359
360 if (new_buffer) {
361 ACPI_MEM_FREE (new_buffer);
362 }
363
364 return_ACPI_STATUS (status);
365}
366
367
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
new file mode 100644
index 000000000000..9d0f9d2e9061
--- /dev/null
+++ b/drivers/acpi/executer/exfldio.c
@@ -0,0 +1,835 @@
1/******************************************************************************
2 *
3 * Module Name: exfldio - Aml Field I/O
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <acpi/acpi.h>
46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h>
48#include <acpi/acevents.h>
49#include <acpi/acdispat.h>
50
51
52#define _COMPONENT ACPI_EXECUTER
53 ACPI_MODULE_NAME ("exfldio")
54
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ex_setup_region
59 *
60 * PARAMETERS: *obj_desc - Field to be read or written
61 * field_datum_byte_offset - Byte offset of this datum within the
62 * parent field
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Common processing for acpi_ex_extract_from_field and
67 * acpi_ex_insert_into_field. Initialize the Region if necessary and
68 * validate the request.
69 *
70 ******************************************************************************/
71
72acpi_status
73acpi_ex_setup_region (
74 union acpi_operand_object *obj_desc,
75 u32 field_datum_byte_offset)
76{
77 acpi_status status = AE_OK;
78 union acpi_operand_object *rgn_desc;
79
80
81 ACPI_FUNCTION_TRACE_U32 ("ex_setup_region", field_datum_byte_offset);
82
83
84 rgn_desc = obj_desc->common_field.region_obj;
85
86 /* We must have a valid region */
87
88 if (ACPI_GET_OBJECT_TYPE (rgn_desc) != ACPI_TYPE_REGION) {
89 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X (%s)\n",
90 ACPI_GET_OBJECT_TYPE (rgn_desc),
91 acpi_ut_get_object_type_name (rgn_desc)));
92
93 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
94 }
95
96 /*
97 * If the Region Address and Length have not been previously evaluated,
98 * evaluate them now and save the results.
99 */
100 if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) {
101 status = acpi_ds_get_region_arguments (rgn_desc);
102 if (ACPI_FAILURE (status)) {
103 return_ACPI_STATUS (status);
104 }
105 }
106
107 if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) {
108 /* SMBus has a non-linear address space */
109
110 return_ACPI_STATUS (AE_OK);
111 }
112
113#ifdef ACPI_UNDER_DEVELOPMENT
114 /*
115 * If the Field access is any_acc, we can now compute the optimal
116 * access (because we know know the length of the parent region)
117 */
118 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
119 if (ACPI_FAILURE (status)) {
120 return_ACPI_STATUS (status);
121 }
122 }
123#endif
124
125 /*
126 * Validate the request. The entire request from the byte offset for a
127 * length of one field datum (access width) must fit within the region.
128 * (Region length is specified in bytes)
129 */
130 if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset
131 + field_datum_byte_offset
132 + obj_desc->common_field.access_byte_width)) {
133 if (acpi_gbl_enable_interpreter_slack) {
134 /*
135 * Slack mode only: We will go ahead and allow access to this
136 * field if it is within the region length rounded up to the next
137 * access width boundary.
138 */
139 if (ACPI_ROUND_UP (rgn_desc->region.length,
140 obj_desc->common_field.access_byte_width) >=
141 (obj_desc->common_field.base_byte_offset +
142 (acpi_native_uint) obj_desc->common_field.access_byte_width +
143 field_datum_byte_offset)) {
144 return_ACPI_STATUS (AE_OK);
145 }
146 }
147
148 if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) {
149 /*
150 * This is the case where the access_type (acc_word, etc.) is wider
151 * than the region itself. For example, a region of length one
152 * byte, and a field with Dword access specified.
153 */
154 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
155 "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
156 acpi_ut_get_node_name (obj_desc->common_field.node),
157 obj_desc->common_field.access_byte_width,
158 acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
159 }
160
161 /*
162 * Offset rounded up to next multiple of field width
163 * exceeds region length, indicate an error
164 */
165 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
166 "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n",
167 acpi_ut_get_node_name (obj_desc->common_field.node),
168 obj_desc->common_field.base_byte_offset,
169 field_datum_byte_offset, obj_desc->common_field.access_byte_width,
170 acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
171
172 return_ACPI_STATUS (AE_AML_REGION_LIMIT);
173 }
174
175 return_ACPI_STATUS (AE_OK);
176}
177
178
179/*******************************************************************************
180 *
181 * FUNCTION: acpi_ex_access_region
182 *
183 * PARAMETERS: *obj_desc - Field to be read
184 * field_datum_byte_offset - Byte offset of this datum within the
185 * parent field
186 * *Value - Where to store value (must at least
187 * the size of acpi_integer)
188 * Function - Read or Write flag plus other region-
189 * dependent flags
190 *
191 * RETURN: Status
192 *
193 * DESCRIPTION: Read or Write a single field datum to an Operation Region.
194 *
195 ******************************************************************************/
196
197acpi_status
198acpi_ex_access_region (
199 union acpi_operand_object *obj_desc,
200 u32 field_datum_byte_offset,
201 acpi_integer *value,
202 u32 function)
203{
204 acpi_status status;
205 union acpi_operand_object *rgn_desc;
206 acpi_physical_address address;
207
208
209 ACPI_FUNCTION_TRACE ("ex_access_region");
210
211
212 /*
213 * Ensure that the region operands are fully evaluated and verify
214 * the validity of the request
215 */
216 status = acpi_ex_setup_region (obj_desc, field_datum_byte_offset);
217 if (ACPI_FAILURE (status)) {
218 return_ACPI_STATUS (status);
219 }
220
221 /*
222 * The physical address of this field datum is:
223 *
224 * 1) The base of the region, plus
225 * 2) The base offset of the field, plus
226 * 3) The current offset into the field
227 */
228 rgn_desc = obj_desc->common_field.region_obj;
229 address = rgn_desc->region.address
230 + obj_desc->common_field.base_byte_offset
231 + field_datum_byte_offset;
232
233 if ((function & ACPI_IO_MASK) == ACPI_READ) {
234 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
235 }
236 else {
237 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[WRITE]"));
238 }
239
240 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD,
241 " Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n",
242 acpi_ut_get_region_name (rgn_desc->region.space_id),
243 rgn_desc->region.space_id,
244 obj_desc->common_field.access_byte_width,
245 obj_desc->common_field.base_byte_offset,
246 field_datum_byte_offset,
247 ACPI_FORMAT_UINT64 (address)));
248
249 /* Invoke the appropriate address_space/op_region handler */
250
251 status = acpi_ev_address_space_dispatch (rgn_desc, function,
252 address, ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value);
253
254 if (ACPI_FAILURE (status)) {
255 if (status == AE_NOT_IMPLEMENTED) {
256 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
257 "Region %s(%X) not implemented\n",
258 acpi_ut_get_region_name (rgn_desc->region.space_id),
259 rgn_desc->region.space_id));
260 }
261 else if (status == AE_NOT_EXIST) {
262 ACPI_REPORT_ERROR ((
263 "Region %s(%X) has no handler\n",
264 acpi_ut_get_region_name (rgn_desc->region.space_id),
265 rgn_desc->region.space_id));
266 }
267 }
268
269 return_ACPI_STATUS (status);
270}
271
272
273/*******************************************************************************
274 *
275 * FUNCTION: acpi_ex_register_overflow
276 *
277 * PARAMETERS: *obj_desc - Register(Field) to be written
278 * Value - Value to be stored
279 *
280 * RETURN: TRUE if value overflows the field, FALSE otherwise
281 *
282 * DESCRIPTION: Check if a value is out of range of the field being written.
283 * Used to check if the values written to Index and Bank registers
284 * are out of range. Normally, the value is simply truncated
285 * to fit the field, but this case is most likely a serious
286 * coding error in the ASL.
287 *
288 ******************************************************************************/
289
290u8
291acpi_ex_register_overflow (
292 union acpi_operand_object *obj_desc,
293 acpi_integer value)
294{
295
296 if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) {
297 /*
298 * The field is large enough to hold the maximum integer, so we can
299 * never overflow it.
300 */
301 return (FALSE);
302 }
303
304 if (value >= ((acpi_integer) 1 << obj_desc->common_field.bit_length)) {
305 /*
306 * The Value is larger than the maximum value that can fit into
307 * the register.
308 */
309 return (TRUE);
310 }
311
312 /* The Value will fit into the field with no truncation */
313
314 return (FALSE);
315}
316
317
318/*******************************************************************************
319 *
320 * FUNCTION: acpi_ex_field_datum_io
321 *
322 * PARAMETERS: *obj_desc - Field to be read
323 * field_datum_byte_offset - Byte offset of this datum within the
324 * parent field
325 * *Value - Where to store value (must be 64 bits)
326 * read_write - Read or Write flag
327 *
328 * RETURN: Status
329 *
330 * DESCRIPTION: Read or Write a single datum of a field. The field_type is
331 * demultiplexed here to handle the different types of fields
332 * (buffer_field, region_field, index_field, bank_field)
333 *
334 ******************************************************************************/
335
336acpi_status
337acpi_ex_field_datum_io (
338 union acpi_operand_object *obj_desc,
339 u32 field_datum_byte_offset,
340 acpi_integer *value,
341 u32 read_write)
342{
343 acpi_status status;
344 acpi_integer local_value;
345
346
347 ACPI_FUNCTION_TRACE_U32 ("ex_field_datum_io", field_datum_byte_offset);
348
349
350 if (read_write == ACPI_READ) {
351 if (!value) {
352 local_value = 0;
353 value = &local_value; /* To support reads without saving return value */
354 }
355
356 /* Clear the entire return buffer first, [Very Important!] */
357
358 *value = 0;
359 }
360
361 /*
362 * The four types of fields are:
363 *
364 * buffer_field - Read/write from/to a Buffer
365 * region_field - Read/write from/to a Operation Region.
366 * bank_field - Write to a Bank Register, then read/write from/to an op_region
367 * index_field - Write to an Index Register, then read/write from/to a Data Register
368 */
369 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
370 case ACPI_TYPE_BUFFER_FIELD:
371 /*
372 * If the buffer_field arguments have not been previously evaluated,
373 * evaluate them now and save the results.
374 */
375 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
376 status = acpi_ds_get_buffer_field_arguments (obj_desc);
377 if (ACPI_FAILURE (status)) {
378 return_ACPI_STATUS (status);
379 }
380 }
381
382 if (read_write == ACPI_READ) {
383 /*
384 * Copy the data from the source buffer.
385 * Length is the field width in bytes.
386 */
387 ACPI_MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer
388 + obj_desc->buffer_field.base_byte_offset
389 + field_datum_byte_offset,
390 obj_desc->common_field.access_byte_width);
391 }
392 else {
393 /*
394 * Copy the data to the target buffer.
395 * Length is the field width in bytes.
396 */
397 ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer
398 + obj_desc->buffer_field.base_byte_offset
399 + field_datum_byte_offset,
400 value, obj_desc->common_field.access_byte_width);
401 }
402
403 status = AE_OK;
404 break;
405
406
407 case ACPI_TYPE_LOCAL_BANK_FIELD:
408
409 /* Ensure that the bank_value is not beyond the capacity of the register */
410
411 if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj,
412 (acpi_integer) obj_desc->bank_field.value)) {
413 return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
414 }
415
416 /*
417 * For bank_fields, we must write the bank_value to the bank_register
418 * (itself a region_field) before we can access the data.
419 */
420 status = acpi_ex_insert_into_field (obj_desc->bank_field.bank_obj,
421 &obj_desc->bank_field.value,
422 sizeof (obj_desc->bank_field.value));
423 if (ACPI_FAILURE (status)) {
424 return_ACPI_STATUS (status);
425 }
426
427 /*
428 * Now that the Bank has been selected, fall through to the
429 * region_field case and write the datum to the Operation Region
430 */
431
432 /*lint -fallthrough */
433
434
435 case ACPI_TYPE_LOCAL_REGION_FIELD:
436 /*
437 * For simple region_fields, we just directly access the owning
438 * Operation Region.
439 */
440 status = acpi_ex_access_region (obj_desc, field_datum_byte_offset, value,
441 read_write);
442 break;
443
444
445 case ACPI_TYPE_LOCAL_INDEX_FIELD:
446
447
448 /* Ensure that the index_value is not beyond the capacity of the register */
449
450 if (acpi_ex_register_overflow (obj_desc->index_field.index_obj,
451 (acpi_integer) obj_desc->index_field.value)) {
452 return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
453 }
454
455 /* Write the index value to the index_register (itself a region_field) */
456
457 field_datum_byte_offset += obj_desc->index_field.value;
458
459 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
460 "Write to Index Register: Value %8.8X\n",
461 field_datum_byte_offset));
462
463 status = acpi_ex_insert_into_field (obj_desc->index_field.index_obj,
464 &field_datum_byte_offset,
465 sizeof (field_datum_byte_offset));
466 if (ACPI_FAILURE (status)) {
467 return_ACPI_STATUS (status);
468 }
469
470 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
471 "I/O to Data Register: value_ptr %p\n",
472 value));
473
474 if (read_write == ACPI_READ) {
475 /* Read the datum from the data_register */
476
477 status = acpi_ex_extract_from_field (obj_desc->index_field.data_obj,
478 value, sizeof (acpi_integer));
479 }
480 else {
481 /* Write the datum to the data_register */
482
483 status = acpi_ex_insert_into_field (obj_desc->index_field.data_obj,
484 value, sizeof (acpi_integer));
485 }
486 break;
487
488
489 default:
490
491 ACPI_REPORT_ERROR (("Wrong object type in field I/O %X\n",
492 ACPI_GET_OBJECT_TYPE (obj_desc)));
493 status = AE_AML_INTERNAL;
494 break;
495 }
496
497 if (ACPI_SUCCESS (status)) {
498 if (read_write == ACPI_READ) {
499 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n",
500 ACPI_FORMAT_UINT64 (*value),
501 obj_desc->common_field.access_byte_width));
502 }
503 else {
504 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n",
505 ACPI_FORMAT_UINT64 (*value),
506 obj_desc->common_field.access_byte_width));
507 }
508 }
509
510 return_ACPI_STATUS (status);
511}
512
513
514/*******************************************************************************
515 *
516 * FUNCTION: acpi_ex_write_with_update_rule
517 *
518 * PARAMETERS: *obj_desc - Field to be set
519 * Value - Value to store
520 *
521 * RETURN: Status
522 *
523 * DESCRIPTION: Apply the field update rule to a field write
524 *
525 ******************************************************************************/
526
527acpi_status
528acpi_ex_write_with_update_rule (
529 union acpi_operand_object *obj_desc,
530 acpi_integer mask,
531 acpi_integer field_value,
532 u32 field_datum_byte_offset)
533{
534 acpi_status status = AE_OK;
535 acpi_integer merged_value;
536 acpi_integer current_value;
537
538
539 ACPI_FUNCTION_TRACE_U32 ("ex_write_with_update_rule", mask);
540
541
542 /* Start with the new bits */
543
544 merged_value = field_value;
545
546 /* If the mask is all ones, we don't need to worry about the update rule */
547
548 if (mask != ACPI_INTEGER_MAX) {
549 /* Decode the update rule */
550
551 switch (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK) {
552 case AML_FIELD_UPDATE_PRESERVE:
553 /*
554 * Check if update rule needs to be applied (not if mask is all
555 * ones) The left shift drops the bits we want to ignore.
556 */
557 if ((~mask << (ACPI_MUL_8 (sizeof (mask)) -
558 ACPI_MUL_8 (obj_desc->common_field.access_byte_width))) != 0) {
559 /*
560 * Read the current contents of the byte/word/dword containing
561 * the field, and merge with the new field value.
562 */
563 status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
564 &current_value, ACPI_READ);
565 if (ACPI_FAILURE (status)) {
566 return_ACPI_STATUS (status);
567 }
568
569 merged_value |= (current_value & ~mask);
570 }
571 break;
572
573 case AML_FIELD_UPDATE_WRITE_AS_ONES:
574
575 /* Set positions outside the field to all ones */
576
577 merged_value |= ~mask;
578 break;
579
580 case AML_FIELD_UPDATE_WRITE_AS_ZEROS:
581
582 /* Set positions outside the field to all zeros */
583
584 merged_value &= mask;
585 break;
586
587 default:
588
589 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
590 "write_with_update_rule: Unknown update_rule setting: %X\n",
591 (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK)));
592 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
593 }
594 }
595
596 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
597 "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n",
598 ACPI_FORMAT_UINT64 (mask),
599 field_datum_byte_offset,
600 obj_desc->common_field.access_byte_width,
601 ACPI_FORMAT_UINT64 (field_value),
602 ACPI_FORMAT_UINT64 (merged_value)));
603
604 /* Write the merged value */
605
606 status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
607 &merged_value, ACPI_WRITE);
608
609 return_ACPI_STATUS (status);
610}
611
612
613/*******************************************************************************
614 *
615 * FUNCTION: acpi_ex_extract_from_field
616 *
617 * PARAMETERS: obj_desc - Field to be read
618 * Buffer - Where to store the field data
619 * buffer_length - Length of Buffer
620 *
621 * RETURN: Status
622 *
623 * DESCRIPTION: Retrieve the current value of the given field
624 *
625 ******************************************************************************/
626
627acpi_status
628acpi_ex_extract_from_field (
629 union acpi_operand_object *obj_desc,
630 void *buffer,
631 u32 buffer_length)
632{
633 acpi_status status;
634 acpi_integer raw_datum;
635 acpi_integer merged_datum;
636 u32 field_offset = 0;
637 u32 buffer_offset = 0;
638 u32 buffer_tail_bits;
639 u32 datum_count;
640 u32 field_datum_count;
641 u32 i;
642
643
644 ACPI_FUNCTION_TRACE ("ex_extract_from_field");
645
646
647 /* Validate target buffer and clear it */
648
649 if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES (
650 obj_desc->common_field.bit_length)) {
651 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
652 "Field size %X (bits) is too large for buffer (%X)\n",
653 obj_desc->common_field.bit_length, buffer_length));
654
655 return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
656 }
657 ACPI_MEMSET (buffer, 0, buffer_length);
658
659 /* Compute the number of datums (access width data items) */
660
661 datum_count = ACPI_ROUND_UP_TO (
662 obj_desc->common_field.bit_length,
663 obj_desc->common_field.access_bit_width);
664 field_datum_count = ACPI_ROUND_UP_TO (
665 obj_desc->common_field.bit_length +
666 obj_desc->common_field.start_field_bit_offset,
667 obj_desc->common_field.access_bit_width);
668
669 /* Priming read from the field */
670
671 status = acpi_ex_field_datum_io (obj_desc, field_offset, &raw_datum, ACPI_READ);
672 if (ACPI_FAILURE (status)) {
673 return_ACPI_STATUS (status);
674 }
675 merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset;
676
677 /* Read the rest of the field */
678
679 for (i = 1; i < field_datum_count; i++) {
680 /* Get next input datum from the field */
681
682 field_offset += obj_desc->common_field.access_byte_width;
683 status = acpi_ex_field_datum_io (obj_desc, field_offset,
684 &raw_datum, ACPI_READ);
685 if (ACPI_FAILURE (status)) {
686 return_ACPI_STATUS (status);
687 }
688
689 /* Merge with previous datum if necessary */
690
691 merged_datum |= raw_datum <<
692 (obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset);
693
694 if (i == datum_count) {
695 break;
696 }
697
698 /* Write merged datum to target buffer */
699
700 ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum,
701 ACPI_MIN(obj_desc->common_field.access_byte_width,
702 buffer_length - buffer_offset));
703
704 buffer_offset += obj_desc->common_field.access_byte_width;
705 merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset;
706 }
707
708 /* Mask off any extra bits in the last datum */
709
710 buffer_tail_bits = obj_desc->common_field.bit_length % obj_desc->common_field.access_bit_width;
711 if (buffer_tail_bits) {
712 merged_datum &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
713 }
714
715 /* Write the last datum to the buffer */
716
717 ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum,
718 ACPI_MIN(obj_desc->common_field.access_byte_width,
719 buffer_length - buffer_offset));
720
721 return_ACPI_STATUS (AE_OK);
722}
723
724
725/*******************************************************************************
726 *
727 * FUNCTION: acpi_ex_insert_into_field
728 *
729 * PARAMETERS: obj_desc - Field to be written
730 * Buffer - Data to be written
731 * buffer_length - Length of Buffer
732 *
733 * RETURN: Status
734 *
735 * DESCRIPTION: Store the Buffer contents into the given field
736 *
737 ******************************************************************************/
738
739acpi_status
740acpi_ex_insert_into_field (
741 union acpi_operand_object *obj_desc,
742 void *buffer,
743 u32 buffer_length)
744{
745 acpi_status status;
746 acpi_integer mask;
747 acpi_integer merged_datum;
748 acpi_integer raw_datum = 0;
749 u32 field_offset = 0;
750 u32 buffer_offset = 0;
751 u32 buffer_tail_bits;
752 u32 datum_count;
753 u32 field_datum_count;
754 u32 i;
755
756
757 ACPI_FUNCTION_TRACE ("ex_insert_into_field");
758
759
760 /* Validate input buffer */
761
762 if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES (
763 obj_desc->common_field.bit_length)) {
764 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
765 "Field size %X (bits) is too large for buffer (%X)\n",
766 obj_desc->common_field.bit_length, buffer_length));
767
768 return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
769 }
770
771 /* Compute the number of datums (access width data items) */
772
773 mask = ACPI_MASK_BITS_BELOW (obj_desc->common_field.start_field_bit_offset);
774 datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length,
775 obj_desc->common_field.access_bit_width);
776 field_datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length +
777 obj_desc->common_field.start_field_bit_offset,
778 obj_desc->common_field.access_bit_width);
779
780 /* Get initial Datum from the input buffer */
781
782 ACPI_MEMCPY (&raw_datum, buffer,
783 ACPI_MIN(obj_desc->common_field.access_byte_width,
784 buffer_length - buffer_offset));
785
786 merged_datum = raw_datum << obj_desc->common_field.start_field_bit_offset;
787
788 /* Write the entire field */
789
790 for (i = 1; i < field_datum_count; i++) {
791 /* Write merged datum to the target field */
792
793 merged_datum &= mask;
794 status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
795 if (ACPI_FAILURE (status)) {
796 return_ACPI_STATUS (status);
797 }
798
799 /* Start new output datum by merging with previous input datum */
800
801 field_offset += obj_desc->common_field.access_byte_width;
802 merged_datum = raw_datum >>
803 (obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset);
804 mask = ACPI_INTEGER_MAX;
805
806 if (i == datum_count) {
807 break;
808 }
809
810 /* Get the next input datum from the buffer */
811
812 buffer_offset += obj_desc->common_field.access_byte_width;
813 ACPI_MEMCPY (&raw_datum, ((char *) buffer) + buffer_offset,
814 ACPI_MIN(obj_desc->common_field.access_byte_width,
815 buffer_length - buffer_offset));
816 merged_datum |= raw_datum << obj_desc->common_field.start_field_bit_offset;
817 }
818
819 /* Mask off any extra bits in the last datum */
820
821 buffer_tail_bits = (obj_desc->common_field.bit_length +
822 obj_desc->common_field.start_field_bit_offset) % obj_desc->common_field.access_bit_width;
823 if (buffer_tail_bits) {
824 mask &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
825 }
826
827 /* Write the last datum to the field */
828
829 merged_datum &= mask;
830 status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
831
832 return_ACPI_STATUS (status);
833}
834
835
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
new file mode 100644
index 000000000000..b542dcd58c07
--- /dev/null
+++ b/drivers/acpi/executer/exmisc.c
@@ -0,0 +1,738 @@
1
2/******************************************************************************
3 *
4 * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acinterp.h>
48#include <acpi/amlcode.h>
49
50
51#define _COMPONENT ACPI_EXECUTER
52 ACPI_MODULE_NAME ("exmisc")
53
54
55/*******************************************************************************
56 *
57 * FUNCTION: acpi_ex_get_object_reference
58 *
59 * PARAMETERS: obj_desc - Create a reference to this object
60 * return_desc - Where to store the reference
61 * walk_state - Current state
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Obtain and return a "reference" to the target object
66 * Common code for the ref_of_op and the cond_ref_of_op.
67 *
68 ******************************************************************************/
69
70acpi_status
71acpi_ex_get_object_reference (
72 union acpi_operand_object *obj_desc,
73 union acpi_operand_object **return_desc,
74 struct acpi_walk_state *walk_state)
75{
76 union acpi_operand_object *reference_obj;
77 union acpi_operand_object *referenced_obj;
78
79
80 ACPI_FUNCTION_TRACE_PTR ("ex_get_object_reference", obj_desc);
81
82
83 *return_desc = NULL;
84
85 switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
86 case ACPI_DESC_TYPE_OPERAND:
87
88 if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
89 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
90 }
91
92 /*
93 * Must be a reference to a Local or Arg
94 */
95 switch (obj_desc->reference.opcode) {
96 case AML_LOCAL_OP:
97 case AML_ARG_OP:
98 case AML_DEBUG_OP:
99
100 /* The referenced object is the pseudo-node for the local/arg */
101
102 referenced_obj = obj_desc->reference.object;
103 break;
104
105 default:
106
107 ACPI_REPORT_ERROR (("Unknown Reference opcode in get_reference %X\n",
108 obj_desc->reference.opcode));
109 return_ACPI_STATUS (AE_AML_INTERNAL);
110 }
111 break;
112
113
114 case ACPI_DESC_TYPE_NAMED:
115
116 /*
117 * A named reference that has already been resolved to a Node
118 */
119 referenced_obj = obj_desc;
120 break;
121
122
123 default:
124
125 ACPI_REPORT_ERROR (("Invalid descriptor type in get_reference: %X\n",
126 ACPI_GET_DESCRIPTOR_TYPE (obj_desc)));
127 return_ACPI_STATUS (AE_TYPE);
128 }
129
130
131 /* Create a new reference object */
132
133 reference_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
134 if (!reference_obj) {
135 return_ACPI_STATUS (AE_NO_MEMORY);
136 }
137
138 reference_obj->reference.opcode = AML_REF_OF_OP;
139 reference_obj->reference.object = referenced_obj;
140 *return_desc = reference_obj;
141
142 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n",
143 obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
144
145 return_ACPI_STATUS (AE_OK);
146}
147
148
149/*******************************************************************************
150 *
151 * FUNCTION: acpi_ex_concat_template
152 *
153 * PARAMETERS: Operand0 - First source object
154 * Operand1 - Second source object
155 * actual_return_desc - Where to place the return object
156 * walk_state - Current walk state
157 *
158 * RETURN: Status
159 *
160 * DESCRIPTION: Concatenate two resource templates
161 *
162 ******************************************************************************/
163
164acpi_status
165acpi_ex_concat_template (
166 union acpi_operand_object *operand0,
167 union acpi_operand_object *operand1,
168 union acpi_operand_object **actual_return_desc,
169 struct acpi_walk_state *walk_state)
170{
171 union acpi_operand_object *return_desc;
172 u8 *new_buf;
173 u8 *end_tag1;
174 u8 *end_tag2;
175 acpi_size length1;
176 acpi_size length2;
177
178
179 ACPI_FUNCTION_TRACE ("ex_concat_template");
180
181
182 /* Find the end_tags in each resource template */
183
184 end_tag1 = acpi_ut_get_resource_end_tag (operand0);
185 end_tag2 = acpi_ut_get_resource_end_tag (operand1);
186 if (!end_tag1 || !end_tag2) {
187 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
188 }
189
190 /* Compute the length of each part */
191
192 length1 = ACPI_PTR_DIFF (end_tag1, operand0->buffer.pointer);
193 length2 = ACPI_PTR_DIFF (end_tag2, operand1->buffer.pointer) +
194 2; /* Size of END_TAG */
195
196 /* Create a new buffer object for the result */
197
198 return_desc = acpi_ut_create_buffer_object (length1 + length2);
199 if (!return_desc) {
200 return_ACPI_STATUS (AE_NO_MEMORY);
201 }
202
203 /* Copy the templates to the new descriptor */
204
205 new_buf = return_desc->buffer.pointer;
206 ACPI_MEMCPY (new_buf, operand0->buffer.pointer, length1);
207 ACPI_MEMCPY (new_buf + length1, operand1->buffer.pointer, length2);
208
209 /* Compute the new checksum */
210
211 new_buf[return_desc->buffer.length - 1] =
212 acpi_ut_generate_checksum (return_desc->buffer.pointer,
213 (return_desc->buffer.length - 1));
214
215 /* Return the completed template descriptor */
216
217 *actual_return_desc = return_desc;
218 return_ACPI_STATUS (AE_OK);
219}
220
221
222/*******************************************************************************
223 *
224 * FUNCTION: acpi_ex_do_concatenate
225 *
226 * PARAMETERS: Operand0 - First source object
227 * Operand1 - Second source object
228 * actual_return_desc - Where to place the return object
229 * walk_state - Current walk state
230 *
231 * RETURN: Status
232 *
233 * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
234 *
235 ******************************************************************************/
236
237acpi_status
238acpi_ex_do_concatenate (
239 union acpi_operand_object *operand0,
240 union acpi_operand_object *operand1,
241 union acpi_operand_object **actual_return_desc,
242 struct acpi_walk_state *walk_state)
243{
244 union acpi_operand_object *local_operand1 = operand1;
245 union acpi_operand_object *return_desc;
246 char *new_buf;
247 acpi_status status;
248 acpi_size new_length;
249
250
251 ACPI_FUNCTION_TRACE ("ex_do_concatenate");
252
253
254 /*
255 * Convert the second operand if necessary. The first operand
256 * determines the type of the second operand, (See the Data Types
257 * section of the ACPI specification.) Both object types are
258 * guaranteed to be either Integer/String/Buffer by the operand
259 * resolution mechanism.
260 */
261 switch (ACPI_GET_OBJECT_TYPE (operand0)) {
262 case ACPI_TYPE_INTEGER:
263 status = acpi_ex_convert_to_integer (operand1, &local_operand1, 16);
264 break;
265
266 case ACPI_TYPE_STRING:
267 status = acpi_ex_convert_to_string (operand1, &local_operand1,
268 ACPI_IMPLICIT_CONVERT_HEX);
269 break;
270
271 case ACPI_TYPE_BUFFER:
272 status = acpi_ex_convert_to_buffer (operand1, &local_operand1);
273 break;
274
275 default:
276 ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
277 ACPI_GET_OBJECT_TYPE (operand0)));
278 status = AE_AML_INTERNAL;
279 }
280
281 if (ACPI_FAILURE (status)) {
282 goto cleanup;
283 }
284
285 /*
286 * Both operands are now known to be the same object type
287 * (Both are Integer, String, or Buffer), and we can now perform the
288 * concatenation.
289 */
290
291 /*
292 * There are three cases to handle:
293 *
294 * 1) Two Integers concatenated to produce a new Buffer
295 * 2) Two Strings concatenated to produce a new String
296 * 3) Two Buffers concatenated to produce a new Buffer
297 */
298 switch (ACPI_GET_OBJECT_TYPE (operand0)) {
299 case ACPI_TYPE_INTEGER:
300
301 /* Result of two Integers is a Buffer */
302 /* Need enough buffer space for two integers */
303
304 return_desc = acpi_ut_create_buffer_object (
305 ACPI_MUL_2 (acpi_gbl_integer_byte_width));
306 if (!return_desc) {
307 status = AE_NO_MEMORY;
308 goto cleanup;
309 }
310
311 new_buf = (char *) return_desc->buffer.pointer;
312
313 /* Copy the first integer, LSB first */
314
315 ACPI_MEMCPY (new_buf,
316 &operand0->integer.value,
317 acpi_gbl_integer_byte_width);
318
319 /* Copy the second integer (LSB first) after the first */
320
321 ACPI_MEMCPY (new_buf + acpi_gbl_integer_byte_width,
322 &local_operand1->integer.value,
323 acpi_gbl_integer_byte_width);
324 break;
325
326 case ACPI_TYPE_STRING:
327
328 /* Result of two Strings is a String */
329
330 new_length = (acpi_size) operand0->string.length +
331 (acpi_size) local_operand1->string.length;
332 if (new_length > ACPI_MAX_STRING_CONVERSION) {
333 status = AE_AML_STRING_LIMIT;
334 goto cleanup;
335 }
336
337 return_desc = acpi_ut_create_string_object (new_length);
338 if (!return_desc) {
339 status = AE_NO_MEMORY;
340 goto cleanup;
341 }
342
343 new_buf = return_desc->string.pointer;
344
345 /* Concatenate the strings */
346
347 ACPI_STRCPY (new_buf,
348 operand0->string.pointer);
349 ACPI_STRCPY (new_buf + operand0->string.length,
350 local_operand1->string.pointer);
351 break;
352
353 case ACPI_TYPE_BUFFER:
354
355 /* Result of two Buffers is a Buffer */
356
357 return_desc = acpi_ut_create_buffer_object (
358 (acpi_size) operand0->buffer.length +
359 (acpi_size) local_operand1->buffer.length);
360 if (!return_desc) {
361 status = AE_NO_MEMORY;
362 goto cleanup;
363 }
364
365 new_buf = (char *) return_desc->buffer.pointer;
366
367 /* Concatenate the buffers */
368
369 ACPI_MEMCPY (new_buf,
370 operand0->buffer.pointer,
371 operand0->buffer.length);
372 ACPI_MEMCPY (new_buf + operand0->buffer.length,
373 local_operand1->buffer.pointer,
374 local_operand1->buffer.length);
375 break;
376
377 default:
378
379 /* Invalid object type, should not happen here */
380
381 ACPI_REPORT_ERROR (("Concatenate - Invalid object type: %X\n",
382 ACPI_GET_OBJECT_TYPE (operand0)));
383 status =AE_AML_INTERNAL;
384 goto cleanup;
385 }
386
387 *actual_return_desc = return_desc;
388
389cleanup:
390 if (local_operand1 != operand1) {
391 acpi_ut_remove_reference (local_operand1);
392 }
393 return_ACPI_STATUS (status);
394}
395
396
397/*******************************************************************************
398 *
399 * FUNCTION: acpi_ex_do_math_op
400 *
401 * PARAMETERS: Opcode - AML opcode
402 * Integer0 - Integer operand #0
403 * Integer1 - Integer operand #1
404 *
405 * RETURN: Integer result of the operation
406 *
407 * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
408 * math functions here is to prevent a lot of pointer dereferencing
409 * to obtain the operands.
410 *
411 ******************************************************************************/
412
413acpi_integer
414acpi_ex_do_math_op (
415 u16 opcode,
416 acpi_integer integer0,
417 acpi_integer integer1)
418{
419
420 ACPI_FUNCTION_ENTRY ();
421
422
423 switch (opcode) {
424 case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
425
426 return (integer0 + integer1);
427
428
429 case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
430
431 return (integer0 & integer1);
432
433
434 case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
435
436 return (~(integer0 & integer1));
437
438
439 case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
440
441 return (integer0 | integer1);
442
443
444 case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
445
446 return (~(integer0 | integer1));
447
448
449 case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
450
451 return (integer0 ^ integer1);
452
453
454 case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
455
456 return (integer0 * integer1);
457
458
459 case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */
460
461 return (integer0 << integer1);
462
463
464 case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */
465
466 return (integer0 >> integer1);
467
468
469 case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
470
471 return (integer0 - integer1);
472
473 default:
474
475 return (0);
476 }
477}
478
479
480/*******************************************************************************
481 *
482 * FUNCTION: acpi_ex_do_logical_numeric_op
483 *
484 * PARAMETERS: Opcode - AML opcode
485 * Integer0 - Integer operand #0
486 * Integer1 - Integer operand #1
487 * logical_result - TRUE/FALSE result of the operation
488 *
489 * RETURN: Status
490 *
491 * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
492 * operators (LAnd and LOr), both operands must be integers.
493 *
494 * Note: cleanest machine code seems to be produced by the code
495 * below, rather than using statements of the form:
496 * Result = (Integer0 && Integer1);
497 *
498 ******************************************************************************/
499
500acpi_status
501acpi_ex_do_logical_numeric_op (
502 u16 opcode,
503 acpi_integer integer0,
504 acpi_integer integer1,
505 u8 *logical_result)
506{
507 acpi_status status = AE_OK;
508 u8 local_result = FALSE;
509
510
511 ACPI_FUNCTION_TRACE ("ex_do_logical_numeric_op");
512
513
514 switch (opcode) {
515 case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
516
517 if (integer0 && integer1) {
518 local_result = TRUE;
519 }
520 break;
521
522 case AML_LOR_OP: /* LOr (Integer0, Integer1) */
523
524 if (integer0 || integer1) {
525 local_result = TRUE;
526 }
527 break;
528
529 default:
530 status = AE_AML_INTERNAL;
531 break;
532 }
533
534 /* Return the logical result and status */
535
536 *logical_result = local_result;
537 return_ACPI_STATUS (status);
538}
539
540
541/*******************************************************************************
542 *
543 * FUNCTION: acpi_ex_do_logical_op
544 *
545 * PARAMETERS: Opcode - AML opcode
546 * Operand0 - operand #0
547 * Operand1 - operand #1
548 * logical_result - TRUE/FALSE result of the operation
549 *
550 * RETURN: Status
551 *
552 * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
553 * functions here is to prevent a lot of pointer dereferencing
554 * to obtain the operands and to simplify the generation of the
555 * logical value. For the Numeric operators (LAnd and LOr), both
556 * operands must be integers. For the other logical operators,
557 * operands can be any combination of Integer/String/Buffer. The
558 * first operand determines the type to which the second operand
559 * will be converted.
560 *
561 * Note: cleanest machine code seems to be produced by the code
562 * below, rather than using statements of the form:
563 * Result = (Operand0 == Operand1);
564 *
565 ******************************************************************************/
566
567acpi_status
568acpi_ex_do_logical_op (
569 u16 opcode,
570 union acpi_operand_object *operand0,
571 union acpi_operand_object *operand1,
572 u8 *logical_result)
573{
574 union acpi_operand_object *local_operand1 = operand1;
575 acpi_integer integer0;
576 acpi_integer integer1;
577 u32 length0;
578 u32 length1;
579 acpi_status status = AE_OK;
580 u8 local_result = FALSE;
581 int compare;
582
583
584 ACPI_FUNCTION_TRACE ("ex_do_logical_op");
585
586
587 /*
588 * Convert the second operand if necessary. The first operand
589 * determines the type of the second operand, (See the Data Types
590 * section of the ACPI 3.0+ specification.) Both object types are
591 * guaranteed to be either Integer/String/Buffer by the operand
592 * resolution mechanism.
593 */
594 switch (ACPI_GET_OBJECT_TYPE (operand0)) {
595 case ACPI_TYPE_INTEGER:
596 status = acpi_ex_convert_to_integer (operand1, &local_operand1, 16);
597 break;
598
599 case ACPI_TYPE_STRING:
600 status = acpi_ex_convert_to_string (operand1, &local_operand1,
601 ACPI_IMPLICIT_CONVERT_HEX);
602 break;
603
604 case ACPI_TYPE_BUFFER:
605 status = acpi_ex_convert_to_buffer (operand1, &local_operand1);
606 break;
607
608 default:
609 status = AE_AML_INTERNAL;
610 break;
611 }
612
613 if (ACPI_FAILURE (status)) {
614 goto cleanup;
615 }
616
617 /*
618 * Two cases: 1) Both Integers, 2) Both Strings or Buffers
619 */
620 if (ACPI_GET_OBJECT_TYPE (operand0) == ACPI_TYPE_INTEGER) {
621 /*
622 * 1) Both operands are of type integer
623 * Note: local_operand1 may have changed above
624 */
625 integer0 = operand0->integer.value;
626 integer1 = local_operand1->integer.value;
627
628 switch (opcode) {
629 case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
630
631 if (integer0 == integer1) {
632 local_result = TRUE;
633 }
634 break;
635
636 case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
637
638 if (integer0 > integer1) {
639 local_result = TRUE;
640 }
641 break;
642
643 case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
644
645 if (integer0 < integer1) {
646 local_result = TRUE;
647 }
648 break;
649
650 default:
651 status = AE_AML_INTERNAL;
652 break;
653 }
654 }
655 else {
656 /*
657 * 2) Both operands are Strings or both are Buffers
658 * Note: Code below takes advantage of common Buffer/String
659 * object fields. local_operand1 may have changed above. Use
660 * memcmp to handle nulls in buffers.
661 */
662 length0 = operand0->buffer.length;
663 length1 = local_operand1->buffer.length;
664
665 /* Lexicographic compare: compare the data bytes */
666
667 compare = ACPI_MEMCMP ((const char * ) operand0->buffer.pointer,
668 (const char * ) local_operand1->buffer.pointer,
669 (length0 > length1) ? length1 : length0);
670
671 switch (opcode) {
672 case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
673
674 /* Length and all bytes must be equal */
675
676 if ((length0 == length1) &&
677 (compare == 0)) {
678 /* Length and all bytes match ==> TRUE */
679
680 local_result = TRUE;
681 }
682 break;
683
684 case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
685
686 if (compare > 0) {
687 local_result = TRUE;
688 goto cleanup; /* TRUE */
689 }
690 if (compare < 0) {
691 goto cleanup; /* FALSE */
692 }
693
694 /* Bytes match (to shortest length), compare lengths */
695
696 if (length0 > length1) {
697 local_result = TRUE;
698 }
699 break;
700
701 case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
702
703 if (compare > 0) {
704 goto cleanup; /* FALSE */
705 }
706 if (compare < 0) {
707 local_result = TRUE;
708 goto cleanup; /* TRUE */
709 }
710
711 /* Bytes match (to shortest length), compare lengths */
712
713 if (length0 < length1) {
714 local_result = TRUE;
715 }
716 break;
717
718 default:
719 status = AE_AML_INTERNAL;
720 break;
721 }
722 }
723
724cleanup:
725
726 /* New object was created if implicit conversion performed - delete */
727
728 if (local_operand1 != operand1) {
729 acpi_ut_remove_reference (local_operand1);
730 }
731
732 /* Return the logical result and status */
733
734 *logical_result = local_result;
735 return_ACPI_STATUS (status);
736}
737
738
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
new file mode 100644
index 000000000000..68c4bb1970a5
--- /dev/null
+++ b/drivers/acpi/executer/exmutex.c
@@ -0,0 +1,363 @@
1
2/******************************************************************************
3 *
4 * Module Name: exmutex - ASL Mutex Acquire/Release functions
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acinterp.h>
48
49#define _COMPONENT ACPI_EXECUTER
50 ACPI_MODULE_NAME ("exmutex")
51
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_ex_unlink_mutex
56 *
57 * PARAMETERS: obj_desc - The mutex to be unlinked
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Remove a mutex from the "acquired_mutex" list
62 *
63 ******************************************************************************/
64
65void
66acpi_ex_unlink_mutex (
67 union acpi_operand_object *obj_desc)
68{
69 struct acpi_thread_state *thread = obj_desc->mutex.owner_thread;
70
71
72 if (!thread) {
73 return;
74 }
75
76 /* Doubly linked list */
77
78 if (obj_desc->mutex.next) {
79 (obj_desc->mutex.next)->mutex.prev = obj_desc->mutex.prev;
80 }
81
82 if (obj_desc->mutex.prev) {
83 (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next;
84 }
85 else {
86 thread->acquired_mutex_list = obj_desc->mutex.next;
87 }
88}
89
90
91/*******************************************************************************
92 *
93 * FUNCTION: acpi_ex_link_mutex
94 *
95 * PARAMETERS: obj_desc - The mutex to be linked
96 * list_head - head of the "acquired_mutex" list
97 *
98 * RETURN: Status
99 *
100 * DESCRIPTION: Add a mutex to the "acquired_mutex" list for this walk
101 *
102 ******************************************************************************/
103
104void
105acpi_ex_link_mutex (
106 union acpi_operand_object *obj_desc,
107 struct acpi_thread_state *thread)
108{
109 union acpi_operand_object *list_head;
110
111
112 list_head = thread->acquired_mutex_list;
113
114 /* This object will be the first object in the list */
115
116 obj_desc->mutex.prev = NULL;
117 obj_desc->mutex.next = list_head;
118
119 /* Update old first object to point back to this object */
120
121 if (list_head) {
122 list_head->mutex.prev = obj_desc;
123 }
124
125 /* Update list head */
126
127 thread->acquired_mutex_list = obj_desc;
128}
129
130
131/*******************************************************************************
132 *
133 * FUNCTION: acpi_ex_acquire_mutex
134 *
135 * PARAMETERS: time_desc - The 'time to delay' object descriptor
136 * obj_desc - The object descriptor for this op
137 *
138 * RETURN: Status
139 *
140 * DESCRIPTION: Acquire an AML mutex
141 *
142 ******************************************************************************/
143
144acpi_status
145acpi_ex_acquire_mutex (
146 union acpi_operand_object *time_desc,
147 union acpi_operand_object *obj_desc,
148 struct acpi_walk_state *walk_state)
149{
150 acpi_status status;
151
152
153 ACPI_FUNCTION_TRACE_PTR ("ex_acquire_mutex", obj_desc);
154
155
156 if (!obj_desc) {
157 return_ACPI_STATUS (AE_BAD_PARAMETER);
158 }
159
160 /* Sanity check -- we must have a valid thread ID */
161
162 if (!walk_state->thread) {
163 ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], null thread info\n",
164 acpi_ut_get_node_name (obj_desc->mutex.node)));
165 return_ACPI_STATUS (AE_AML_INTERNAL);
166 }
167
168 /*
169 * Current Sync must be less than or equal to the sync level of the
170 * mutex. This mechanism provides some deadlock prevention
171 */
172 if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
173 ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], incorrect sync_level\n",
174 acpi_ut_get_node_name (obj_desc->mutex.node)));
175 return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
176 }
177
178 /* Support for multiple acquires by the owning thread */
179
180 if (obj_desc->mutex.owner_thread) {
181 /* Special case for Global Lock, allow all threads */
182
183 if ((obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id) ||
184 (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore)) {
185 /*
186 * The mutex is already owned by this thread,
187 * just increment the acquisition depth
188 */
189 obj_desc->mutex.acquisition_depth++;
190 return_ACPI_STATUS (AE_OK);
191 }
192 }
193
194 /* Acquire the mutex, wait if necessary */
195
196 status = acpi_ex_system_acquire_mutex (time_desc, obj_desc);
197 if (ACPI_FAILURE (status)) {
198 /* Includes failure from a timeout on time_desc */
199
200 return_ACPI_STATUS (status);
201 }
202
203 /* Have the mutex: update mutex and walk info and save the sync_level */
204
205 obj_desc->mutex.owner_thread = walk_state->thread;
206 obj_desc->mutex.acquisition_depth = 1;
207 obj_desc->mutex.original_sync_level = walk_state->thread->current_sync_level;
208
209 walk_state->thread->current_sync_level = obj_desc->mutex.sync_level;
210
211 /* Link the mutex to the current thread for force-unlock at method exit */
212
213 acpi_ex_link_mutex (obj_desc, walk_state->thread);
214
215 return_ACPI_STATUS (AE_OK);
216}
217
218
219/*******************************************************************************
220 *
221 * FUNCTION: acpi_ex_release_mutex
222 *
223 * PARAMETERS: obj_desc - The object descriptor for this op
224 *
225 * RETURN: Status
226 *
227 * DESCRIPTION: Release a previously acquired Mutex.
228 *
229 ******************************************************************************/
230
231acpi_status
232acpi_ex_release_mutex (
233 union acpi_operand_object *obj_desc,
234 struct acpi_walk_state *walk_state)
235{
236 acpi_status status;
237
238
239 ACPI_FUNCTION_TRACE ("ex_release_mutex");
240
241
242 if (!obj_desc) {
243 return_ACPI_STATUS (AE_BAD_PARAMETER);
244 }
245
246 /* The mutex must have been previously acquired in order to release it */
247
248 if (!obj_desc->mutex.owner_thread) {
249 ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], not acquired\n",
250 acpi_ut_get_node_name (obj_desc->mutex.node)));
251 return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
252 }
253
254 /* Sanity check -- we must have a valid thread ID */
255
256 if (!walk_state->thread) {
257 ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], null thread info\n",
258 acpi_ut_get_node_name (obj_desc->mutex.node)));
259 return_ACPI_STATUS (AE_AML_INTERNAL);
260 }
261
262 /*
263 * The Mutex is owned, but this thread must be the owner.
264 * Special case for Global Lock, any thread can release
265 */
266 if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) &&
267 (obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) {
268 ACPI_REPORT_ERROR ((
269 "Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n",
270 walk_state->thread->thread_id,
271 acpi_ut_get_node_name (obj_desc->mutex.node),
272 obj_desc->mutex.owner_thread->thread_id));
273 return_ACPI_STATUS (AE_AML_NOT_OWNER);
274 }
275
276 /*
277 * The sync level of the mutex must be less than or
278 * equal to the current sync level
279 */
280 if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
281 ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], incorrect sync_level\n",
282 acpi_ut_get_node_name (obj_desc->mutex.node)));
283 return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
284 }
285
286 /* Match multiple Acquires with multiple Releases */
287
288 obj_desc->mutex.acquisition_depth--;
289 if (obj_desc->mutex.acquisition_depth != 0) {
290 /* Just decrement the depth and return */
291
292 return_ACPI_STATUS (AE_OK);
293 }
294
295 /* Unlink the mutex from the owner's list */
296
297 acpi_ex_unlink_mutex (obj_desc);
298
299 /* Release the mutex */
300
301 status = acpi_ex_system_release_mutex (obj_desc);
302
303 /* Update the mutex and walk state, restore sync_level before acquire */
304
305 obj_desc->mutex.owner_thread = NULL;
306 walk_state->thread->current_sync_level = obj_desc->mutex.original_sync_level;
307
308 return_ACPI_STATUS (status);
309}
310
311
312/*******************************************************************************
313 *
314 * FUNCTION: acpi_ex_release_all_mutexes
315 *
316 * PARAMETERS: mutex_list - Head of the mutex list
317 *
318 * RETURN: Status
319 *
320 * DESCRIPTION: Release all mutexes in the list
321 *
322 ******************************************************************************/
323
324void
325acpi_ex_release_all_mutexes (
326 struct acpi_thread_state *thread)
327{
328 union acpi_operand_object *next = thread->acquired_mutex_list;
329 union acpi_operand_object *this;
330 acpi_status status;
331
332
333 ACPI_FUNCTION_ENTRY ();
334
335
336 /* Traverse the list of owned mutexes, releasing each one */
337
338 while (next) {
339 this = next;
340 next = this->mutex.next;
341
342 this->mutex.acquisition_depth = 1;
343 this->mutex.prev = NULL;
344 this->mutex.next = NULL;
345
346 /* Release the mutex */
347
348 status = acpi_ex_system_release_mutex (this);
349 if (ACPI_FAILURE (status)) {
350 continue;
351 }
352
353 /* Mark mutex unowned */
354
355 this->mutex.owner_thread = NULL;
356
357 /* Update Thread sync_level (Last mutex is the important one) */
358
359 thread->current_sync_level = this->mutex.original_sync_level;
360 }
361}
362
363
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
new file mode 100644
index 000000000000..7911c533c265
--- /dev/null
+++ b/drivers/acpi/executer/exnames.c
@@ -0,0 +1,427 @@
1
2/******************************************************************************
3 *
4 * Module Name: exnames - interpreter/scanner name load/execute
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acinterp.h>
48#include <acpi/amlcode.h>
49
50#define _COMPONENT ACPI_EXECUTER
51 ACPI_MODULE_NAME ("exnames")
52
53
54/* AML Package Length encodings */
55
56#define ACPI_AML_PACKAGE_TYPE1 0x40
57#define ACPI_AML_PACKAGE_TYPE2 0x4000
58#define ACPI_AML_PACKAGE_TYPE3 0x400000
59#define ACPI_AML_PACKAGE_TYPE4 0x40000000
60
61
62/*******************************************************************************
63 *
64 * FUNCTION: acpi_ex_allocate_name_string
65 *
66 * PARAMETERS: prefix_count - Count of parent levels. Special cases:
67 * (-1) = root, 0 = none
68 * num_name_segs - count of 4-character name segments
69 *
70 * RETURN: A pointer to the allocated string segment. This segment must
71 * be deleted by the caller.
72 *
73 * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
74 * string is long enough, and set up prefix if any.
75 *
76 ******************************************************************************/
77
78char *
79acpi_ex_allocate_name_string (
80 u32 prefix_count,
81 u32 num_name_segs)
82{
83 char *temp_ptr;
84 char *name_string;
85 u32 size_needed;
86
87 ACPI_FUNCTION_TRACE ("ex_allocate_name_string");
88
89
90 /*
91 * Allow room for all \ and ^ prefixes, all segments, and a multi_name_prefix.
92 * Also, one byte for the null terminator.
93 * This may actually be somewhat longer than needed.
94 */
95 if (prefix_count == ACPI_UINT32_MAX) {
96 /* Special case for root */
97
98 size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
99 }
100 else {
101 size_needed = prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
102 }
103
104 /*
105 * Allocate a buffer for the name.
106 * This buffer must be deleted by the caller!
107 */
108 name_string = ACPI_MEM_ALLOCATE (size_needed);
109 if (!name_string) {
110 ACPI_REPORT_ERROR (("ex_allocate_name_string: Could not allocate size %d\n", size_needed));
111 return_PTR (NULL);
112 }
113
114 temp_ptr = name_string;
115
116 /* Set up Root or Parent prefixes if needed */
117
118 if (prefix_count == ACPI_UINT32_MAX) {
119 *temp_ptr++ = AML_ROOT_PREFIX;
120 }
121 else {
122 while (prefix_count--) {
123 *temp_ptr++ = AML_PARENT_PREFIX;
124 }
125 }
126
127
128 /* Set up Dual or Multi prefixes if needed */
129
130 if (num_name_segs > 2) {
131 /* Set up multi prefixes */
132
133 *temp_ptr++ = AML_MULTI_NAME_PREFIX_OP;
134 *temp_ptr++ = (char) num_name_segs;
135 }
136 else if (2 == num_name_segs) {
137 /* Set up dual prefixes */
138
139 *temp_ptr++ = AML_DUAL_NAME_PREFIX;
140 }
141
142 /*
143 * Terminate string following prefixes. acpi_ex_name_segment() will
144 * append the segment(s)
145 */
146 *temp_ptr = 0;
147
148 return_PTR (name_string);
149}
150
151/*******************************************************************************
152 *
153 * FUNCTION: acpi_ex_name_segment
154 *
155 * PARAMETERS: interpreter_mode - Current running mode (load1/Load2/Exec)
156 *
157 * RETURN: Status
158 *
159 * DESCRIPTION: Execute a name segment (4 bytes)
160 *
161 ******************************************************************************/
162
163acpi_status
164acpi_ex_name_segment (
165 u8 **in_aml_address,
166 char *name_string)
167{
168 char *aml_address = (void *) *in_aml_address;
169 acpi_status status = AE_OK;
170 u32 index;
171 char char_buf[5];
172
173
174 ACPI_FUNCTION_TRACE ("ex_name_segment");
175
176
177 /*
178 * If first character is a digit, then we know that we aren't looking at a
179 * valid name segment
180 */
181 char_buf[0] = *aml_address;
182
183 if ('0' <= char_buf[0] && char_buf[0] <= '9') {
184 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "leading digit: %c\n", char_buf[0]));
185 return_ACPI_STATUS (AE_CTRL_PENDING);
186 }
187
188 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n"));
189
190 for (index = 0;
191 (index < ACPI_NAME_SIZE) && (acpi_ut_valid_acpi_character (*aml_address));
192 index++) {
193 char_buf[index] = *aml_address++;
194 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", char_buf[index]));
195 }
196
197
198 /* Valid name segment */
199
200 if (index == 4) {
201 /* Found 4 valid characters */
202
203 char_buf[4] = '\0';
204
205 if (name_string) {
206 ACPI_STRCAT (name_string, char_buf);
207 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
208 "Appended to - %s \n", name_string));
209 }
210 else {
211 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
212 "No Name string - %s \n", char_buf));
213 }
214 }
215 else if (index == 0) {
216 /*
217 * First character was not a valid name character,
218 * so we are looking at something other than a name.
219 */
220 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
221 "Leading character is not alpha: %02Xh (not a name)\n",
222 char_buf[0]));
223 status = AE_CTRL_PENDING;
224 }
225 else {
226 /* Segment started with one or more valid characters, but fewer than 4 */
227
228 status = AE_AML_BAD_NAME;
229 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad character %02x in name, at %p\n",
230 *aml_address, aml_address));
231 }
232
233 *in_aml_address = (u8 *) aml_address;
234 return_ACPI_STATUS (status);
235}
236
237
238/*******************************************************************************
239 *
240 * FUNCTION: acpi_ex_get_name_string
241 *
242 * PARAMETERS: data_type - Data type to be associated with this name
243 *
244 * RETURN: Status
245 *
246 * DESCRIPTION: Get a name, including any prefixes.
247 *
248 ******************************************************************************/
249
250acpi_status
251acpi_ex_get_name_string (
252 acpi_object_type data_type,
253 u8 *in_aml_address,
254 char **out_name_string,
255 u32 *out_name_length)
256{
257 acpi_status status = AE_OK;
258 u8 *aml_address = in_aml_address;
259 char *name_string = NULL;
260 u32 num_segments;
261 u32 prefix_count = 0;
262 u8 has_prefix = FALSE;
263
264
265 ACPI_FUNCTION_TRACE_PTR ("ex_get_name_string", aml_address);
266
267
268 if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type ||
269 ACPI_TYPE_LOCAL_BANK_FIELD == data_type ||
270 ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) {
271 /* Disallow prefixes for types associated with field_unit names */
272
273 name_string = acpi_ex_allocate_name_string (0, 1);
274 if (!name_string) {
275 status = AE_NO_MEMORY;
276 }
277 else {
278 status = acpi_ex_name_segment (&aml_address, name_string);
279 }
280 }
281 else {
282 /*
283 * data_type is not a field name.
284 * Examine first character of name for root or parent prefix operators
285 */
286 switch (*aml_address) {
287 case AML_ROOT_PREFIX:
288
289 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n", aml_address));
290
291 /*
292 * Remember that we have a root_prefix --
293 * see comment in acpi_ex_allocate_name_string()
294 */
295 aml_address++;
296 prefix_count = ACPI_UINT32_MAX;
297 has_prefix = TRUE;
298 break;
299
300
301 case AML_PARENT_PREFIX:
302
303 /* Increment past possibly multiple parent prefixes */
304
305 do {
306 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n", aml_address));
307
308 aml_address++;
309 prefix_count++;
310
311 } while (*aml_address == AML_PARENT_PREFIX);
312
313 has_prefix = TRUE;
314 break;
315
316
317 default:
318
319 /* Not a prefix character */
320
321 break;
322 }
323
324
325 /* Examine first character of name for name segment prefix operator */
326
327 switch (*aml_address) {
328 case AML_DUAL_NAME_PREFIX:
329
330 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n", aml_address));
331
332 aml_address++;
333 name_string = acpi_ex_allocate_name_string (prefix_count, 2);
334 if (!name_string) {
335 status = AE_NO_MEMORY;
336 break;
337 }
338
339 /* Indicate that we processed a prefix */
340
341 has_prefix = TRUE;
342
343 status = acpi_ex_name_segment (&aml_address, name_string);
344 if (ACPI_SUCCESS (status)) {
345 status = acpi_ex_name_segment (&aml_address, name_string);
346 }
347 break;
348
349
350 case AML_MULTI_NAME_PREFIX_OP:
351
352 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n", aml_address));
353
354 /* Fetch count of segments remaining in name path */
355
356 aml_address++;
357 num_segments = *aml_address;
358
359 name_string = acpi_ex_allocate_name_string (prefix_count, num_segments);
360 if (!name_string) {
361 status = AE_NO_MEMORY;
362 break;
363 }
364
365 /* Indicate that we processed a prefix */
366
367 aml_address++;
368 has_prefix = TRUE;
369
370 while (num_segments &&
371 (status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) {
372 num_segments--;
373 }
374
375 break;
376
377
378 case 0:
379
380 /* null_name valid as of 8-12-98 ASL/AML Grammar Update */
381
382 if (prefix_count == ACPI_UINT32_MAX) {
383 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "name_seg is \"\\\" followed by NULL\n"));
384 }
385
386 /* Consume the NULL byte */
387
388 aml_address++;
389 name_string = acpi_ex_allocate_name_string (prefix_count, 0);
390 if (!name_string) {
391 status = AE_NO_MEMORY;
392 break;
393 }
394
395 break;
396
397
398 default:
399
400 /* Name segment string */
401
402 name_string = acpi_ex_allocate_name_string (prefix_count, 1);
403 if (!name_string) {
404 status = AE_NO_MEMORY;
405 break;
406 }
407
408 status = acpi_ex_name_segment (&aml_address, name_string);
409 break;
410 }
411 }
412
413 if (AE_CTRL_PENDING == status && has_prefix) {
414 /* Ran out of segments after processing a prefix */
415
416 ACPI_REPORT_ERROR (
417 ("ex_do_name: Malformed Name at %p\n", name_string));
418 status = AE_AML_BAD_NAME;
419 }
420
421 *out_name_string = name_string;
422 *out_name_length = (u32) (aml_address - in_aml_address);
423
424 return_ACPI_STATUS (status);
425}
426
427
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
new file mode 100644
index 000000000000..8482aefaf38b
--- /dev/null
+++ b/drivers/acpi/executer/exoparg1.c
@@ -0,0 +1,1013 @@
1
2/******************************************************************************
3 *
4 * Module Name: exoparg1 - AML execution - opcodes with 1 argument
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acparser.h>
48#include <acpi/acdispat.h>
49#include <acpi/acinterp.h>
50#include <acpi/amlcode.h>
51#include <acpi/acnamesp.h>
52
53
54#define _COMPONENT ACPI_EXECUTER
55 ACPI_MODULE_NAME ("exoparg1")
56
57
58/*!
59 * Naming convention for AML interpreter execution routines.
60 *
61 * The routines that begin execution of AML opcodes are named with a common
62 * convention based upon the number of arguments, the number of target operands,
63 * and whether or not a value is returned:
64 *
65 * AcpiExOpcode_xA_yT_zR
66 *
67 * Where:
68 *
69 * xA - ARGUMENTS: The number of arguments (input operands) that are
70 * required for this opcode type (0 through 6 args).
71 * yT - TARGETS: The number of targets (output operands) that are required
72 * for this opcode type (0, 1, or 2 targets).
73 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
74 * as the function return (0 or 1).
75 *
76 * The AcpiExOpcode* functions are called via the Dispatcher component with
77 * fully resolved operands.
78!*/
79
80/*******************************************************************************
81 *
82 * FUNCTION: acpi_ex_opcode_0A_0T_1R
83 *
84 * PARAMETERS: walk_state - Current state (contains AML opcode)
85 *
86 * RETURN: Status
87 *
88 * DESCRIPTION: Execute operator with no operands, one return value
89 *
90 ******************************************************************************/
91
92acpi_status
93acpi_ex_opcode_0A_0T_1R (
94 struct acpi_walk_state *walk_state)
95{
96 acpi_status status = AE_OK;
97 union acpi_operand_object *return_desc = NULL;
98
99
100 ACPI_FUNCTION_TRACE_STR ("ex_opcode_0A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
101
102
103 /* Examine the AML opcode */
104
105 switch (walk_state->opcode) {
106 case AML_TIMER_OP: /* Timer () */
107
108 /* Create a return object of type Integer */
109
110 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
111 if (!return_desc) {
112 status = AE_NO_MEMORY;
113 goto cleanup;
114 }
115
116 return_desc->integer.value = acpi_os_get_timer ();
117 break;
118
119 default: /* Unknown opcode */
120
121 ACPI_REPORT_ERROR (("acpi_ex_opcode_0A_0T_1R: Unknown opcode %X\n",
122 walk_state->opcode));
123 status = AE_AML_BAD_OPCODE;
124 break;
125 }
126
127cleanup:
128
129 if (!walk_state->result_obj) {
130 walk_state->result_obj = return_desc;
131 }
132
133 /* Delete return object on error */
134
135 if (ACPI_FAILURE (status)) {
136 acpi_ut_remove_reference (return_desc);
137 }
138
139 return_ACPI_STATUS (status);
140}
141
142
143/*******************************************************************************
144 *
145 * FUNCTION: acpi_ex_opcode_1A_0T_0R
146 *
147 * PARAMETERS: walk_state - Current state (contains AML opcode)
148 *
149 * RETURN: Status
150 *
151 * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
152 * object stack
153 *
154 ******************************************************************************/
155
156acpi_status
157acpi_ex_opcode_1A_0T_0R (
158 struct acpi_walk_state *walk_state)
159{
160 union acpi_operand_object **operand = &walk_state->operands[0];
161 acpi_status status = AE_OK;
162
163
164 ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
165
166
167 /* Examine the AML opcode */
168
169 switch (walk_state->opcode) {
170 case AML_RELEASE_OP: /* Release (mutex_object) */
171
172 status = acpi_ex_release_mutex (operand[0], walk_state);
173 break;
174
175
176 case AML_RESET_OP: /* Reset (event_object) */
177
178 status = acpi_ex_system_reset_event (operand[0]);
179 break;
180
181
182 case AML_SIGNAL_OP: /* Signal (event_object) */
183
184 status = acpi_ex_system_signal_event (operand[0]);
185 break;
186
187
188 case AML_SLEEP_OP: /* Sleep (msec_time) */
189
190 status = acpi_ex_system_do_suspend (operand[0]->integer.value);
191 break;
192
193
194 case AML_STALL_OP: /* Stall (usec_time) */
195
196 status = acpi_ex_system_do_stall ((u32) operand[0]->integer.value);
197 break;
198
199
200 case AML_UNLOAD_OP: /* Unload (Handle) */
201
202 status = acpi_ex_unload_table (operand[0]);
203 break;
204
205
206 default: /* Unknown opcode */
207
208 ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n",
209 walk_state->opcode));
210 status = AE_AML_BAD_OPCODE;
211 break;
212 }
213
214 return_ACPI_STATUS (status);
215}
216
217
218/*******************************************************************************
219 *
220 * FUNCTION: acpi_ex_opcode_1A_1T_0R
221 *
222 * PARAMETERS: walk_state - Current state (contains AML opcode)
223 *
224 * RETURN: Status
225 *
226 * DESCRIPTION: Execute opcode with one argument, one target, and no
227 * return value.
228 *
229 ******************************************************************************/
230
231acpi_status
232acpi_ex_opcode_1A_1T_0R (
233 struct acpi_walk_state *walk_state)
234{
235 acpi_status status = AE_OK;
236 union acpi_operand_object **operand = &walk_state->operands[0];
237
238
239 ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
240
241
242 /* Examine the AML opcode */
243
244 switch (walk_state->opcode) {
245 case AML_LOAD_OP:
246
247 status = acpi_ex_load_op (operand[0], operand[1], walk_state);
248 break;
249
250 default: /* Unknown opcode */
251
252 ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n",
253 walk_state->opcode));
254 status = AE_AML_BAD_OPCODE;
255 goto cleanup;
256 }
257
258
259cleanup:
260
261 return_ACPI_STATUS (status);
262}
263
264
265/*******************************************************************************
266 *
267 * FUNCTION: acpi_ex_opcode_1A_1T_1R
268 *
269 * PARAMETERS: walk_state - Current state (contains AML opcode)
270 *
271 * RETURN: Status
272 *
273 * DESCRIPTION: Execute opcode with one argument, one target, and a
274 * return value.
275 *
276 ******************************************************************************/
277
278acpi_status
279acpi_ex_opcode_1A_1T_1R (
280 struct acpi_walk_state *walk_state)
281{
282 acpi_status status = AE_OK;
283 union acpi_operand_object **operand = &walk_state->operands[0];
284 union acpi_operand_object *return_desc = NULL;
285 union acpi_operand_object *return_desc2 = NULL;
286 u32 temp32;
287 u32 i;
288 acpi_integer power_of_ten;
289 acpi_integer digit;
290
291
292 ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
293
294
295 /* Examine the AML opcode */
296
297 switch (walk_state->opcode) {
298 case AML_BIT_NOT_OP:
299 case AML_FIND_SET_LEFT_BIT_OP:
300 case AML_FIND_SET_RIGHT_BIT_OP:
301 case AML_FROM_BCD_OP:
302 case AML_TO_BCD_OP:
303 case AML_COND_REF_OF_OP:
304
305 /* Create a return object of type Integer for these opcodes */
306
307 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
308 if (!return_desc) {
309 status = AE_NO_MEMORY;
310 goto cleanup;
311 }
312
313 switch (walk_state->opcode) {
314 case AML_BIT_NOT_OP: /* Not (Operand, Result) */
315
316 return_desc->integer.value = ~operand[0]->integer.value;
317 break;
318
319
320 case AML_FIND_SET_LEFT_BIT_OP: /* find_set_left_bit (Operand, Result) */
321
322 return_desc->integer.value = operand[0]->integer.value;
323
324 /*
325 * Acpi specification describes Integer type as a little
326 * endian unsigned value, so this boundary condition is valid.
327 */
328 for (temp32 = 0; return_desc->integer.value &&
329 temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
330 return_desc->integer.value >>= 1;
331 }
332
333 return_desc->integer.value = temp32;
334 break;
335
336
337 case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */
338
339 return_desc->integer.value = operand[0]->integer.value;
340
341 /*
342 * The Acpi specification describes Integer type as a little
343 * endian unsigned value, so this boundary condition is valid.
344 */
345 for (temp32 = 0; return_desc->integer.value &&
346 temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
347 return_desc->integer.value <<= 1;
348 }
349
350 /* Since the bit position is one-based, subtract from 33 (65) */
351
352 return_desc->integer.value = temp32 == 0 ? 0 :
353 (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
354 break;
355
356
357 case AML_FROM_BCD_OP: /* from_bcd (BCDValue, Result) */
358
359 /*
360 * The 64-bit ACPI integer can hold 16 4-bit BCD characters
361 * (if table is 32-bit, integer can hold 8 BCD characters)
362 * Convert each 4-bit BCD value
363 */
364 power_of_ten = 1;
365 return_desc->integer.value = 0;
366 digit = operand[0]->integer.value;
367
368 /* Convert each BCD digit (each is one nybble wide) */
369
370 for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
371 /* Get the least significant 4-bit BCD digit */
372
373 temp32 = ((u32) digit) & 0xF;
374
375 /* Check the range of the digit */
376
377 if (temp32 > 9) {
378 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
379 "BCD digit too large (not decimal): 0x%X\n",
380 temp32));
381
382 status = AE_AML_NUMERIC_OVERFLOW;
383 goto cleanup;
384 }
385
386 /* Sum the digit into the result with the current power of 10 */
387
388 return_desc->integer.value += (((acpi_integer) temp32) *
389 power_of_ten);
390
391 /* Shift to next BCD digit */
392
393 digit >>= 4;
394
395 /* Next power of 10 */
396
397 power_of_ten *= 10;
398 }
399 break;
400
401
402 case AML_TO_BCD_OP: /* to_bcd (Operand, Result) */
403
404 return_desc->integer.value = 0;
405 digit = operand[0]->integer.value;
406
407 /* Each BCD digit is one nybble wide */
408
409 for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
410 (void) acpi_ut_short_divide (digit, 10, &digit, &temp32);
411
412 /* Insert the BCD digit that resides in the remainder from above */
413
414 return_desc->integer.value |= (((acpi_integer) temp32) <<
415 ACPI_MUL_4 (i));
416 }
417
418 /* Overflow if there is any data left in Digit */
419
420 if (digit > 0) {
421 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
422 "Integer too large to convert to BCD: %8.8X%8.8X\n",
423 ACPI_FORMAT_UINT64 (operand[0]->integer.value)));
424 status = AE_AML_NUMERIC_OVERFLOW;
425 goto cleanup;
426 }
427 break;
428
429
430 case AML_COND_REF_OF_OP: /* cond_ref_of (source_object, Result) */
431
432 /*
433 * This op is a little strange because the internal return value is
434 * different than the return value stored in the result descriptor
435 * (There are really two return values)
436 */
437 if ((struct acpi_namespace_node *) operand[0] == acpi_gbl_root_node) {
438 /*
439 * This means that the object does not exist in the namespace,
440 * return FALSE
441 */
442 return_desc->integer.value = 0;
443 goto cleanup;
444 }
445
446 /* Get the object reference, store it, and remove our reference */
447
448 status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state);
449 if (ACPI_FAILURE (status)) {
450 goto cleanup;
451 }
452
453 status = acpi_ex_store (return_desc2, operand[1], walk_state);
454 acpi_ut_remove_reference (return_desc2);
455
456 /* The object exists in the namespace, return TRUE */
457
458 return_desc->integer.value = ACPI_INTEGER_MAX;
459 goto cleanup;
460
461
462 default:
463 /* No other opcodes get here */
464 break;
465 }
466 break;
467
468
469 case AML_STORE_OP: /* Store (Source, Target) */
470
471 /*
472 * A store operand is typically a number, string, buffer or lvalue
473 * Be careful about deleting the source object,
474 * since the object itself may have been stored.
475 */
476 status = acpi_ex_store (operand[0], operand[1], walk_state);
477 if (ACPI_FAILURE (status)) {
478 return_ACPI_STATUS (status);
479 }
480
481 /* It is possible that the Store already produced a return object */
482
483 if (!walk_state->result_obj) {
484 /*
485 * Normally, we would remove a reference on the Operand[0] parameter;
486 * But since it is being used as the internal return object
487 * (meaning we would normally increment it), the two cancel out,
488 * and we simply don't do anything.
489 */
490 walk_state->result_obj = operand[0];
491 walk_state->operands[0] = NULL; /* Prevent deletion */
492 }
493 return_ACPI_STATUS (status);
494
495
496 /*
497 * ACPI 2.0 Opcodes
498 */
499 case AML_COPY_OP: /* Copy (Source, Target) */
500
501 status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc,
502 walk_state);
503 break;
504
505
506 case AML_TO_DECSTRING_OP: /* to_decimal_string (Data, Result) */
507
508 status = acpi_ex_convert_to_string (operand[0], &return_desc,
509 ACPI_EXPLICIT_CONVERT_DECIMAL);
510 if (return_desc == operand[0]) {
511 /* No conversion performed, add ref to handle return value */
512 acpi_ut_add_reference (return_desc);
513 }
514 break;
515
516
517 case AML_TO_HEXSTRING_OP: /* to_hex_string (Data, Result) */
518
519 status = acpi_ex_convert_to_string (operand[0], &return_desc,
520 ACPI_EXPLICIT_CONVERT_HEX);
521 if (return_desc == operand[0]) {
522 /* No conversion performed, add ref to handle return value */
523 acpi_ut_add_reference (return_desc);
524 }
525 break;
526
527
528 case AML_TO_BUFFER_OP: /* to_buffer (Data, Result) */
529
530 status = acpi_ex_convert_to_buffer (operand[0], &return_desc);
531 if (return_desc == operand[0]) {
532 /* No conversion performed, add ref to handle return value */
533 acpi_ut_add_reference (return_desc);
534 }
535 break;
536
537
538 case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */
539
540 status = acpi_ex_convert_to_integer (operand[0], &return_desc,
541 ACPI_ANY_BASE);
542 if (return_desc == operand[0]) {
543 /* No conversion performed, add ref to handle return value */
544 acpi_ut_add_reference (return_desc);
545 }
546 break;
547
548
549 case AML_SHIFT_LEFT_BIT_OP: /* shift_left_bit (Source, bit_num) */
550 case AML_SHIFT_RIGHT_BIT_OP: /* shift_right_bit (Source, bit_num) */
551
552 /*
553 * These are two obsolete opcodes
554 */
555 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
556 "%s is obsolete and not implemented\n",
557 acpi_ps_get_opcode_name (walk_state->opcode)));
558 status = AE_SUPPORT;
559 goto cleanup;
560
561
562 default: /* Unknown opcode */
563
564 ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n",
565 walk_state->opcode));
566 status = AE_AML_BAD_OPCODE;
567 goto cleanup;
568 }
569
570 if (ACPI_SUCCESS (status)) {
571 /*
572 * Store the return value computed above into the target object
573 */
574 status = acpi_ex_store (return_desc, operand[1], walk_state);
575 }
576
577
578cleanup:
579
580 if (!walk_state->result_obj) {
581 walk_state->result_obj = return_desc;
582 }
583
584 /* Delete return object on error */
585
586 if (ACPI_FAILURE (status)) {
587 acpi_ut_remove_reference (return_desc);
588 }
589
590 return_ACPI_STATUS (status);
591}
592
593
594/*******************************************************************************
595 *
596 * FUNCTION: acpi_ex_opcode_1A_0T_1R
597 *
598 * PARAMETERS: walk_state - Current state (contains AML opcode)
599 *
600 * RETURN: Status
601 *
602 * DESCRIPTION: Execute opcode with one argument, no target, and a return value
603 *
604 ******************************************************************************/
605
606acpi_status
607acpi_ex_opcode_1A_0T_1R (
608 struct acpi_walk_state *walk_state)
609{
610 union acpi_operand_object **operand = &walk_state->operands[0];
611 union acpi_operand_object *temp_desc;
612 union acpi_operand_object *return_desc = NULL;
613 acpi_status status = AE_OK;
614 u32 type;
615 acpi_integer value;
616
617
618 ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
619
620
621 /* Examine the AML opcode */
622
623 switch (walk_state->opcode) {
624 case AML_LNOT_OP: /* LNot (Operand) */
625
626 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
627 if (!return_desc) {
628 status = AE_NO_MEMORY;
629 goto cleanup;
630 }
631
632 /*
633 * Set result to ONES (TRUE) if Value == 0. Note:
634 * return_desc->Integer.Value is initially == 0 (FALSE) from above.
635 */
636 if (!operand[0]->integer.value) {
637 return_desc->integer.value = ACPI_INTEGER_MAX;
638 }
639 break;
640
641
642 case AML_DECREMENT_OP: /* Decrement (Operand) */
643 case AML_INCREMENT_OP: /* Increment (Operand) */
644
645 /*
646 * Create a new integer. Can't just get the base integer and
647 * increment it because it may be an Arg or Field.
648 */
649 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
650 if (!return_desc) {
651 status = AE_NO_MEMORY;
652 goto cleanup;
653 }
654
655 /*
656 * Since we are expecting a Reference operand, it can be either a
657 * NS Node or an internal object.
658 */
659 temp_desc = operand[0];
660 if (ACPI_GET_DESCRIPTOR_TYPE (temp_desc) == ACPI_DESC_TYPE_OPERAND) {
661 /* Internal reference object - prevent deletion */
662
663 acpi_ut_add_reference (temp_desc);
664 }
665
666 /*
667 * Convert the Reference operand to an Integer (This removes a
668 * reference on the Operand[0] object)
669 *
670 * NOTE: We use LNOT_OP here in order to force resolution of the
671 * reference operand to an actual integer.
672 */
673 status = acpi_ex_resolve_operands (AML_LNOT_OP, &temp_desc, walk_state);
674 if (ACPI_FAILURE (status)) {
675 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n",
676 acpi_ps_get_opcode_name (walk_state->opcode),
677 acpi_format_exception(status)));
678
679 goto cleanup;
680 }
681
682 /*
683 * temp_desc is now guaranteed to be an Integer object --
684 * Perform the actual increment or decrement
685 */
686 if (walk_state->opcode == AML_INCREMENT_OP) {
687 return_desc->integer.value = temp_desc->integer.value +1;
688 }
689 else {
690 return_desc->integer.value = temp_desc->integer.value -1;
691 }
692
693 /* Finished with this Integer object */
694
695 acpi_ut_remove_reference (temp_desc);
696
697 /*
698 * Store the result back (indirectly) through the original
699 * Reference object
700 */
701 status = acpi_ex_store (return_desc, operand[0], walk_state);
702 break;
703
704
705 case AML_TYPE_OP: /* object_type (source_object) */
706
707 /*
708 * Note: The operand is not resolved at this point because we want to
709 * get the associated object, not its value. For example, we don't want
710 * to resolve a field_unit to its value, we want the actual field_unit
711 * object.
712 */
713
714 /* Get the type of the base object */
715
716 status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, NULL);
717 if (ACPI_FAILURE (status)) {
718 goto cleanup;
719 }
720 /* Allocate a descriptor to hold the type. */
721
722 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
723 if (!return_desc) {
724 status = AE_NO_MEMORY;
725 goto cleanup;
726 }
727
728 return_desc->integer.value = type;
729 break;
730
731
732 case AML_SIZE_OF_OP: /* size_of (source_object) */
733
734 /*
735 * Note: The operand is not resolved at this point because we want to
736 * get the associated object, not its value.
737 */
738
739 /* Get the base object */
740
741 status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, &temp_desc);
742 if (ACPI_FAILURE (status)) {
743 goto cleanup;
744 }
745
746 /*
747 * The type of the base object must be integer, buffer, string, or
748 * package. All others are not supported.
749 *
750 * NOTE: Integer is not specifically supported by the ACPI spec,
751 * but is supported implicitly via implicit operand conversion.
752 * rather than bother with conversion, we just use the byte width
753 * global (4 or 8 bytes).
754 */
755 switch (type) {
756 case ACPI_TYPE_INTEGER:
757 value = acpi_gbl_integer_byte_width;
758 break;
759
760 case ACPI_TYPE_BUFFER:
761 value = temp_desc->buffer.length;
762 break;
763
764 case ACPI_TYPE_STRING:
765 value = temp_desc->string.length;
766 break;
767
768 case ACPI_TYPE_PACKAGE:
769 value = temp_desc->package.count;
770 break;
771
772 default:
773 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
774 "size_of - Operand is not Buf/Int/Str/Pkg - found type %s\n",
775 acpi_ut_get_type_name (type)));
776 status = AE_AML_OPERAND_TYPE;
777 goto cleanup;
778 }
779
780 /*
781 * Now that we have the size of the object, create a result
782 * object to hold the value
783 */
784 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
785 if (!return_desc) {
786 status = AE_NO_MEMORY;
787 goto cleanup;
788 }
789
790 return_desc->integer.value = value;
791 break;
792
793
794 case AML_REF_OF_OP: /* ref_of (source_object) */
795
796 status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state);
797 if (ACPI_FAILURE (status)) {
798 goto cleanup;
799 }
800 break;
801
802
803 case AML_DEREF_OF_OP: /* deref_of (obj_reference | String) */
804
805 /* Check for a method local or argument, or standalone String */
806
807 if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) != ACPI_DESC_TYPE_NAMED) {
808 switch (ACPI_GET_OBJECT_TYPE (operand[0])) {
809 case ACPI_TYPE_LOCAL_REFERENCE:
810 /*
811 * This is a deref_of (local_x | arg_x)
812 *
813 * Must resolve/dereference the local/arg reference first
814 */
815 switch (operand[0]->reference.opcode) {
816 case AML_LOCAL_OP:
817 case AML_ARG_OP:
818
819 /* Set Operand[0] to the value of the local/arg */
820
821 status = acpi_ds_method_data_get_value (operand[0]->reference.opcode,
822 operand[0]->reference.offset, walk_state, &temp_desc);
823 if (ACPI_FAILURE (status)) {
824 goto cleanup;
825 }
826
827 /*
828 * Delete our reference to the input object and
829 * point to the object just retrieved
830 */
831 acpi_ut_remove_reference (operand[0]);
832 operand[0] = temp_desc;
833 break;
834
835 case AML_REF_OF_OP:
836
837 /* Get the object to which the reference refers */
838
839 temp_desc = operand[0]->reference.object;
840 acpi_ut_remove_reference (operand[0]);
841 operand[0] = temp_desc;
842 break;
843
844 default:
845
846 /* Must be an Index op - handled below */
847 break;
848 }
849 break;
850
851
852 case ACPI_TYPE_STRING:
853
854 /*
855 * This is a deref_of (String). The string is a reference to a named ACPI object.
856 *
857 * 1) Find the owning Node
858 * 2) Dereference the node to an actual object. Could be a Field, so we nee
859 * to resolve the node to a value.
860 */
861 status = acpi_ns_get_node_by_path (operand[0]->string.pointer,
862 walk_state->scope_info->scope.node, ACPI_NS_SEARCH_PARENT,
863 ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc));
864 if (ACPI_FAILURE (status)) {
865 goto cleanup;
866 }
867
868 status = acpi_ex_resolve_node_to_value (
869 ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc), walk_state);
870 goto cleanup;
871
872
873 default:
874
875 status = AE_AML_OPERAND_TYPE;
876 goto cleanup;
877 }
878 }
879
880 /* Operand[0] may have changed from the code above */
881
882 if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_NAMED) {
883 /*
884 * This is a deref_of (object_reference)
885 * Get the actual object from the Node (This is the dereference).
886 * -- This case may only happen when a local_x or arg_x is dereferenced above.
887 */
888 return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) operand[0]);
889 }
890 else {
891 /*
892 * This must be a reference object produced by either the Index() or
893 * ref_of() operator
894 */
895 switch (operand[0]->reference.opcode) {
896 case AML_INDEX_OP:
897
898 /*
899 * The target type for the Index operator must be
900 * either a Buffer or a Package
901 */
902 switch (operand[0]->reference.target_type) {
903 case ACPI_TYPE_BUFFER_FIELD:
904
905 temp_desc = operand[0]->reference.object;
906
907 /*
908 * Create a new object that contains one element of the
909 * buffer -- the element pointed to by the index.
910 *
911 * NOTE: index into a buffer is NOT a pointer to a
912 * sub-buffer of the main buffer, it is only a pointer to a
913 * single element (byte) of the buffer!
914 */
915 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
916 if (!return_desc) {
917 status = AE_NO_MEMORY;
918 goto cleanup;
919 }
920
921 /*
922 * Since we are returning the value of the buffer at the
923 * indexed location, we don't need to add an additional
924 * reference to the buffer itself.
925 */
926 return_desc->integer.value =
927 temp_desc->buffer.pointer[operand[0]->reference.offset];
928 break;
929
930
931 case ACPI_TYPE_PACKAGE:
932
933 /*
934 * Return the referenced element of the package. We must add
935 * another reference to the referenced object, however.
936 */
937 return_desc = *(operand[0]->reference.where);
938 if (!return_desc) {
939 /*
940 * We can't return a NULL dereferenced value. This is
941 * an uninitialized package element and is thus a
942 * severe error.
943 */
944 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
945 "NULL package element obj %p\n",
946 operand[0]));
947 status = AE_AML_UNINITIALIZED_ELEMENT;
948 goto cleanup;
949 }
950
951 acpi_ut_add_reference (return_desc);
952 break;
953
954
955 default:
956
957 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
958 "Unknown Index target_type %X in obj %p\n",
959 operand[0]->reference.target_type, operand[0]));
960 status = AE_AML_OPERAND_TYPE;
961 goto cleanup;
962 }
963 break;
964
965
966 case AML_REF_OF_OP:
967
968 return_desc = operand[0]->reference.object;
969
970 if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) == ACPI_DESC_TYPE_NAMED) {
971
972 return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) return_desc);
973 }
974
975 /* Add another reference to the object! */
976
977 acpi_ut_add_reference (return_desc);
978 break;
979
980
981 default:
982 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
983 "Unknown opcode in ref(%p) - %X\n",
984 operand[0], operand[0]->reference.opcode));
985
986 status = AE_TYPE;
987 goto cleanup;
988 }
989 }
990 break;
991
992
993 default:
994
995 ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n",
996 walk_state->opcode));
997 status = AE_AML_BAD_OPCODE;
998 goto cleanup;
999 }
1000
1001
1002cleanup:
1003
1004 /* Delete return object on error */
1005
1006 if (ACPI_FAILURE (status)) {
1007 acpi_ut_remove_reference (return_desc);
1008 }
1009
1010 walk_state->result_obj = return_desc;
1011 return_ACPI_STATUS (status);
1012}
1013
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
new file mode 100644
index 000000000000..8be4d80ceed5
--- /dev/null
+++ b/drivers/acpi/executer/exoparg2.c
@@ -0,0 +1,608 @@
1/******************************************************************************
2 *
3 * Module Name: exoparg2 - AML execution - opcodes with 2 arguments
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <acpi/acpi.h>
46#include <acpi/acparser.h>
47#include <acpi/acinterp.h>
48#include <acpi/acevents.h>
49#include <acpi/amlcode.h>
50
51
52#define _COMPONENT ACPI_EXECUTER
53 ACPI_MODULE_NAME ("exoparg2")
54
55
56/*!
57 * Naming convention for AML interpreter execution routines.
58 *
59 * The routines that begin execution of AML opcodes are named with a common
60 * convention based upon the number of arguments, the number of target operands,
61 * and whether or not a value is returned:
62 *
63 * AcpiExOpcode_xA_yT_zR
64 *
65 * Where:
66 *
67 * xA - ARGUMENTS: The number of arguments (input operands) that are
68 * required for this opcode type (1 through 6 args).
69 * yT - TARGETS: The number of targets (output operands) that are required
70 * for this opcode type (0, 1, or 2 targets).
71 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
72 * as the function return (0 or 1).
73 *
74 * The AcpiExOpcode* functions are called via the Dispatcher component with
75 * fully resolved operands.
76!*/
77
78
79/*******************************************************************************
80 *
81 * FUNCTION: acpi_ex_opcode_2A_0T_0R
82 *
83 * PARAMETERS: walk_state - Current walk state
84 *
85 * RETURN: Status
86 *
87 * DESCRIPTION: Execute opcode with two arguments, no target, and no return
88 * value.
89 *
90 * ALLOCATION: Deletes both operands
91 *
92 ******************************************************************************/
93
94acpi_status
95acpi_ex_opcode_2A_0T_0R (
96 struct acpi_walk_state *walk_state)
97{
98 union acpi_operand_object **operand = &walk_state->operands[0];
99 struct acpi_namespace_node *node;
100 u32 value;
101 acpi_status status = AE_OK;
102
103
104 ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_0R",
105 acpi_ps_get_opcode_name (walk_state->opcode));
106
107
108 /* Examine the opcode */
109
110 switch (walk_state->opcode) {
111 case AML_NOTIFY_OP: /* Notify (notify_object, notify_value) */
112
113 /* The first operand is a namespace node */
114
115 node = (struct acpi_namespace_node *) operand[0];
116
117 /* Second value is the notify value */
118
119 value = (u32) operand[1]->integer.value;
120
121 /* Notifies allowed on this object? */
122
123 if (!acpi_ev_is_notify_object (node)) {
124 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
125 "Unexpected notify object type [%s]\n",
126 acpi_ut_get_type_name (node->type)));
127
128 status = AE_AML_OPERAND_TYPE;
129 break;
130 }
131
132#ifdef ACPI_GPE_NOTIFY_CHECK
133 /*
134 * GPE method wake/notify check. Here, we want to ensure that we
135 * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx
136 * GPE method during system runtime. If we do, the GPE is marked
137 * as "wake-only" and disabled.
138 *
139 * 1) Is the Notify() value == device_wake?
140 * 2) Is this a GPE deferred method? (An _Lxx or _Exx method)
141 * 3) Did the original GPE happen at system runtime?
142 * (versus during wake)
143 *
144 * If all three cases are true, this is a wake-only GPE that should
145 * be disabled at runtime.
146 */
147 if (value == 2) /* device_wake */ {
148 status = acpi_ev_check_for_wake_only_gpe (walk_state->gpe_event_info);
149 if (ACPI_FAILURE (status)) {
150 /* AE_WAKE_ONLY_GPE only error, means ignore this notify */
151
152 return_ACPI_STATUS (AE_OK)
153 }
154 }
155#endif
156
157 /*
158 * Dispatch the notify to the appropriate handler
159 * NOTE: the request is queued for execution after this method
160 * completes. The notify handlers are NOT invoked synchronously
161 * from this thread -- because handlers may in turn run other
162 * control methods.
163 */
164 status = acpi_ev_queue_notify_request (node, value);
165 break;
166
167
168 default:
169
170 ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n",
171 walk_state->opcode));
172 status = AE_AML_BAD_OPCODE;
173 }
174
175 return_ACPI_STATUS (status);
176}
177
178
179/*******************************************************************************
180 *
181 * FUNCTION: acpi_ex_opcode_2A_2T_1R
182 *
183 * PARAMETERS: walk_state - Current walk state
184 *
185 * RETURN: Status
186 *
187 * DESCRIPTION: Execute a dyadic operator (2 operands) with 2 output targets
188 * and one implicit return value.
189 *
190 ******************************************************************************/
191
192acpi_status
193acpi_ex_opcode_2A_2T_1R (
194 struct acpi_walk_state *walk_state)
195{
196 union acpi_operand_object **operand = &walk_state->operands[0];
197 union acpi_operand_object *return_desc1 = NULL;
198 union acpi_operand_object *return_desc2 = NULL;
199 acpi_status status;
200
201
202 ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_2T_1R",
203 acpi_ps_get_opcode_name (walk_state->opcode));
204
205
206 /*
207 * Execute the opcode
208 */
209 switch (walk_state->opcode) {
210 case AML_DIVIDE_OP: /* Divide (Dividend, Divisor, remainder_result quotient_result) */
211
212 return_desc1 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
213 if (!return_desc1) {
214 status = AE_NO_MEMORY;
215 goto cleanup;
216 }
217
218 return_desc2 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
219 if (!return_desc2) {
220 status = AE_NO_MEMORY;
221 goto cleanup;
222 }
223
224 /* Quotient to return_desc1, remainder to return_desc2 */
225
226 status = acpi_ut_divide (operand[0]->integer.value,
227 operand[1]->integer.value,
228 &return_desc1->integer.value,
229 &return_desc2->integer.value);
230 if (ACPI_FAILURE (status)) {
231 goto cleanup;
232 }
233 break;
234
235
236 default:
237
238 ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_2T_1R: Unknown opcode %X\n",
239 walk_state->opcode));
240 status = AE_AML_BAD_OPCODE;
241 goto cleanup;
242 }
243
244
245 /* Store the results to the target reference operands */
246
247 status = acpi_ex_store (return_desc2, operand[2], walk_state);
248 if (ACPI_FAILURE (status)) {
249 goto cleanup;
250 }
251
252 status = acpi_ex_store (return_desc1, operand[3], walk_state);
253 if (ACPI_FAILURE (status)) {
254 goto cleanup;
255 }
256
257 /* Return the remainder */
258
259 walk_state->result_obj = return_desc1;
260
261
262cleanup:
263 /*
264 * Since the remainder is not returned indirectly, remove a reference to
265 * it. Only the quotient is returned indirectly.
266 */
267 acpi_ut_remove_reference (return_desc2);
268
269 if (ACPI_FAILURE (status)) {
270 /* Delete the return object */
271
272 acpi_ut_remove_reference (return_desc1);
273 }
274
275 return_ACPI_STATUS (status);
276}
277
278
279/*******************************************************************************
280 *
281 * FUNCTION: acpi_ex_opcode_2A_1T_1R
282 *
283 * PARAMETERS: walk_state - Current walk state
284 *
285 * RETURN: Status
286 *
287 * DESCRIPTION: Execute opcode with two arguments, one target, and a return
288 * value.
289 *
290 ******************************************************************************/
291
292acpi_status
293acpi_ex_opcode_2A_1T_1R (
294 struct acpi_walk_state *walk_state)
295{
296 union acpi_operand_object **operand = &walk_state->operands[0];
297 union acpi_operand_object *return_desc = NULL;
298 u32 index;
299 acpi_status status = AE_OK;
300 acpi_size length;
301
302
303 ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_1T_1R",
304 acpi_ps_get_opcode_name (walk_state->opcode));
305
306
307 /*
308 * Execute the opcode
309 */
310 if (walk_state->op_info->flags & AML_MATH) {
311 /* All simple math opcodes (add, etc.) */
312
313 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
314 if (!return_desc) {
315 status = AE_NO_MEMORY;
316 goto cleanup;
317 }
318
319 return_desc->integer.value = acpi_ex_do_math_op (walk_state->opcode,
320 operand[0]->integer.value,
321 operand[1]->integer.value);
322 goto store_result_to_target;
323 }
324
325
326 switch (walk_state->opcode) {
327 case AML_MOD_OP: /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
328
329 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
330 if (!return_desc) {
331 status = AE_NO_MEMORY;
332 goto cleanup;
333 }
334
335 /* return_desc will contain the remainder */
336
337 status = acpi_ut_divide (operand[0]->integer.value,
338 operand[1]->integer.value,
339 NULL,
340 &return_desc->integer.value);
341 break;
342
343
344 case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
345
346 status = acpi_ex_do_concatenate (operand[0], operand[1],
347 &return_desc, walk_state);
348 break;
349
350
351 case AML_TO_STRING_OP: /* to_string (Buffer, Length, Result) (ACPI 2.0) */
352
353 /*
354 * Input object is guaranteed to be a buffer at this point (it may have
355 * been converted.) Copy the raw buffer data to a new object of type String.
356 */
357
358 /*
359 * Get the length of the new string. It is the smallest of:
360 * 1) Length of the input buffer
361 * 2) Max length as specified in the to_string operator
362 * 3) Length of input buffer up to a zero byte (null terminator)
363 *
364 * NOTE: A length of zero is ok, and will create a zero-length, null
365 * terminated string.
366 */
367 length = 0;
368 while ((length < operand[0]->buffer.length) &&
369 (length < operand[1]->integer.value) &&
370 (operand[0]->buffer.pointer[length])) {
371 length++;
372 if (length > ACPI_MAX_STRING_CONVERSION) {
373 status = AE_AML_STRING_LIMIT;
374 goto cleanup;
375 }
376 }
377
378 /* Allocate a new string object */
379
380 return_desc = acpi_ut_create_string_object (length);
381 if (!return_desc) {
382 status = AE_NO_MEMORY;
383 goto cleanup;
384 }
385
386 /* Copy the raw buffer data with no transform. NULL terminated already. */
387
388 ACPI_MEMCPY (return_desc->string.pointer,
389 operand[0]->buffer.pointer, length);
390 break;
391
392
393 case AML_CONCAT_RES_OP: /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
394
395 status = acpi_ex_concat_template (operand[0], operand[1],
396 &return_desc, walk_state);
397 break;
398
399
400 case AML_INDEX_OP: /* Index (Source Index Result) */
401
402 /* Create the internal return object */
403
404 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
405 if (!return_desc) {
406 status = AE_NO_MEMORY;
407 goto cleanup;
408 }
409
410 index = (u32) operand[1]->integer.value;
411
412 /*
413 * At this point, the Source operand is a Package, Buffer, or String
414 */
415 if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) {
416 /* Object to be indexed is a Package */
417
418 if (index >= operand[0]->package.count) {
419 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
420 "Index value (%X) beyond package end (%X)\n",
421 index, operand[0]->package.count));
422 status = AE_AML_PACKAGE_LIMIT;
423 goto cleanup;
424 }
425
426 return_desc->reference.target_type = ACPI_TYPE_PACKAGE;
427 return_desc->reference.object = operand[0];
428 return_desc->reference.where = &operand[0]->package.elements [index];
429 }
430 else {
431 /* Object to be indexed is a Buffer/String */
432
433 if (index >= operand[0]->buffer.length) {
434 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
435 "Index value (%X) beyond end of buffer (%X)\n",
436 index, operand[0]->buffer.length));
437 status = AE_AML_BUFFER_LIMIT;
438 goto cleanup;
439 }
440
441 return_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD;
442 return_desc->reference.object = operand[0];
443 }
444
445 /*
446 * Add a reference to the target package/buffer/string for the life
447 * of the index.
448 */
449 acpi_ut_add_reference (operand[0]);
450
451 /* Complete the Index reference object */
452
453 return_desc->reference.opcode = AML_INDEX_OP;
454 return_desc->reference.offset = index;
455
456 /* Store the reference to the Target */
457
458 status = acpi_ex_store (return_desc, operand[2], walk_state);
459
460 /* Return the reference */
461
462 walk_state->result_obj = return_desc;
463 goto cleanup;
464
465
466 default:
467
468 ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_1T_1R: Unknown opcode %X\n",
469 walk_state->opcode));
470 status = AE_AML_BAD_OPCODE;
471 break;
472 }
473
474
475store_result_to_target:
476
477 if (ACPI_SUCCESS (status)) {
478 /*
479 * Store the result of the operation (which is now in return_desc) into
480 * the Target descriptor.
481 */
482 status = acpi_ex_store (return_desc, operand[2], walk_state);
483 if (ACPI_FAILURE (status)) {
484 goto cleanup;
485 }
486
487 if (!walk_state->result_obj) {
488 walk_state->result_obj = return_desc;
489 }
490 }
491
492
493cleanup:
494
495 /* Delete return object on error */
496
497 if (ACPI_FAILURE (status)) {
498 acpi_ut_remove_reference (return_desc);
499 }
500
501 return_ACPI_STATUS (status);
502}
503
504
505/*******************************************************************************
506 *
507 * FUNCTION: acpi_ex_opcode_2A_0T_1R
508 *
509 * PARAMETERS: walk_state - Current walk state
510 *
511 * RETURN: Status
512 *
513 * DESCRIPTION: Execute opcode with 2 arguments, no target, and a return value
514 *
515 ******************************************************************************/
516
517acpi_status
518acpi_ex_opcode_2A_0T_1R (
519 struct acpi_walk_state *walk_state)
520{
521 union acpi_operand_object **operand = &walk_state->operands[0];
522 union acpi_operand_object *return_desc = NULL;
523 acpi_status status = AE_OK;
524 u8 logical_result = FALSE;
525
526
527 ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_1R",
528 acpi_ps_get_opcode_name (walk_state->opcode));
529
530
531 /* Create the internal return object */
532
533 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
534 if (!return_desc) {
535 status = AE_NO_MEMORY;
536 goto cleanup;
537 }
538
539 /*
540 * Execute the Opcode
541 */
542 if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) /* logical_op (Operand0, Operand1) */ {
543 status = acpi_ex_do_logical_numeric_op (walk_state->opcode,
544 operand[0]->integer.value, operand[1]->integer.value,
545 &logical_result);
546 goto store_logical_result;
547 }
548 else if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ {
549 status = acpi_ex_do_logical_op (walk_state->opcode, operand[0],
550 operand[1], &logical_result);
551 goto store_logical_result;
552 }
553
554
555 switch (walk_state->opcode) {
556 case AML_ACQUIRE_OP: /* Acquire (mutex_object, Timeout) */
557
558 status = acpi_ex_acquire_mutex (operand[1], operand[0], walk_state);
559 if (status == AE_TIME) {
560 logical_result = TRUE; /* TRUE = Acquire timed out */
561 status = AE_OK;
562 }
563 break;
564
565
566 case AML_WAIT_OP: /* Wait (event_object, Timeout) */
567
568 status = acpi_ex_system_wait_event (operand[1], operand[0]);
569 if (status == AE_TIME) {
570 logical_result = TRUE; /* TRUE, Wait timed out */
571 status = AE_OK;
572 }
573 break;
574
575
576 default:
577
578 ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n",
579 walk_state->opcode));
580 status = AE_AML_BAD_OPCODE;
581 goto cleanup;
582 }
583
584
585store_logical_result:
586 /*
587 * Set return value to according to logical_result. logical TRUE (all ones)
588 * Default is FALSE (zero)
589 */
590 if (logical_result) {
591 return_desc->integer.value = ACPI_INTEGER_MAX;
592 }
593
594 walk_state->result_obj = return_desc;
595
596
597cleanup:
598
599 /* Delete return object on error */
600
601 if (ACPI_FAILURE (status)) {
602 acpi_ut_remove_reference (return_desc);
603 }
604
605 return_ACPI_STATUS (status);
606}
607
608
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
new file mode 100644
index 000000000000..29d0b167745d
--- /dev/null
+++ b/drivers/acpi/executer/exoparg3.c
@@ -0,0 +1,256 @@
1
2/******************************************************************************
3 *
4 * Module Name: exoparg3 - AML execution - opcodes with 3 arguments
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acinterp.h>
48#include <acpi/acparser.h>
49#include <acpi/amlcode.h>
50
51
52#define _COMPONENT ACPI_EXECUTER
53 ACPI_MODULE_NAME ("exoparg3")
54
55
56/*!
57 * Naming convention for AML interpreter execution routines.
58 *
59 * The routines that begin execution of AML opcodes are named with a common
60 * convention based upon the number of arguments, the number of target operands,
61 * and whether or not a value is returned:
62 *
63 * AcpiExOpcode_xA_yT_zR
64 *
65 * Where:
66 *
67 * xA - ARGUMENTS: The number of arguments (input operands) that are
68 * required for this opcode type (1 through 6 args).
69 * yT - TARGETS: The number of targets (output operands) that are required
70 * for this opcode type (0, 1, or 2 targets).
71 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
72 * as the function return (0 or 1).
73 *
74 * The AcpiExOpcode* functions are called via the Dispatcher component with
75 * fully resolved operands.
76!*/
77
78
79/*******************************************************************************
80 *
81 * FUNCTION: acpi_ex_opcode_3A_0T_0R
82 *
83 * PARAMETERS: walk_state - Current walk state
84 *
85 * RETURN: Status
86 *
87 * DESCRIPTION: Execute Triadic operator (3 operands)
88 *
89 ******************************************************************************/
90
91acpi_status
92acpi_ex_opcode_3A_0T_0R (
93 struct acpi_walk_state *walk_state)
94{
95 union acpi_operand_object **operand = &walk_state->operands[0];
96 struct acpi_signal_fatal_info *fatal;
97 acpi_status status = AE_OK;
98
99
100 ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
101
102
103 switch (walk_state->opcode) {
104 case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */
105
106 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
107 "fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
108 (u32) operand[0]->integer.value,
109 (u32) operand[1]->integer.value,
110 (u32) operand[2]->integer.value));
111
112 fatal = ACPI_MEM_ALLOCATE (sizeof (struct acpi_signal_fatal_info));
113 if (fatal) {
114 fatal->type = (u32) operand[0]->integer.value;
115 fatal->code = (u32) operand[1]->integer.value;
116 fatal->argument = (u32) operand[2]->integer.value;
117 }
118
119 /*
120 * Always signal the OS!
121 */
122 status = acpi_os_signal (ACPI_SIGNAL_FATAL, fatal);
123
124 /* Might return while OS is shutting down, just continue */
125
126 ACPI_MEM_FREE (fatal);
127 break;
128
129
130 default:
131
132 ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
133 walk_state->opcode));
134 status = AE_AML_BAD_OPCODE;
135 goto cleanup;
136 }
137
138
139cleanup:
140
141 return_ACPI_STATUS (status);
142}
143
144
145/*******************************************************************************
146 *
147 * FUNCTION: acpi_ex_opcode_3A_1T_1R
148 *
149 * PARAMETERS: walk_state - Current walk state
150 *
151 * RETURN: Status
152 *
153 * DESCRIPTION: Execute Triadic operator (3 operands)
154 *
155 ******************************************************************************/
156
157acpi_status
158acpi_ex_opcode_3A_1T_1R (
159 struct acpi_walk_state *walk_state)
160{
161 union acpi_operand_object **operand = &walk_state->operands[0];
162 union acpi_operand_object *return_desc = NULL;
163 char *buffer;
164 acpi_status status = AE_OK;
165 acpi_native_uint index;
166 acpi_size length;
167
168
169 ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
170
171
172 switch (walk_state->opcode) {
173 case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
174
175 /*
176 * Create the return object. The Source operand is guaranteed to be
177 * either a String or a Buffer, so just use its type.
178 */
179 return_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (operand[0]));
180 if (!return_desc) {
181 status = AE_NO_MEMORY;
182 goto cleanup;
183 }
184
185 /* Get the Integer values from the objects */
186
187 index = (acpi_native_uint) operand[1]->integer.value;
188 length = (acpi_size) operand[2]->integer.value;
189
190 /*
191 * If the index is beyond the length of the String/Buffer, or if the
192 * requested length is zero, return a zero-length String/Buffer
193 */
194 if ((index < operand[0]->string.length) &&
195 (length > 0)) {
196 /* Truncate request if larger than the actual String/Buffer */
197
198 if ((index + length) >
199 operand[0]->string.length) {
200 length = (acpi_size) operand[0]->string.length - index;
201 }
202
203 /* Allocate a new buffer for the String/Buffer */
204
205 buffer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1);
206 if (!buffer) {
207 status = AE_NO_MEMORY;
208 goto cleanup;
209 }
210
211 /* Copy the portion requested */
212
213 ACPI_MEMCPY (buffer, operand[0]->string.pointer + index,
214 length);
215
216 /* Set the length of the new String/Buffer */
217
218 return_desc->string.pointer = buffer;
219 return_desc->string.length = (u32) length;
220 }
221
222 /* Mark buffer initialized */
223
224 return_desc->buffer.flags |= AOPOBJ_DATA_VALID;
225 break;
226
227
228 default:
229
230 ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
231 walk_state->opcode));
232 status = AE_AML_BAD_OPCODE;
233 goto cleanup;
234 }
235
236 /* Store the result in the target */
237
238 status = acpi_ex_store (return_desc, operand[3], walk_state);
239
240cleanup:
241
242 /* Delete return object on error */
243
244 if (ACPI_FAILURE (status)) {
245 acpi_ut_remove_reference (return_desc);
246 }
247
248 /* Set the return object and exit */
249
250 if (!walk_state->result_obj) {
251 walk_state->result_obj = return_desc;
252 }
253 return_ACPI_STATUS (status);
254}
255
256
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
new file mode 100644
index 000000000000..d32624331626
--- /dev/null
+++ b/drivers/acpi/executer/exoparg6.c
@@ -0,0 +1,336 @@
1
2/******************************************************************************
3 *
4 * Module Name: exoparg6 - AML execution - opcodes with 6 arguments
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acinterp.h>
48#include <acpi/acparser.h>
49#include <acpi/amlcode.h>
50
51
52#define _COMPONENT ACPI_EXECUTER
53 ACPI_MODULE_NAME ("exoparg6")
54
55
56/*!
57 * Naming convention for AML interpreter execution routines.
58 *
59 * The routines that begin execution of AML opcodes are named with a common
60 * convention based upon the number of arguments, the number of target operands,
61 * and whether or not a value is returned:
62 *
63 * AcpiExOpcode_xA_yT_zR
64 *
65 * Where:
66 *
67 * xA - ARGUMENTS: The number of arguments (input operands) that are
68 * required for this opcode type (1 through 6 args).
69 * yT - TARGETS: The number of targets (output operands) that are required
70 * for this opcode type (0, 1, or 2 targets).
71 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
72 * as the function return (0 or 1).
73 *
74 * The AcpiExOpcode* functions are called via the Dispatcher component with
75 * fully resolved operands.
76!*/
77
78
79/*******************************************************************************
80 *
81 * FUNCTION: acpi_ex_do_match
82 *
83 * PARAMETERS: match_op - The AML match operand
84 * package_obj - Object from the target package
85 * match_obj - Object to be matched
86 *
87 * RETURN: TRUE if the match is successful, FALSE otherwise
88 *
89 * DESCRIPTION: Implements the low-level match for the ASL Match operator.
90 * Package elements will be implicitly converted to the type of
91 * the match object (Integer/Buffer/String).
92 *
93 ******************************************************************************/
94
95u8
96acpi_ex_do_match (
97 u32 match_op,
98 union acpi_operand_object *package_obj,
99 union acpi_operand_object *match_obj)
100{
101 u8 logical_result = TRUE;
102 acpi_status status;
103
104
105 /*
106 * Note: Since the package_obj/match_obj ordering is opposite to that of
107 * the standard logical operators, we have to reverse them when we call
108 * do_logical_op in order to make the implicit conversion rules work
109 * correctly. However, this means we have to flip the entire equation
110 * also. A bit ugly perhaps, but overall, better than fussing the
111 * parameters around at runtime, over and over again.
112 *
113 * Below, P[i] refers to the package element, M refers to the Match object.
114 */
115 switch (match_op) {
116 case MATCH_MTR:
117
118 /* Always true */
119
120 break;
121
122 case MATCH_MEQ:
123
124 /*
125 * True if equal: (P[i] == M)
126 * Change to: (M == P[i])
127 */
128 status = acpi_ex_do_logical_op (AML_LEQUAL_OP, match_obj, package_obj,
129 &logical_result);
130 if (ACPI_FAILURE (status)) {
131 return (FALSE);
132 }
133 break;
134
135 case MATCH_MLE:
136
137 /*
138 * True if less than or equal: (P[i] <= M) (P[i] not_greater than M)
139 * Change to: (M >= P[i]) (M not_less than P[i])
140 */
141 status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
142 &logical_result);
143 if (ACPI_FAILURE (status)) {
144 return (FALSE);
145 }
146 logical_result = (u8) !logical_result;
147 break;
148
149 case MATCH_MLT:
150
151 /*
152 * True if less than: (P[i] < M)
153 * Change to: (M > P[i])
154 */
155 status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
156 &logical_result);
157 if (ACPI_FAILURE (status)) {
158 return (FALSE);
159 }
160 break;
161
162 case MATCH_MGE:
163
164 /*
165 * True if greater than or equal: (P[i] >= M) (P[i] not_less than M)
166 * Change to: (M <= P[i]) (M not_greater than P[i])
167 */
168 status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
169 &logical_result);
170 if (ACPI_FAILURE (status)) {
171 return (FALSE);
172 }
173 logical_result = (u8)!logical_result;
174 break;
175
176 case MATCH_MGT:
177
178 /*
179 * True if greater than: (P[i] > M)
180 * Change to: (M < P[i])
181 */
182 status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
183 &logical_result);
184 if (ACPI_FAILURE (status)) {
185 return (FALSE);
186 }
187 break;
188
189 default:
190
191 /* Undefined */
192
193 return (FALSE);
194 }
195
196 return logical_result;
197}
198
199
200/*******************************************************************************
201 *
202 * FUNCTION: acpi_ex_opcode_6A_0T_1R
203 *
204 * PARAMETERS: walk_state - Current walk state
205 *
206 * RETURN: Status
207 *
208 * DESCRIPTION: Execute opcode with 6 arguments, no target, and a return value
209 *
210 ******************************************************************************/
211
212acpi_status
213acpi_ex_opcode_6A_0T_1R (
214 struct acpi_walk_state *walk_state)
215{
216 union acpi_operand_object **operand = &walk_state->operands[0];
217 union acpi_operand_object *return_desc = NULL;
218 acpi_status status = AE_OK;
219 u32 index;
220 union acpi_operand_object *this_element;
221
222
223 ACPI_FUNCTION_TRACE_STR ("ex_opcode_6A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
224
225
226 switch (walk_state->opcode) {
227 case AML_MATCH_OP:
228 /*
229 * Match (search_pkg[0], match_op1[1], match_obj1[2],
230 * match_op2[3], match_obj2[4], start_index[5])
231 */
232
233 /* Validate both Match Term Operators (MTR, MEQ, etc.) */
234
235 if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
236 (operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
237 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Match operator out of range\n"));
238 status = AE_AML_OPERAND_VALUE;
239 goto cleanup;
240 }
241
242 /* Get the package start_index, validate against the package length */
243
244 index = (u32) operand[5]->integer.value;
245 if (index >= (u32) operand[0]->package.count) {
246 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index beyond package end\n"));
247 status = AE_AML_PACKAGE_LIMIT;
248 goto cleanup;
249 }
250
251 /* Create an integer for the return value */
252
253 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
254 if (!return_desc) {
255 status = AE_NO_MEMORY;
256 goto cleanup;
257
258 }
259
260 /* Default return value if no match found */
261
262 return_desc->integer.value = ACPI_INTEGER_MAX;
263
264 /*
265 * Examine each element until a match is found. Both match conditions
266 * must be satisfied for a match to occur. Within the loop,
267 * "continue" signifies that the current element does not match
268 * and the next should be examined.
269 *
270 * Upon finding a match, the loop will terminate via "break" at
271 * the bottom. If it terminates "normally", match_value will be
272 * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no
273 * match was found.
274 */
275 for ( ; index < operand[0]->package.count; index++) {
276 /* Get the current package element */
277
278 this_element = operand[0]->package.elements[index];
279
280 /* Treat any uninitialized (NULL) elements as non-matching */
281
282 if (!this_element) {
283 continue;
284 }
285
286 /*
287 * Both match conditions must be satisfied. Execution of a continue
288 * (proceed to next iteration of enclosing for loop) signifies a
289 * non-match.
290 */
291 if (!acpi_ex_do_match ((u32) operand[1]->integer.value,
292 this_element, operand[2])) {
293 continue;
294 }
295
296 if (!acpi_ex_do_match ((u32) operand[3]->integer.value,
297 this_element, operand[4])) {
298 continue;
299 }
300
301 /* Match found: Index is the return value */
302
303 return_desc->integer.value = index;
304 break;
305 }
306 break;
307
308
309 case AML_LOAD_TABLE_OP:
310
311 status = acpi_ex_load_table_op (walk_state, &return_desc);
312 break;
313
314
315 default:
316
317 ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
318 walk_state->opcode));
319 status = AE_AML_BAD_OPCODE;
320 goto cleanup;
321 }
322
323
324 walk_state->result_obj = return_desc;
325
326
327cleanup:
328
329 /* Delete return object on error */
330
331 if (ACPI_FAILURE (status)) {
332 acpi_ut_remove_reference (return_desc);
333 }
334
335 return_ACPI_STATUS (status);
336}
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
new file mode 100644
index 000000000000..264ef3bba31b
--- /dev/null
+++ b/drivers/acpi/executer/exprep.c
@@ -0,0 +1,530 @@
1
2/******************************************************************************
3 *
4 * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acinterp.h>
48#include <acpi/amlcode.h>
49#include <acpi/acnamesp.h>
50
51
52#define _COMPONENT ACPI_EXECUTER
53 ACPI_MODULE_NAME ("exprep")
54
55
56#ifdef ACPI_UNDER_DEVELOPMENT
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ex_generate_access
60 *
61 * PARAMETERS: field_bit_offset - Start of field within parent region/buffer
62 * field_bit_length - Length of field in bits
63 * region_length - Length of parent in bytes
64 *
65 * RETURN: Field granularity (8, 16, 32 or 64) and
66 * byte_alignment (1, 2, 3, or 4)
67 *
68 * DESCRIPTION: Generate an optimal access width for fields defined with the
69 * any_acc keyword.
70 *
71 * NOTE: Need to have the region_length in order to check for boundary
72 * conditions (end-of-region). However, the region_length is a deferred
73 * operation. Therefore, to complete this implementation, the generation
74 * of this access width must be deferred until the region length has
75 * been evaluated.
76 *
77 ******************************************************************************/
78
79static u32
80acpi_ex_generate_access (
81 u32 field_bit_offset,
82 u32 field_bit_length,
83 u32 region_length)
84{
85 u32 field_byte_length;
86 u32 field_byte_offset;
87 u32 field_byte_end_offset;
88 u32 access_byte_width;
89 u32 field_start_offset;
90 u32 field_end_offset;
91 u32 minimum_access_width = 0xFFFFFFFF;
92 u32 minimum_accesses = 0xFFFFFFFF;
93 u32 accesses;
94
95
96 ACPI_FUNCTION_TRACE ("ex_generate_access");
97
98
99 /* Round Field start offset and length to "minimal" byte boundaries */
100
101 field_byte_offset = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8));
102 field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + field_bit_offset, 8));
103 field_byte_length = field_byte_end_offset - field_byte_offset;
104
105 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
106 "Bit length %d, Bit offset %d\n",
107 field_bit_length, field_bit_offset));
108 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
109 "Byte Length %d, Byte Offset %d, End Offset %d\n",
110 field_byte_length, field_byte_offset, field_byte_end_offset));
111
112 /*
113 * Iterative search for the maximum access width that is both aligned
114 * and does not go beyond the end of the region
115 *
116 * Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes)
117 */
118 for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) {
119 /*
120 * 1) Round end offset up to next access boundary and make sure that this
121 * does not go beyond the end of the parent region.
122 * 2) When the Access width is greater than the field_byte_length, we are done.
123 * (This does not optimize for the perfectly aligned case yet).
124 */
125 if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) {
126 field_start_offset = ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) /
127 access_byte_width;
128 field_end_offset = ACPI_ROUND_UP ((field_byte_length + field_byte_offset),
129 access_byte_width) / access_byte_width;
130 accesses = field_end_offset - field_start_offset;
131
132 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
133 "access_width %d end is within region\n", access_byte_width));
134 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
135 "Field Start %d, Field End %d -- requires %d accesses\n",
136 field_start_offset, field_end_offset, accesses));
137
138 /* Single access is optimal */
139
140 if (accesses <= 1) {
141 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
142 "Entire field can be accessed with one operation of size %d\n",
143 access_byte_width));
144 return_VALUE (access_byte_width);
145 }
146
147 /*
148 * Fits in the region, but requires more than one read/write.
149 * try the next wider access on next iteration
150 */
151 if (accesses < minimum_accesses) {
152 minimum_accesses = accesses;
153 minimum_access_width = access_byte_width;
154 }
155 }
156 else {
157 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
158 "access_width %d end is NOT within region\n", access_byte_width));
159 if (access_byte_width == 1) {
160 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
161 "Field goes beyond end-of-region!\n"));
162 return_VALUE (0); /* Field does not fit in the region at all */
163 }
164
165 /* This width goes beyond the end-of-region, back off to previous access */
166
167 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
168 "Backing off to previous optimal access width of %d\n",
169 minimum_access_width));
170 return_VALUE (minimum_access_width);
171 }
172 }
173
174 /* Could not read/write field with one operation, just use max access width */
175
176 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
177 "Cannot access field in one operation, using width 8\n"));
178 return_VALUE (8);
179}
180#endif /* ACPI_UNDER_DEVELOPMENT */
181
182
183/*******************************************************************************
184 *
185 * FUNCTION: acpi_ex_decode_field_access
186 *
187 * PARAMETERS: Access - Encoded field access bits
188 * Length - Field length.
189 *
190 * RETURN: Field granularity (8, 16, 32 or 64) and
191 * byte_alignment (1, 2, 3, or 4)
192 *
193 * DESCRIPTION: Decode the access_type bits of a field definition.
194 *
195 ******************************************************************************/
196
197static u32
198acpi_ex_decode_field_access (
199 union acpi_operand_object *obj_desc,
200 u8 field_flags,
201 u32 *return_byte_alignment)
202{
203 u32 access;
204 u32 byte_alignment;
205 u32 bit_length;
206
207
208 ACPI_FUNCTION_TRACE ("ex_decode_field_access");
209
210
211 access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK);
212
213 switch (access) {
214 case AML_FIELD_ACCESS_ANY:
215
216#ifdef ACPI_UNDER_DEVELOPMENT
217 byte_alignment = acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset,
218 obj_desc->common_field.bit_length,
219 0xFFFFFFFF /* Temp until we pass region_length as param */);
220 bit_length = byte_alignment * 8;
221#endif
222
223 byte_alignment = 1;
224 bit_length = 8;
225 break;
226
227 case AML_FIELD_ACCESS_BYTE:
228 case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */
229 byte_alignment = 1;
230 bit_length = 8;
231 break;
232
233 case AML_FIELD_ACCESS_WORD:
234 byte_alignment = 2;
235 bit_length = 16;
236 break;
237
238 case AML_FIELD_ACCESS_DWORD:
239 byte_alignment = 4;
240 bit_length = 32;
241 break;
242
243 case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */
244 byte_alignment = 8;
245 bit_length = 64;
246 break;
247
248 default:
249 /* Invalid field access type */
250
251 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
252 "Unknown field access type %X\n",
253 access));
254 return_VALUE (0);
255 }
256
257 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
258 /*
259 * buffer_field access can be on any byte boundary, so the
260 * byte_alignment is always 1 byte -- regardless of any byte_alignment
261 * implied by the field access type.
262 */
263 byte_alignment = 1;
264 }
265
266 *return_byte_alignment = byte_alignment;
267 return_VALUE (bit_length);
268}
269
270
271/*******************************************************************************
272 *
273 * FUNCTION: acpi_ex_prep_common_field_object
274 *
275 * PARAMETERS: obj_desc - The field object
276 * field_flags - Access, lock_rule, and update_rule.
277 * The format of a field_flag is described
278 * in the ACPI specification
279 * field_bit_position - Field start position
280 * field_bit_length - Field length in number of bits
281 *
282 * RETURN: Status
283 *
284 * DESCRIPTION: Initialize the areas of the field object that are common
285 * to the various types of fields. Note: This is very "sensitive"
286 * code because we are solving the general case for field
287 * alignment.
288 *
289 ******************************************************************************/
290
291acpi_status
292acpi_ex_prep_common_field_object (
293 union acpi_operand_object *obj_desc,
294 u8 field_flags,
295 u8 field_attribute,
296 u32 field_bit_position,
297 u32 field_bit_length)
298{
299 u32 access_bit_width;
300 u32 byte_alignment;
301 u32 nearest_byte_address;
302
303
304 ACPI_FUNCTION_TRACE ("ex_prep_common_field_object");
305
306
307 /*
308 * Note: the structure being initialized is the
309 * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common
310 * area are initialized by this procedure.
311 */
312 obj_desc->common_field.field_flags = field_flags;
313 obj_desc->common_field.attribute = field_attribute;
314 obj_desc->common_field.bit_length = field_bit_length;
315
316 /*
317 * Decode the access type so we can compute offsets. The access type gives
318 * two pieces of information - the width of each field access and the
319 * necessary byte_alignment (address granularity) of the access.
320 *
321 * For any_acc, the access_bit_width is the largest width that is both
322 * necessary and possible in an attempt to access the whole field in one
323 * I/O operation. However, for any_acc, the byte_alignment is always one
324 * byte.
325 *
326 * For all Buffer Fields, the byte_alignment is always one byte.
327 *
328 * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
329 * the same (equivalent) as the byte_alignment.
330 */
331 access_bit_width = acpi_ex_decode_field_access (obj_desc, field_flags,
332 &byte_alignment);
333 if (!access_bit_width) {
334 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
335 }
336
337 /* Setup width (access granularity) fields */
338
339 obj_desc->common_field.access_byte_width = (u8)
340 ACPI_DIV_8 (access_bit_width); /* 1, 2, 4, 8 */
341
342 obj_desc->common_field.access_bit_width = (u8) access_bit_width;
343
344 /*
345 * base_byte_offset is the address of the start of the field within the
346 * region. It is the byte address of the first *datum* (field-width data
347 * unit) of the field. (i.e., the first datum that contains at least the
348 * first *bit* of the field.)
349 *
350 * Note: byte_alignment is always either equal to the access_bit_width or 8
351 * (Byte access), and it defines the addressing granularity of the parent
352 * region or buffer.
353 */
354 nearest_byte_address =
355 ACPI_ROUND_BITS_DOWN_TO_BYTES (field_bit_position);
356 obj_desc->common_field.base_byte_offset = (u32)
357 ACPI_ROUND_DOWN (nearest_byte_address, byte_alignment);
358
359 /*
360 * start_field_bit_offset is the offset of the first bit of the field within
361 * a field datum.
362 */
363 obj_desc->common_field.start_field_bit_offset = (u8)
364 (field_bit_position - ACPI_MUL_8 (obj_desc->common_field.base_byte_offset));
365
366 /*
367 * Does the entire field fit within a single field access element? (datum)
368 * (i.e., without crossing a datum boundary)
369 */
370 if ((obj_desc->common_field.start_field_bit_offset + field_bit_length) <=
371 (u16) access_bit_width) {
372 obj_desc->common.flags |= AOPOBJ_SINGLE_DATUM;
373 }
374
375 return_ACPI_STATUS (AE_OK);
376}
377
378
379/*******************************************************************************
380 *
381 * FUNCTION: acpi_ex_prep_field_value
382 *
383 * PARAMETERS: Node - Owning Node
384 * region_node - Region in which field is being defined
385 * field_flags - Access, lock_rule, and update_rule.
386 * field_bit_position - Field start position
387 * field_bit_length - Field length in number of bits
388 *
389 * RETURN: Status
390 *
391 * DESCRIPTION: Construct an union acpi_operand_object of type def_field and
392 * connect it to the parent Node.
393 *
394 ******************************************************************************/
395
396acpi_status
397acpi_ex_prep_field_value (
398 struct acpi_create_field_info *info)
399{
400 union acpi_operand_object *obj_desc;
401 u32 type;
402 acpi_status status;
403
404
405 ACPI_FUNCTION_TRACE ("ex_prep_field_value");
406
407
408 /* Parameter validation */
409
410 if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) {
411 if (!info->region_node) {
412 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null region_node\n"));
413 return_ACPI_STATUS (AE_AML_NO_OPERAND);
414 }
415
416 type = acpi_ns_get_type (info->region_node);
417 if (type != ACPI_TYPE_REGION) {
418 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
419 "Needed Region, found type %X (%s)\n",
420 type, acpi_ut_get_type_name (type)));
421
422 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
423 }
424 }
425
426 /* Allocate a new field object */
427
428 obj_desc = acpi_ut_create_internal_object (info->field_type);
429 if (!obj_desc) {
430 return_ACPI_STATUS (AE_NO_MEMORY);
431 }
432
433 /* Initialize areas of the object that are common to all fields */
434
435 obj_desc->common_field.node = info->field_node;
436 status = acpi_ex_prep_common_field_object (obj_desc, info->field_flags,
437 info->attribute, info->field_bit_position, info->field_bit_length);
438 if (ACPI_FAILURE (status)) {
439 acpi_ut_delete_object_desc (obj_desc);
440 return_ACPI_STATUS (status);
441 }
442
443 /* Initialize areas of the object that are specific to the field type */
444
445 switch (info->field_type) {
446 case ACPI_TYPE_LOCAL_REGION_FIELD:
447
448 obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node);
449
450 /* An additional reference for the container */
451
452 acpi_ut_add_reference (obj_desc->field.region_obj);
453
454 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
455 "region_field: bit_off %X, Off %X, Gran %X, Region %p\n",
456 obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset,
457 obj_desc->field.access_byte_width, obj_desc->field.region_obj));
458 break;
459
460
461 case ACPI_TYPE_LOCAL_BANK_FIELD:
462
463 obj_desc->bank_field.value = info->bank_value;
464 obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (info->region_node);
465 obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object (info->register_node);
466
467 /* An additional reference for the attached objects */
468
469 acpi_ut_add_reference (obj_desc->bank_field.region_obj);
470 acpi_ut_add_reference (obj_desc->bank_field.bank_obj);
471
472 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
473 "Bank Field: bit_off %X, Off %X, Gran %X, Region %p, bank_reg %p\n",
474 obj_desc->bank_field.start_field_bit_offset,
475 obj_desc->bank_field.base_byte_offset,
476 obj_desc->field.access_byte_width,
477 obj_desc->bank_field.region_obj,
478 obj_desc->bank_field.bank_obj));
479 break;
480
481
482 case ACPI_TYPE_LOCAL_INDEX_FIELD:
483
484 obj_desc->index_field.index_obj = acpi_ns_get_attached_object (info->register_node);
485 obj_desc->index_field.data_obj = acpi_ns_get_attached_object (info->data_register_node);
486 obj_desc->index_field.value = (u32)
487 (info->field_bit_position / ACPI_MUL_8 (obj_desc->field.access_byte_width));
488
489 if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) {
490 ACPI_REPORT_ERROR (("Null Index Object during field prep\n"));
491 acpi_ut_delete_object_desc (obj_desc);
492 return_ACPI_STATUS (AE_AML_INTERNAL);
493 }
494
495 /* An additional reference for the attached objects */
496
497 acpi_ut_add_reference (obj_desc->index_field.data_obj);
498 acpi_ut_add_reference (obj_desc->index_field.index_obj);
499
500 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
501 "index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
502 obj_desc->index_field.start_field_bit_offset,
503 obj_desc->index_field.base_byte_offset,
504 obj_desc->index_field.value,
505 obj_desc->field.access_byte_width,
506 obj_desc->index_field.index_obj,
507 obj_desc->index_field.data_obj));
508 break;
509
510 default:
511 /* No other types should get here */
512 break;
513 }
514
515 /*
516 * Store the constructed descriptor (obj_desc) into the parent Node,
517 * preserving the current type of that named_obj.
518 */
519 status = acpi_ns_attach_object (info->field_node, obj_desc,
520 acpi_ns_get_type (info->field_node));
521
522 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set named_obj %p [%4.4s], obj_desc %p\n",
523 info->field_node, acpi_ut_get_node_name (info->field_node), obj_desc));
524
525 /* Remove local reference to the object */
526
527 acpi_ut_remove_reference (obj_desc);
528 return_ACPI_STATUS (status);
529}
530
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
new file mode 100644
index 000000000000..7cfd0684c70b
--- /dev/null
+++ b/drivers/acpi/executer/exregion.c
@@ -0,0 +1,528 @@
1
2/******************************************************************************
3 *
4 * Module Name: exregion - ACPI default op_region (address space) handlers
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acinterp.h>
48
49
50#define _COMPONENT ACPI_EXECUTER
51 ACPI_MODULE_NAME ("exregion")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ex_system_memory_space_handler
57 *
58 * PARAMETERS: Function - Read or Write operation
59 * Address - Where in the space to read or write
60 * bit_width - Field width in bits (8, 16, or 32)
61 * Value - Pointer to in or out value
62 * handler_context - Pointer to Handler's context
63 * region_context - Pointer to context specific to the
64 * accessed region
65 *
66 * RETURN: Status
67 *
68 * DESCRIPTION: Handler for the System Memory address space (Op Region)
69 *
70 ******************************************************************************/
71
72acpi_status
73acpi_ex_system_memory_space_handler (
74 u32 function,
75 acpi_physical_address address,
76 u32 bit_width,
77 acpi_integer *value,
78 void *handler_context,
79 void *region_context)
80{
81 acpi_status status = AE_OK;
82 void *logical_addr_ptr = NULL;
83 struct acpi_mem_space_context *mem_info = region_context;
84 u32 length;
85 acpi_size window_size;
86#ifndef ACPI_MISALIGNED_TRANSFERS
87 u32 remainder;
88#endif
89
90 ACPI_FUNCTION_TRACE ("ex_system_memory_space_handler");
91
92
93 /* Validate and translate the bit width */
94
95 switch (bit_width) {
96 case 8:
97 length = 1;
98 break;
99
100 case 16:
101 length = 2;
102 break;
103
104 case 32:
105 length = 4;
106 break;
107
108 case 64:
109 length = 8;
110 break;
111
112 default:
113 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid system_memory width %d\n",
114 bit_width));
115 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
116 }
117
118
119#ifndef ACPI_MISALIGNED_TRANSFERS
120 /*
121 * Hardware does not support non-aligned data transfers, we must verify
122 * the request.
123 */
124 (void) acpi_ut_short_divide ((acpi_integer) address, length, NULL, &remainder);
125 if (remainder != 0) {
126 return_ACPI_STATUS (AE_AML_ALIGNMENT);
127 }
128#endif
129
130 /*
131 * Does the request fit into the cached memory mapping?
132 * Is 1) Address below the current mapping? OR
133 * 2) Address beyond the current mapping?
134 */
135 if ((address < mem_info->mapped_physical_address) ||
136 (((acpi_integer) address + length) >
137 ((acpi_integer) mem_info->mapped_physical_address + mem_info->mapped_length))) {
138 /*
139 * The request cannot be resolved by the current memory mapping;
140 * Delete the existing mapping and create a new one.
141 */
142 if (mem_info->mapped_length) {
143 /* Valid mapping, delete it */
144
145 acpi_os_unmap_memory (mem_info->mapped_logical_address,
146 mem_info->mapped_length);
147 }
148
149 /*
150 * Don't attempt to map memory beyond the end of the region, and
151 * constrain the maximum mapping size to something reasonable.
152 */
153 window_size = (acpi_size) ((mem_info->address + mem_info->length) - address);
154 if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
155 window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
156 }
157
158 /* Create a new mapping starting at the address given */
159
160 status = acpi_os_map_memory (address, window_size,
161 (void **) &mem_info->mapped_logical_address);
162 if (ACPI_FAILURE (status)) {
163 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n",
164 ACPI_FORMAT_UINT64 (address), (u32) window_size));
165 mem_info->mapped_length = 0;
166 return_ACPI_STATUS (status);
167 }
168
169 /* Save the physical address and mapping size */
170
171 mem_info->mapped_physical_address = address;
172 mem_info->mapped_length = window_size;
173 }
174
175 /*
176 * Generate a logical pointer corresponding to the address we want to
177 * access
178 */
179 logical_addr_ptr = mem_info->mapped_logical_address +
180 ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address);
181
182 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
183 "system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
184 ACPI_FORMAT_UINT64 (address)));
185
186 /*
187 * Perform the memory read or write
188 *
189 * Note: For machines that do not support non-aligned transfers, the target
190 * address was checked for alignment above. We do not attempt to break the
191 * transfer up into smaller (byte-size) chunks because the AML specifically
192 * asked for a transfer width that the hardware may require.
193 */
194 switch (function) {
195 case ACPI_READ:
196
197 *value = 0;
198 switch (bit_width) {
199 case 8:
200 *value = (acpi_integer) *((u8 *) logical_addr_ptr);
201 break;
202
203 case 16:
204 *value = (acpi_integer) *((u16 *) logical_addr_ptr);
205 break;
206
207 case 32:
208 *value = (acpi_integer) *((u32 *) logical_addr_ptr);
209 break;
210
211#if ACPI_MACHINE_WIDTH != 16
212 case 64:
213 *value = (acpi_integer) *((u64 *) logical_addr_ptr);
214 break;
215#endif
216 default:
217 /* bit_width was already validated */
218 break;
219 }
220 break;
221
222 case ACPI_WRITE:
223
224 switch (bit_width) {
225 case 8:
226 *(u8 *) logical_addr_ptr = (u8) *value;
227 break;
228
229 case 16:
230 *(u16 *) logical_addr_ptr = (u16) *value;
231 break;
232
233 case 32:
234 *(u32 *) logical_addr_ptr = (u32) *value;
235 break;
236
237#if ACPI_MACHINE_WIDTH != 16
238 case 64:
239 *(u64 *) logical_addr_ptr = (u64) *value;
240 break;
241#endif
242
243 default:
244 /* bit_width was already validated */
245 break;
246 }
247 break;
248
249 default:
250 status = AE_BAD_PARAMETER;
251 break;
252 }
253
254 return_ACPI_STATUS (status);
255}
256
257
258/*******************************************************************************
259 *
260 * FUNCTION: acpi_ex_system_io_space_handler
261 *
262 * PARAMETERS: Function - Read or Write operation
263 * Address - Where in the space to read or write
264 * bit_width - Field width in bits (8, 16, or 32)
265 * Value - Pointer to in or out value
266 * handler_context - Pointer to Handler's context
267 * region_context - Pointer to context specific to the
268 * accessed region
269 *
270 * RETURN: Status
271 *
272 * DESCRIPTION: Handler for the System IO address space (Op Region)
273 *
274 ******************************************************************************/
275
276acpi_status
277acpi_ex_system_io_space_handler (
278 u32 function,
279 acpi_physical_address address,
280 u32 bit_width,
281 acpi_integer *value,
282 void *handler_context,
283 void *region_context)
284{
285 acpi_status status = AE_OK;
286 u32 value32;
287
288
289 ACPI_FUNCTION_TRACE ("ex_system_io_space_handler");
290
291
292 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
293 "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
294 ACPI_FORMAT_UINT64 (address)));
295
296 /* Decode the function parameter */
297
298 switch (function) {
299 case ACPI_READ:
300
301 status = acpi_os_read_port ((acpi_io_address) address, &value32, bit_width);
302 *value = value32;
303 break;
304
305 case ACPI_WRITE:
306
307 status = acpi_os_write_port ((acpi_io_address) address, (u32) *value, bit_width);
308 break;
309
310 default:
311 status = AE_BAD_PARAMETER;
312 break;
313 }
314
315 return_ACPI_STATUS (status);
316}
317
318
319/*******************************************************************************
320 *
321 * FUNCTION: acpi_ex_pci_config_space_handler
322 *
323 * PARAMETERS: Function - Read or Write operation
324 * Address - Where in the space to read or write
325 * bit_width - Field width in bits (8, 16, or 32)
326 * Value - Pointer to in or out value
327 * handler_context - Pointer to Handler's context
328 * region_context - Pointer to context specific to the
329 * accessed region
330 *
331 * RETURN: Status
332 *
333 * DESCRIPTION: Handler for the PCI Config address space (Op Region)
334 *
335 ******************************************************************************/
336
337acpi_status
338acpi_ex_pci_config_space_handler (
339 u32 function,
340 acpi_physical_address address,
341 u32 bit_width,
342 acpi_integer *value,
343 void *handler_context,
344 void *region_context)
345{
346 acpi_status status = AE_OK;
347 struct acpi_pci_id *pci_id;
348 u16 pci_register;
349
350
351 ACPI_FUNCTION_TRACE ("ex_pci_config_space_handler");
352
353
354 /*
355 * The arguments to acpi_os(Read|Write)pci_configuration are:
356 *
357 * pci_segment is the PCI bus segment range 0-31
358 * pci_bus is the PCI bus number range 0-255
359 * pci_device is the PCI device number range 0-31
360 * pci_function is the PCI device function number
361 * pci_register is the Config space register range 0-255 bytes
362 *
363 * Value - input value for write, output address for read
364 *
365 */
366 pci_id = (struct acpi_pci_id *) region_context;
367 pci_register = (u16) (u32) address;
368
369 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
370 "pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
371 function, bit_width, pci_id->segment, pci_id->bus, pci_id->device,
372 pci_id->function, pci_register));
373
374 switch (function) {
375 case ACPI_READ:
376
377 *value = 0;
378 status = acpi_os_read_pci_configuration (pci_id, pci_register, value, bit_width);
379 break;
380
381 case ACPI_WRITE:
382
383 status = acpi_os_write_pci_configuration (pci_id, pci_register, *value, bit_width);
384 break;
385
386 default:
387
388 status = AE_BAD_PARAMETER;
389 break;
390 }
391
392 return_ACPI_STATUS (status);
393}
394
395
396/*******************************************************************************
397 *
398 * FUNCTION: acpi_ex_cmos_space_handler
399 *
400 * PARAMETERS: Function - Read or Write operation
401 * Address - Where in the space to read or write
402 * bit_width - Field width in bits (8, 16, or 32)
403 * Value - Pointer to in or out value
404 * handler_context - Pointer to Handler's context
405 * region_context - Pointer to context specific to the
406 * accessed region
407 *
408 * RETURN: Status
409 *
410 * DESCRIPTION: Handler for the CMOS address space (Op Region)
411 *
412 ******************************************************************************/
413
414acpi_status
415acpi_ex_cmos_space_handler (
416 u32 function,
417 acpi_physical_address address,
418 u32 bit_width,
419 acpi_integer *value,
420 void *handler_context,
421 void *region_context)
422{
423 acpi_status status = AE_OK;
424
425
426 ACPI_FUNCTION_TRACE ("ex_cmos_space_handler");
427
428
429 return_ACPI_STATUS (status);
430}
431
432
433/*******************************************************************************
434 *
435 * FUNCTION: acpi_ex_pci_bar_space_handler
436 *
437 * PARAMETERS: Function - Read or Write operation
438 * Address - Where in the space to read or write
439 * bit_width - Field width in bits (8, 16, or 32)
440 * Value - Pointer to in or out value
441 * handler_context - Pointer to Handler's context
442 * region_context - Pointer to context specific to the
443 * accessed region
444 *
445 * RETURN: Status
446 *
447 * DESCRIPTION: Handler for the PCI bar_target address space (Op Region)
448 *
449 ******************************************************************************/
450
451acpi_status
452acpi_ex_pci_bar_space_handler (
453 u32 function,
454 acpi_physical_address address,
455 u32 bit_width,
456 acpi_integer *value,
457 void *handler_context,
458 void *region_context)
459{
460 acpi_status status = AE_OK;
461
462
463 ACPI_FUNCTION_TRACE ("ex_pci_bar_space_handler");
464
465
466 return_ACPI_STATUS (status);
467}
468
469
470/*******************************************************************************
471 *
472 * FUNCTION: acpi_ex_data_table_space_handler
473 *
474 * PARAMETERS: Function - Read or Write operation
475 * Address - Where in the space to read or write
476 * bit_width - Field width in bits (8, 16, or 32)
477 * Value - Pointer to in or out value
478 * handler_context - Pointer to Handler's context
479 * region_context - Pointer to context specific to the
480 * accessed region
481 *
482 * RETURN: Status
483 *
484 * DESCRIPTION: Handler for the Data Table address space (Op Region)
485 *
486 ******************************************************************************/
487
488acpi_status
489acpi_ex_data_table_space_handler (
490 u32 function,
491 acpi_physical_address address,
492 u32 bit_width,
493 acpi_integer *value,
494 void *handler_context,
495 void *region_context)
496{
497 acpi_status status = AE_OK;
498 u32 byte_width = ACPI_DIV_8 (bit_width);
499 u32 i;
500 char *logical_addr_ptr;
501
502
503 ACPI_FUNCTION_TRACE ("ex_data_table_space_handler");
504
505
506 logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address);
507
508
509 /* Perform the memory read or write */
510
511 switch (function) {
512 case ACPI_READ:
513
514 for (i = 0; i < byte_width; i++) {
515 ((char *) value) [i] = logical_addr_ptr[i];
516 }
517 break;
518
519 case ACPI_WRITE:
520 default:
521
522 return_ACPI_STATUS (AE_SUPPORT);
523 }
524
525 return_ACPI_STATUS (status);
526}
527
528
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
new file mode 100644
index 000000000000..7936329a0e35
--- /dev/null
+++ b/drivers/acpi/executer/exresnte.c
@@ -0,0 +1,289 @@
1
2/******************************************************************************
3 *
4 * Module Name: exresnte - AML Interpreter object resolution
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <acpi/acnamesp.h>
50#include <acpi/acparser.h>
51#include <acpi/amlcode.h>
52
53
54#define _COMPONENT ACPI_EXECUTER
55 ACPI_MODULE_NAME ("exresnte")
56
57
58/*******************************************************************************
59 *
60 * FUNCTION: acpi_ex_resolve_node_to_value
61 *
62 * PARAMETERS: object_ptr - Pointer to a location that contains
63 * a pointer to a NS node, and will receive a
64 * pointer to the resolved object.
65 * walk_state - Current state. Valid only if executing AML
66 * code. NULL if simply resolving an object
67 *
68 * RETURN: Status
69 *
70 * DESCRIPTION: Resolve a Namespace node to a valued object
71 *
72 * Note: for some of the data types, the pointer attached to the Node
73 * can be either a pointer to an actual internal object or a pointer into the
74 * AML stream itself. These types are currently:
75 *
76 * ACPI_TYPE_INTEGER
77 * ACPI_TYPE_STRING
78 * ACPI_TYPE_BUFFER
79 * ACPI_TYPE_MUTEX
80 * ACPI_TYPE_PACKAGE
81 *
82 ******************************************************************************/
83
84acpi_status
85acpi_ex_resolve_node_to_value (
86 struct acpi_namespace_node **object_ptr,
87 struct acpi_walk_state *walk_state)
88
89{
90 acpi_status status = AE_OK;
91 union acpi_operand_object *source_desc;
92 union acpi_operand_object *obj_desc = NULL;
93 struct acpi_namespace_node *node;
94 acpi_object_type entry_type;
95
96
97 ACPI_FUNCTION_TRACE ("ex_resolve_node_to_value");
98
99
100 /*
101 * The stack pointer points to a struct acpi_namespace_node (Node). Get the
102 * object that is attached to the Node.
103 */
104 node = *object_ptr;
105 source_desc = acpi_ns_get_attached_object (node);
106 entry_type = acpi_ns_get_type ((acpi_handle) node);
107
108 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p source_desc=%p [%s]\n",
109 node, source_desc, acpi_ut_get_type_name (entry_type)));
110
111 if ((entry_type == ACPI_TYPE_LOCAL_ALIAS) ||
112 (entry_type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
113 /* There is always exactly one level of indirection */
114
115 node = ACPI_CAST_PTR (struct acpi_namespace_node, node->object);
116 source_desc = acpi_ns_get_attached_object (node);
117 entry_type = acpi_ns_get_type ((acpi_handle) node);
118 *object_ptr = node;
119 }
120
121 /*
122 * Several object types require no further processing:
123 * 1) Devices rarely have an attached object, return the Node
124 * 2) Method locals and arguments have a pseudo-Node
125 */
126 if (entry_type == ACPI_TYPE_DEVICE ||
127 (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
128 return_ACPI_STATUS (AE_OK);
129 }
130
131 if (!source_desc) {
132 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object attached to node %p\n",
133 node));
134 return_ACPI_STATUS (AE_AML_NO_OPERAND);
135 }
136
137 /*
138 * Action is based on the type of the Node, which indicates the type
139 * of the attached object or pointer
140 */
141 switch (entry_type) {
142 case ACPI_TYPE_PACKAGE:
143
144 if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_PACKAGE) {
145 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Package, type %s\n",
146 acpi_ut_get_object_type_name (source_desc)));
147 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
148 }
149
150 status = acpi_ds_get_package_arguments (source_desc);
151 if (ACPI_SUCCESS (status)) {
152 /* Return an additional reference to the object */
153
154 obj_desc = source_desc;
155 acpi_ut_add_reference (obj_desc);
156 }
157 break;
158
159
160 case ACPI_TYPE_BUFFER:
161
162 if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
163 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Buffer, type %s\n",
164 acpi_ut_get_object_type_name (source_desc)));
165 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
166 }
167
168 status = acpi_ds_get_buffer_arguments (source_desc);
169 if (ACPI_SUCCESS (status)) {
170 /* Return an additional reference to the object */
171
172 obj_desc = source_desc;
173 acpi_ut_add_reference (obj_desc);
174 }
175 break;
176
177
178 case ACPI_TYPE_STRING:
179
180 if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) {
181 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a String, type %s\n",
182 acpi_ut_get_object_type_name (source_desc)));
183 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
184 }
185
186 /* Return an additional reference to the object */
187
188 obj_desc = source_desc;
189 acpi_ut_add_reference (obj_desc);
190 break;
191
192
193 case ACPI_TYPE_INTEGER:
194
195 if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) {
196 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Integer, type %s\n",
197 acpi_ut_get_object_type_name (source_desc)));
198 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
199 }
200
201 /* Return an additional reference to the object */
202
203 obj_desc = source_desc;
204 acpi_ut_add_reference (obj_desc);
205 break;
206
207
208 case ACPI_TYPE_BUFFER_FIELD:
209 case ACPI_TYPE_LOCAL_REGION_FIELD:
210 case ACPI_TYPE_LOCAL_BANK_FIELD:
211 case ACPI_TYPE_LOCAL_INDEX_FIELD:
212
213 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read Node=%p source_desc=%p Type=%X\n",
214 node, source_desc, entry_type));
215
216 status = acpi_ex_read_data_from_field (walk_state, source_desc, &obj_desc);
217 break;
218
219 /*
220 * For these objects, just return the object attached to the Node
221 */
222 case ACPI_TYPE_MUTEX:
223 case ACPI_TYPE_METHOD:
224 case ACPI_TYPE_POWER:
225 case ACPI_TYPE_PROCESSOR:
226 case ACPI_TYPE_THERMAL:
227 case ACPI_TYPE_EVENT:
228 case ACPI_TYPE_REGION:
229
230 /* Return an additional reference to the object */
231
232 obj_desc = source_desc;
233 acpi_ut_add_reference (obj_desc);
234 break;
235
236
237 /* TYPE_ANY is untyped, and thus there is no object associated with it */
238
239 case ACPI_TYPE_ANY:
240
241 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Untyped entry %p, no attached object!\n",
242 node));
243
244 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */
245
246
247 case ACPI_TYPE_LOCAL_REFERENCE:
248
249 switch (source_desc->reference.opcode) {
250 case AML_LOAD_OP:
251
252 /* This is a ddb_handle */
253 /* Return an additional reference to the object */
254
255 obj_desc = source_desc;
256 acpi_ut_add_reference (obj_desc);
257 break;
258
259 default:
260 /* No named references are allowed here */
261
262 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X (%s)\n",
263 source_desc->reference.opcode,
264 acpi_ps_get_opcode_name (source_desc->reference.opcode)));
265
266 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
267 }
268 break;
269
270
271 /* Default case is for unknown types */
272
273 default:
274
275 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Node %p - Unknown object type %X\n",
276 node, entry_type));
277
278 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
279
280 } /* switch (entry_type) */
281
282
283 /* Put the object descriptor on the stack */
284
285 *object_ptr = (void *) obj_desc;
286 return_ACPI_STATUS (status);
287}
288
289
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
new file mode 100644
index 000000000000..7be604911156
--- /dev/null
+++ b/drivers/acpi/executer/exresolv.c
@@ -0,0 +1,546 @@
1
2/******************************************************************************
3 *
4 * Module Name: exresolv - AML Interpreter object resolution
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/amlcode.h>
48#include <acpi/acdispat.h>
49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h>
51#include <acpi/acparser.h>
52
53
54#define _COMPONENT ACPI_EXECUTER
55 ACPI_MODULE_NAME ("exresolv")
56
57
58/*******************************************************************************
59 *
60 * FUNCTION: acpi_ex_resolve_to_value
61 *
62 * PARAMETERS: **stack_ptr - Points to entry on obj_stack, which can
63 * be either an (union acpi_operand_object *)
64 * or an acpi_handle.
65 * walk_state - Current method state
66 *
67 * RETURN: Status
68 *
69 * DESCRIPTION: Convert Reference objects to values
70 *
71 ******************************************************************************/
72
73acpi_status
74acpi_ex_resolve_to_value (
75 union acpi_operand_object **stack_ptr,
76 struct acpi_walk_state *walk_state)
77{
78 acpi_status status;
79
80
81 ACPI_FUNCTION_TRACE_PTR ("ex_resolve_to_value", stack_ptr);
82
83
84 if (!stack_ptr || !*stack_ptr) {
85 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n"));
86 return_ACPI_STATUS (AE_AML_NO_OPERAND);
87 }
88
89 /*
90 * The entity pointed to by the stack_ptr can be either
91 * 1) A valid union acpi_operand_object, or
92 * 2) A struct acpi_namespace_node (named_obj)
93 */
94 if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
95 status = acpi_ex_resolve_object_to_value (stack_ptr, walk_state);
96 if (ACPI_FAILURE (status)) {
97 return_ACPI_STATUS (status);
98 }
99 }
100
101 /*
102 * Object on the stack may have changed if acpi_ex_resolve_object_to_value()
103 * was called (i.e., we can't use an _else_ here.)
104 */
105 if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
106 status = acpi_ex_resolve_node_to_value (
107 ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, stack_ptr),
108 walk_state);
109 if (ACPI_FAILURE (status)) {
110 return_ACPI_STATUS (status);
111 }
112 }
113
114 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
115 return_ACPI_STATUS (AE_OK);
116}
117
118
119/*******************************************************************************
120 *
121 * FUNCTION: acpi_ex_resolve_object_to_value
122 *
123 * PARAMETERS: stack_ptr - Pointer to a stack location that contains a
124 * ptr to an internal object.
125 * walk_state - Current method state
126 *
127 * RETURN: Status
128 *
129 * DESCRIPTION: Retrieve the value from an internal object. The Reference type
130 * uses the associated AML opcode to determine the value.
131 *
132 ******************************************************************************/
133
134acpi_status
135acpi_ex_resolve_object_to_value (
136 union acpi_operand_object **stack_ptr,
137 struct acpi_walk_state *walk_state)
138{
139 acpi_status status = AE_OK;
140 union acpi_operand_object *stack_desc;
141 void *temp_node;
142 union acpi_operand_object *obj_desc;
143 u16 opcode;
144
145
146 ACPI_FUNCTION_TRACE ("ex_resolve_object_to_value");
147
148
149 stack_desc = *stack_ptr;
150
151 /* This is an union acpi_operand_object */
152
153 switch (ACPI_GET_OBJECT_TYPE (stack_desc)) {
154 case ACPI_TYPE_LOCAL_REFERENCE:
155
156 opcode = stack_desc->reference.opcode;
157
158 switch (opcode) {
159 case AML_NAME_OP:
160
161 /*
162 * Convert indirect name ptr to a direct name ptr.
163 * Then, acpi_ex_resolve_node_to_value can be used to get the value
164 */
165 temp_node = stack_desc->reference.object;
166
167 /* Delete the Reference Object */
168
169 acpi_ut_remove_reference (stack_desc);
170
171 /* Put direct name pointer onto stack and exit */
172
173 (*stack_ptr) = temp_node;
174 break;
175
176
177 case AML_LOCAL_OP:
178 case AML_ARG_OP:
179
180 /*
181 * Get the local from the method's state info
182 * Note: this increments the local's object reference count
183 */
184 status = acpi_ds_method_data_get_value (opcode,
185 stack_desc->reference.offset, walk_state, &obj_desc);
186 if (ACPI_FAILURE (status)) {
187 return_ACPI_STATUS (status);
188 }
189
190 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] value_obj is %p\n",
191 stack_desc->reference.offset, obj_desc));
192
193 /*
194 * Now we can delete the original Reference Object and
195 * replace it with the resolved value
196 */
197 acpi_ut_remove_reference (stack_desc);
198 *stack_ptr = obj_desc;
199 break;
200
201
202 case AML_INDEX_OP:
203
204 switch (stack_desc->reference.target_type) {
205 case ACPI_TYPE_BUFFER_FIELD:
206
207 /* Just return - leave the Reference on the stack */
208 break;
209
210
211 case ACPI_TYPE_PACKAGE:
212
213 obj_desc = *stack_desc->reference.where;
214 if (obj_desc) {
215 /*
216 * Valid obj descriptor, copy pointer to return value
217 * (i.e., dereference the package index)
218 * Delete the ref object, increment the returned object
219 */
220 acpi_ut_remove_reference (stack_desc);
221 acpi_ut_add_reference (obj_desc);
222 *stack_ptr = obj_desc;
223 }
224 else {
225 /*
226 * A NULL object descriptor means an unitialized element of
227 * the package, can't dereference it
228 */
229 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
230 "Attempt to deref an Index to NULL pkg element Idx=%p\n",
231 stack_desc));
232 status = AE_AML_UNINITIALIZED_ELEMENT;
233 }
234 break;
235
236
237 default:
238
239 /* Invalid reference object */
240
241 ACPI_REPORT_ERROR ((
242 "During resolve, Unknown target_type %X in Index/Reference obj %p\n",
243 stack_desc->reference.target_type, stack_desc));
244 status = AE_AML_INTERNAL;
245 break;
246 }
247 break;
248
249
250 case AML_REF_OF_OP:
251 case AML_DEBUG_OP:
252 case AML_LOAD_OP:
253
254 /* Just leave the object as-is */
255
256 break;
257
258
259 default:
260
261 ACPI_REPORT_ERROR (("During resolve, Unknown Reference opcode %X (%s) in %p\n",
262 opcode, acpi_ps_get_opcode_name (opcode), stack_desc));
263 status = AE_AML_INTERNAL;
264 break;
265 }
266 break;
267
268
269 case ACPI_TYPE_BUFFER:
270
271 status = acpi_ds_get_buffer_arguments (stack_desc);
272 break;
273
274
275 case ACPI_TYPE_PACKAGE:
276
277 status = acpi_ds_get_package_arguments (stack_desc);
278 break;
279
280
281 /*
282 * These cases may never happen here, but just in case..
283 */
284 case ACPI_TYPE_BUFFER_FIELD:
285 case ACPI_TYPE_LOCAL_REGION_FIELD:
286 case ACPI_TYPE_LOCAL_BANK_FIELD:
287 case ACPI_TYPE_LOCAL_INDEX_FIELD:
288
289 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read source_desc=%p Type=%X\n",
290 stack_desc, ACPI_GET_OBJECT_TYPE (stack_desc)));
291
292 status = acpi_ex_read_data_from_field (walk_state, stack_desc, &obj_desc);
293 *stack_ptr = (void *) obj_desc;
294 break;
295
296 default:
297 break;
298 }
299
300 return_ACPI_STATUS (status);
301}
302
303
304/*******************************************************************************
305 *
306 * FUNCTION: acpi_ex_resolve_multiple
307 *
308 * PARAMETERS: walk_state - Current state (contains AML opcode)
309 * Operand - Starting point for resolution
310 * return_type - Where the object type is returned
311 * return_desc - Where the resolved object is returned
312 *
313 * RETURN: Status
314 *
315 * DESCRIPTION: Return the base object and type. Traverse a reference list if
316 * necessary to get to the base object.
317 *
318 ******************************************************************************/
319
320acpi_status
321acpi_ex_resolve_multiple (
322 struct acpi_walk_state *walk_state,
323 union acpi_operand_object *operand,
324 acpi_object_type *return_type,
325 union acpi_operand_object **return_desc)
326{
327 union acpi_operand_object *obj_desc = (void *) operand;
328 struct acpi_namespace_node *node;
329 acpi_object_type type;
330 acpi_status status;
331
332
333 ACPI_FUNCTION_TRACE ("acpi_ex_resolve_multiple");
334
335
336 /*
337 * Operand can be either a namespace node or an operand descriptor
338 */
339 switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
340 case ACPI_DESC_TYPE_OPERAND:
341 type = obj_desc->common.type;
342 break;
343
344 case ACPI_DESC_TYPE_NAMED:
345 type = ((struct acpi_namespace_node *) obj_desc)->type;
346 obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) obj_desc);
347
348 /* If we had an Alias node, use the attached object for type info */
349
350 if (type == ACPI_TYPE_LOCAL_ALIAS) {
351 type = ((struct acpi_namespace_node *) obj_desc)->type;
352 obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) obj_desc);
353 }
354 break;
355
356 default:
357 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
358 }
359
360
361 /*
362 * If type is anything other than a reference, we are done
363 */
364 if (type != ACPI_TYPE_LOCAL_REFERENCE) {
365 goto exit;
366 }
367
368 /*
369 * For reference objects created via the ref_of or Index operators,
370 * we need to get to the base object (as per the ACPI specification
371 * of the object_type and size_of operators). This means traversing
372 * the list of possibly many nested references.
373 */
374 while (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
375 switch (obj_desc->reference.opcode) {
376 case AML_REF_OF_OP:
377
378 /* Dereference the reference pointer */
379
380 node = obj_desc->reference.object;
381
382 /* All "References" point to a NS node */
383
384 if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
385 ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
386 node, acpi_ut_get_descriptor_name (node)));
387 return_ACPI_STATUS (AE_AML_INTERNAL);
388 }
389
390 /* Get the attached object */
391
392 obj_desc = acpi_ns_get_attached_object (node);
393 if (!obj_desc) {
394 /* No object, use the NS node type */
395
396 type = acpi_ns_get_type (node);
397 goto exit;
398 }
399
400 /* Check for circular references */
401
402 if (obj_desc == operand) {
403 return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
404 }
405 break;
406
407
408 case AML_INDEX_OP:
409
410 /* Get the type of this reference (index into another object) */
411
412 type = obj_desc->reference.target_type;
413 if (type != ACPI_TYPE_PACKAGE) {
414 goto exit;
415 }
416
417 /*
418 * The main object is a package, we want to get the type
419 * of the individual package element that is referenced by
420 * the index.
421 *
422 * This could of course in turn be another reference object.
423 */
424 obj_desc = *(obj_desc->reference.where);
425 if (!obj_desc) {
426 /* NULL package elements are allowed */
427
428 type = 0; /* Uninitialized */
429 goto exit;
430 }
431 break;
432
433
434 case AML_INT_NAMEPATH_OP:
435
436 /* Dereference the reference pointer */
437
438 node = obj_desc->reference.node;
439
440 /* All "References" point to a NS node */
441
442 if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
443 ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
444 node, acpi_ut_get_descriptor_name (node)));
445 return_ACPI_STATUS (AE_AML_INTERNAL);
446 }
447
448 /* Get the attached object */
449
450 obj_desc = acpi_ns_get_attached_object (node);
451 if (!obj_desc) {
452 /* No object, use the NS node type */
453
454 type = acpi_ns_get_type (node);
455 goto exit;
456 }
457
458 /* Check for circular references */
459
460 if (obj_desc == operand) {
461 return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
462 }
463 break;
464
465
466 case AML_LOCAL_OP:
467 case AML_ARG_OP:
468
469 if (return_desc) {
470 status = acpi_ds_method_data_get_value (obj_desc->reference.opcode,
471 obj_desc->reference.offset, walk_state, &obj_desc);
472 if (ACPI_FAILURE (status)) {
473 return_ACPI_STATUS (status);
474 }
475 acpi_ut_remove_reference (obj_desc);
476 }
477 else {
478 status = acpi_ds_method_data_get_node (obj_desc->reference.opcode,
479 obj_desc->reference.offset, walk_state, &node);
480 if (ACPI_FAILURE (status)) {
481 return_ACPI_STATUS (status);
482 }
483
484 obj_desc = acpi_ns_get_attached_object (node);
485 if (!obj_desc) {
486 type = ACPI_TYPE_ANY;
487 goto exit;
488 }
489 }
490 break;
491
492
493 case AML_DEBUG_OP:
494
495 /* The Debug Object is of type "debug_object" */
496
497 type = ACPI_TYPE_DEBUG_OBJECT;
498 goto exit;
499
500
501 default:
502
503 ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n",
504 obj_desc->reference.opcode));
505 return_ACPI_STATUS (AE_AML_INTERNAL);
506 }
507 }
508
509 /*
510 * Now we are guaranteed to have an object that has not been created
511 * via the ref_of or Index operators.
512 */
513 type = ACPI_GET_OBJECT_TYPE (obj_desc);
514
515
516exit:
517 /* Convert internal types to external types */
518
519 switch (type) {
520 case ACPI_TYPE_LOCAL_REGION_FIELD:
521 case ACPI_TYPE_LOCAL_BANK_FIELD:
522 case ACPI_TYPE_LOCAL_INDEX_FIELD:
523
524 type = ACPI_TYPE_FIELD_UNIT;
525 break;
526
527 case ACPI_TYPE_LOCAL_SCOPE:
528
529 /* Per ACPI Specification, Scope is untyped */
530
531 type = ACPI_TYPE_ANY;
532 break;
533
534 default:
535 /* No change to Type required */
536 break;
537 }
538
539 *return_type = type;
540 if (return_desc) {
541 *return_desc = obj_desc;
542 }
543 return_ACPI_STATUS (AE_OK);
544}
545
546
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
new file mode 100644
index 000000000000..c92890220c32
--- /dev/null
+++ b/drivers/acpi/executer/exresop.c
@@ -0,0 +1,661 @@
1
2/******************************************************************************
3 *
4 * Module Name: exresop - AML Interpreter operand/object resolution
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/amlcode.h>
48#include <acpi/acparser.h>
49#include <acpi/acinterp.h>
50
51
52#define _COMPONENT ACPI_EXECUTER
53 ACPI_MODULE_NAME ("exresop")
54
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ex_check_object_type
59 *
60 * PARAMETERS: type_needed Object type needed
61 * this_type Actual object type
62 * Object Object pointer
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Check required type against actual type
67 *
68 ******************************************************************************/
69
70acpi_status
71acpi_ex_check_object_type (
72 acpi_object_type type_needed,
73 acpi_object_type this_type,
74 void *object)
75{
76 ACPI_FUNCTION_NAME ("ex_check_object_type");
77
78
79 if (type_needed == ACPI_TYPE_ANY) {
80 /* All types OK, so we don't perform any typechecks */
81
82 return (AE_OK);
83 }
84
85 if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) {
86 /*
87 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
88 * objects and thus allow them to be targets. (As per the ACPI
89 * specification, a store to a constant is a noop.)
90 */
91 if ((this_type == ACPI_TYPE_INTEGER) &&
92 (((union acpi_operand_object *) object)->common.flags & AOPOBJ_AML_CONSTANT)) {
93 return (AE_OK);
94 }
95 }
96
97 if (type_needed != this_type) {
98 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
99 "Needed [%s], found [%s] %p\n",
100 acpi_ut_get_type_name (type_needed),
101 acpi_ut_get_type_name (this_type), object));
102
103 return (AE_AML_OPERAND_TYPE);
104 }
105
106 return (AE_OK);
107}
108
109
110/*******************************************************************************
111 *
112 * FUNCTION: acpi_ex_resolve_operands
113 *
114 * PARAMETERS: Opcode - Opcode being interpreted
115 * stack_ptr - Pointer to the operand stack to be
116 * resolved
117 * walk_state - Current state
118 *
119 * RETURN: Status
120 *
121 * DESCRIPTION: Convert multiple input operands to the types required by the
122 * target operator.
123 *
124 * Each 5-bit group in arg_types represents one required
125 * operand and indicates the required Type. The corresponding operand
126 * will be converted to the required type if possible, otherwise we
127 * abort with an exception.
128 *
129 ******************************************************************************/
130
131acpi_status
132acpi_ex_resolve_operands (
133 u16 opcode,
134 union acpi_operand_object **stack_ptr,
135 struct acpi_walk_state *walk_state)
136{
137 union acpi_operand_object *obj_desc;
138 acpi_status status = AE_OK;
139 u8 object_type;
140 void *temp_node;
141 u32 arg_types;
142 const struct acpi_opcode_info *op_info;
143 u32 this_arg_type;
144 acpi_object_type type_needed;
145
146
147 ACPI_FUNCTION_TRACE_U32 ("ex_resolve_operands", opcode);
148
149
150 op_info = acpi_ps_get_opcode_info (opcode);
151 if (op_info->class == AML_CLASS_UNKNOWN) {
152 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
153 }
154
155 arg_types = op_info->runtime_args;
156 if (arg_types == ARGI_INVALID_OPCODE) {
157 ACPI_REPORT_ERROR (("resolve_operands: %X is not a valid AML opcode\n",
158 opcode));
159
160 return_ACPI_STATUS (AE_AML_INTERNAL);
161 }
162
163 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X [%s] required_operand_types=%8.8X \n",
164 opcode, op_info->name, arg_types));
165
166 /*
167 * Normal exit is with (arg_types == 0) at end of argument list.
168 * Function will return an exception from within the loop upon
169 * finding an entry which is not (or cannot be converted
170 * to) the required type; if stack underflows; or upon
171 * finding a NULL stack entry (which should not happen).
172 */
173 while (GET_CURRENT_ARG_TYPE (arg_types)) {
174 if (!stack_ptr || !*stack_ptr) {
175 ACPI_REPORT_ERROR (("resolve_operands: Null stack entry at %p\n",
176 stack_ptr));
177
178 return_ACPI_STATUS (AE_AML_INTERNAL);
179 }
180
181 /* Extract useful items */
182
183 obj_desc = *stack_ptr;
184
185 /* Decode the descriptor type */
186
187 switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
188 case ACPI_DESC_TYPE_NAMED:
189
190 /* Node */
191
192 object_type = ((struct acpi_namespace_node *) obj_desc)->type;
193 break;
194
195
196 case ACPI_DESC_TYPE_OPERAND:
197
198 /* ACPI internal object */
199
200 object_type = ACPI_GET_OBJECT_TYPE (obj_desc);
201
202 /* Check for bad acpi_object_type */
203
204 if (!acpi_ut_valid_object_type (object_type)) {
205 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad operand object type [%X]\n",
206 object_type));
207
208 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
209 }
210
211 if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
212 /*
213 * Decode the Reference
214 */
215 op_info = acpi_ps_get_opcode_info (opcode);
216 if (op_info->class == AML_CLASS_UNKNOWN) {
217 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
218 }
219
220 switch (obj_desc->reference.opcode) {
221 case AML_DEBUG_OP:
222 case AML_NAME_OP:
223 case AML_INDEX_OP:
224 case AML_REF_OF_OP:
225 case AML_ARG_OP:
226 case AML_LOCAL_OP:
227 case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
228
229 ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
230 "Operand is a Reference, ref_opcode [%s]\n",
231 (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name)));
232 break;
233
234 default:
235 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
236 "Operand is a Reference, Unknown Reference Opcode %X [%s]\n",
237 obj_desc->reference.opcode,
238 (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name));
239
240 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
241 }
242 }
243 break;
244
245
246 default:
247
248 /* Invalid descriptor */
249
250 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
251 "Invalid descriptor %p [%s]\n",
252 obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
253
254 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
255 }
256
257
258 /*
259 * Get one argument type, point to the next
260 */
261 this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
262 INCREMENT_ARG_LIST (arg_types);
263
264 /*
265 * Handle cases where the object does not need to be
266 * resolved to a value
267 */
268 switch (this_arg_type) {
269 case ARGI_REF_OR_STRING: /* Can be a String or Reference */
270
271 if ((ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_OPERAND) &&
272 (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_STRING)) {
273 /*
274 * String found - the string references a named object and must be
275 * resolved to a node
276 */
277 goto next_operand;
278 }
279
280 /* Else not a string - fall through to the normal Reference case below */
281 /*lint -fallthrough */
282
283 case ARGI_REFERENCE: /* References: */
284 case ARGI_INTEGER_REF:
285 case ARGI_OBJECT_REF:
286 case ARGI_DEVICE_REF:
287 case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
288 case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
289 case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */
290
291 /* Need an operand of type ACPI_TYPE_LOCAL_REFERENCE */
292
293 if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) /* Node (name) ptr OK as-is */ {
294 goto next_operand;
295 }
296
297 status = acpi_ex_check_object_type (ACPI_TYPE_LOCAL_REFERENCE,
298 object_type, obj_desc);
299 if (ACPI_FAILURE (status)) {
300 return_ACPI_STATUS (status);
301 }
302
303 if (AML_NAME_OP == obj_desc->reference.opcode) {
304 /*
305 * Convert an indirect name ptr to direct name ptr and put
306 * it on the stack
307 */
308 temp_node = obj_desc->reference.object;
309 acpi_ut_remove_reference (obj_desc);
310 (*stack_ptr) = temp_node;
311 }
312 goto next_operand;
313
314
315 case ARGI_DATAREFOBJ: /* Store operator only */
316
317 /*
318 * We don't want to resolve index_op reference objects during
319 * a store because this would be an implicit de_ref_of operation.
320 * Instead, we just want to store the reference object.
321 * -- All others must be resolved below.
322 */
323 if ((opcode == AML_STORE_OP) &&
324 (ACPI_GET_OBJECT_TYPE (*stack_ptr) == ACPI_TYPE_LOCAL_REFERENCE) &&
325 ((*stack_ptr)->reference.opcode == AML_INDEX_OP)) {
326 goto next_operand;
327 }
328 break;
329
330 default:
331 /* All cases covered above */
332 break;
333 }
334
335
336 /*
337 * Resolve this object to a value
338 */
339 status = acpi_ex_resolve_to_value (stack_ptr, walk_state);
340 if (ACPI_FAILURE (status)) {
341 return_ACPI_STATUS (status);
342 }
343
344 /* Get the resolved object */
345
346 obj_desc = *stack_ptr;
347
348 /*
349 * Check the resulting object (value) type
350 */
351 switch (this_arg_type) {
352 /*
353 * For the simple cases, only one type of resolved object
354 * is allowed
355 */
356 case ARGI_MUTEX:
357
358 /* Need an operand of type ACPI_TYPE_MUTEX */
359
360 type_needed = ACPI_TYPE_MUTEX;
361 break;
362
363 case ARGI_EVENT:
364
365 /* Need an operand of type ACPI_TYPE_EVENT */
366
367 type_needed = ACPI_TYPE_EVENT;
368 break;
369
370 case ARGI_PACKAGE: /* Package */
371
372 /* Need an operand of type ACPI_TYPE_PACKAGE */
373
374 type_needed = ACPI_TYPE_PACKAGE;
375 break;
376
377 case ARGI_ANYTYPE:
378
379 /* Any operand type will do */
380
381 type_needed = ACPI_TYPE_ANY;
382 break;
383
384 case ARGI_DDBHANDLE:
385
386 /* Need an operand of type ACPI_TYPE_DDB_HANDLE */
387
388 type_needed = ACPI_TYPE_LOCAL_REFERENCE;
389 break;
390
391
392 /*
393 * The more complex cases allow multiple resolved object types
394 */
395 case ARGI_INTEGER: /* Number */
396
397 /*
398 * Need an operand of type ACPI_TYPE_INTEGER,
399 * But we can implicitly convert from a STRING or BUFFER
400 * Aka - "Implicit Source Operand Conversion"
401 */
402 status = acpi_ex_convert_to_integer (obj_desc, stack_ptr, 16);
403 if (ACPI_FAILURE (status)) {
404 if (status == AE_TYPE) {
405 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
406 "Needed [Integer/String/Buffer], found [%s] %p\n",
407 acpi_ut_get_object_type_name (obj_desc), obj_desc));
408
409 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
410 }
411
412 return_ACPI_STATUS (status);
413 }
414 goto next_operand;
415
416
417 case ARGI_BUFFER:
418
419 /*
420 * Need an operand of type ACPI_TYPE_BUFFER,
421 * But we can implicitly convert from a STRING or INTEGER
422 * Aka - "Implicit Source Operand Conversion"
423 */
424 status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr);
425 if (ACPI_FAILURE (status)) {
426 if (status == AE_TYPE) {
427 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
428 "Needed [Integer/String/Buffer], found [%s] %p\n",
429 acpi_ut_get_object_type_name (obj_desc), obj_desc));
430
431 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
432 }
433
434 return_ACPI_STATUS (status);
435 }
436 goto next_operand;
437
438
439 case ARGI_STRING:
440
441 /*
442 * Need an operand of type ACPI_TYPE_STRING,
443 * But we can implicitly convert from a BUFFER or INTEGER
444 * Aka - "Implicit Source Operand Conversion"
445 */
446 status = acpi_ex_convert_to_string (obj_desc, stack_ptr,
447 ACPI_IMPLICIT_CONVERT_HEX);
448 if (ACPI_FAILURE (status)) {
449 if (status == AE_TYPE) {
450 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
451 "Needed [Integer/String/Buffer], found [%s] %p\n",
452 acpi_ut_get_object_type_name (obj_desc), obj_desc));
453
454 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
455 }
456
457 return_ACPI_STATUS (status);
458 }
459 goto next_operand;
460
461
462 case ARGI_COMPUTEDATA:
463
464 /* Need an operand of type INTEGER, STRING or BUFFER */
465
466 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
467 case ACPI_TYPE_INTEGER:
468 case ACPI_TYPE_STRING:
469 case ACPI_TYPE_BUFFER:
470
471 /* Valid operand */
472 break;
473
474 default:
475 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
476 "Needed [Integer/String/Buffer], found [%s] %p\n",
477 acpi_ut_get_object_type_name (obj_desc), obj_desc));
478
479 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
480 }
481 goto next_operand;
482
483
484 case ARGI_BUFFER_OR_STRING:
485
486 /* Need an operand of type STRING or BUFFER */
487
488 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
489 case ACPI_TYPE_STRING:
490 case ACPI_TYPE_BUFFER:
491
492 /* Valid operand */
493 break;
494
495 case ACPI_TYPE_INTEGER:
496
497 /* Highest priority conversion is to type Buffer */
498
499 status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr);
500 if (ACPI_FAILURE (status)) {
501 return_ACPI_STATUS (status);
502 }
503 break;
504
505 default:
506 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
507 "Needed [Integer/String/Buffer], found [%s] %p\n",
508 acpi_ut_get_object_type_name (obj_desc), obj_desc));
509
510 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
511 }
512 goto next_operand;
513
514
515 case ARGI_DATAOBJECT:
516 /*
517 * ARGI_DATAOBJECT is only used by the size_of operator.
518 * Need a buffer, string, package, or ref_of reference.
519 *
520 * The only reference allowed here is a direct reference to
521 * a namespace node.
522 */
523 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
524 case ACPI_TYPE_PACKAGE:
525 case ACPI_TYPE_STRING:
526 case ACPI_TYPE_BUFFER:
527 case ACPI_TYPE_LOCAL_REFERENCE:
528
529 /* Valid operand */
530 break;
531
532 default:
533 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
534 "Needed [Buffer/String/Package/Reference], found [%s] %p\n",
535 acpi_ut_get_object_type_name (obj_desc), obj_desc));
536
537 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
538 }
539 goto next_operand;
540
541
542 case ARGI_COMPLEXOBJ:
543
544 /* Need a buffer or package or (ACPI 2.0) String */
545
546 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
547 case ACPI_TYPE_PACKAGE:
548 case ACPI_TYPE_STRING:
549 case ACPI_TYPE_BUFFER:
550
551 /* Valid operand */
552 break;
553
554 default:
555 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
556 "Needed [Buffer/String/Package], found [%s] %p\n",
557 acpi_ut_get_object_type_name (obj_desc), obj_desc));
558
559 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
560 }
561 goto next_operand;
562
563
564 case ARGI_REGION_OR_FIELD:
565
566 /* Need an operand of type ACPI_TYPE_REGION or a FIELD in a region */
567
568 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
569 case ACPI_TYPE_REGION:
570 case ACPI_TYPE_LOCAL_REGION_FIELD:
571 case ACPI_TYPE_LOCAL_BANK_FIELD:
572 case ACPI_TYPE_LOCAL_INDEX_FIELD:
573
574 /* Valid operand */
575 break;
576
577 default:
578 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
579 "Needed [Region/region_field], found [%s] %p\n",
580 acpi_ut_get_object_type_name (obj_desc), obj_desc));
581
582 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
583 }
584 goto next_operand;
585
586
587 case ARGI_DATAREFOBJ:
588
589 /* Used by the Store() operator only */
590
591 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
592 case ACPI_TYPE_INTEGER:
593 case ACPI_TYPE_PACKAGE:
594 case ACPI_TYPE_STRING:
595 case ACPI_TYPE_BUFFER:
596 case ACPI_TYPE_BUFFER_FIELD:
597 case ACPI_TYPE_LOCAL_REFERENCE:
598 case ACPI_TYPE_LOCAL_REGION_FIELD:
599 case ACPI_TYPE_LOCAL_BANK_FIELD:
600 case ACPI_TYPE_LOCAL_INDEX_FIELD:
601 case ACPI_TYPE_DDB_HANDLE:
602
603 /* Valid operand */
604 break;
605
606 default:
607
608 if (acpi_gbl_enable_interpreter_slack) {
609 /*
610 * Enable original behavior of Store(), allowing any and all
611 * objects as the source operand. The ACPI spec does not
612 * allow this, however.
613 */
614 break;
615 }
616
617 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
618 "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n",
619 acpi_ut_get_object_type_name (obj_desc), obj_desc));
620
621 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
622 }
623 goto next_operand;
624
625
626 default:
627
628 /* Unknown type */
629
630 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
631 "Internal - Unknown ARGI (required operand) type %X\n",
632 this_arg_type));
633
634 return_ACPI_STATUS (AE_BAD_PARAMETER);
635 }
636
637 /*
638 * Make sure that the original object was resolved to the
639 * required object type (Simple cases only).
640 */
641 status = acpi_ex_check_object_type (type_needed,
642 ACPI_GET_OBJECT_TYPE (*stack_ptr), *stack_ptr);
643 if (ACPI_FAILURE (status)) {
644 return_ACPI_STATUS (status);
645 }
646
647next_operand:
648 /*
649 * If more operands needed, decrement stack_ptr to point
650 * to next operand on stack
651 */
652 if (GET_CURRENT_ARG_TYPE (arg_types)) {
653 stack_ptr--;
654 }
655
656 } /* while (*Types) */
657
658 return_ACPI_STATUS (status);
659}
660
661
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
new file mode 100644
index 000000000000..e0fc6aba1253
--- /dev/null
+++ b/drivers/acpi/executer/exstore.c
@@ -0,0 +1,536 @@
1
2/******************************************************************************
3 *
4 * Module Name: exstore - AML Interpreter object store support
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <acpi/amlcode.h>
50#include <acpi/acnamesp.h>
51
52
53#define _COMPONENT ACPI_EXECUTER
54 ACPI_MODULE_NAME ("exstore")
55
56
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ex_store
60 *
61 * PARAMETERS: *source_desc - Value to be stored
62 * *dest_desc - Where to store it. Must be an NS node
63 * or an union acpi_operand_object of type
64 * Reference;
65 * walk_state - Current walk state
66 *
67 * RETURN: Status
68 *
69 * DESCRIPTION: Store the value described by source_desc into the location
70 * described by dest_desc. Called by various interpreter
71 * functions to store the result of an operation into
72 * the destination operand -- not just simply the actual "Store"
73 * ASL operator.
74 *
75 ******************************************************************************/
76
77acpi_status
78acpi_ex_store (
79 union acpi_operand_object *source_desc,
80 union acpi_operand_object *dest_desc,
81 struct acpi_walk_state *walk_state)
82{
83 acpi_status status = AE_OK;
84 union acpi_operand_object *ref_desc = dest_desc;
85
86
87 ACPI_FUNCTION_TRACE_PTR ("ex_store", dest_desc);
88
89
90 /* Validate parameters */
91
92 if (!source_desc || !dest_desc) {
93 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null parameter\n"));
94 return_ACPI_STATUS (AE_AML_NO_OPERAND);
95 }
96
97 /* dest_desc can be either a namespace node or an ACPI object */
98
99 if (ACPI_GET_DESCRIPTOR_TYPE (dest_desc) == ACPI_DESC_TYPE_NAMED) {
100 /*
101 * Dest is a namespace node,
102 * Storing an object into a Named node.
103 */
104 status = acpi_ex_store_object_to_node (source_desc,
105 (struct acpi_namespace_node *) dest_desc, walk_state,
106 ACPI_IMPLICIT_CONVERSION);
107
108 return_ACPI_STATUS (status);
109 }
110
111 /* Destination object must be a Reference or a Constant object */
112
113 switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
114 case ACPI_TYPE_LOCAL_REFERENCE:
115 break;
116
117 case ACPI_TYPE_INTEGER:
118
119 /* Allow stores to Constants -- a Noop as per ACPI spec */
120
121 if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
122 return_ACPI_STATUS (AE_OK);
123 }
124
125 /*lint -fallthrough */
126
127 default:
128
129 /* Destination is not a Reference object */
130
131 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
132 "Target is not a Reference or Constant object - %s [%p]\n",
133 acpi_ut_get_object_type_name (dest_desc), dest_desc));
134
135 ACPI_DUMP_STACK_ENTRY (source_desc);
136 ACPI_DUMP_STACK_ENTRY (dest_desc);
137 ACPI_DUMP_OPERANDS (&dest_desc, ACPI_IMODE_EXECUTE, "ex_store",
138 2, "Target is not a Reference or Constant object");
139
140 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
141 }
142
143 /*
144 * Examine the Reference opcode. These cases are handled:
145 *
146 * 1) Store to Name (Change the object associated with a name)
147 * 2) Store to an indexed area of a Buffer or Package
148 * 3) Store to a Method Local or Arg
149 * 4) Store to the debug object
150 */
151 switch (ref_desc->reference.opcode) {
152 case AML_NAME_OP:
153 case AML_REF_OF_OP:
154
155 /* Storing an object into a Name "container" */
156
157 status = acpi_ex_store_object_to_node (source_desc, ref_desc->reference.object,
158 walk_state, ACPI_IMPLICIT_CONVERSION);
159 break;
160
161
162 case AML_INDEX_OP:
163
164 /* Storing to an Index (pointer into a packager or buffer) */
165
166 status = acpi_ex_store_object_to_index (source_desc, ref_desc, walk_state);
167 break;
168
169
170 case AML_LOCAL_OP:
171 case AML_ARG_OP:
172
173 /* Store to a method local/arg */
174
175 status = acpi_ds_store_object_to_local (ref_desc->reference.opcode,
176 ref_desc->reference.offset, source_desc, walk_state);
177 break;
178
179
180 case AML_DEBUG_OP:
181
182 /*
183 * Storing to the Debug object causes the value stored to be
184 * displayed and otherwise has no effect -- see ACPI Specification
185 */
186 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
187 "**** Write to Debug Object: Object %p %s ****:\n\n",
188 source_desc, acpi_ut_get_object_type_name (source_desc)));
189
190 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ",
191 acpi_ut_get_object_type_name (source_desc)));
192
193 if (!acpi_ut_valid_internal_object (source_desc)) {
194 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
195 "%p, Invalid Internal Object!\n", source_desc));
196 break;
197 }
198
199 switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
200 case ACPI_TYPE_INTEGER:
201
202 if (acpi_gbl_integer_byte_width == 4) {
203 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
204 (u32) source_desc->integer.value));
205 }
206 else {
207 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
208 ACPI_FORMAT_UINT64 (source_desc->integer.value)));
209 }
210 break;
211
212
213 case ACPI_TYPE_BUFFER:
214
215 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]",
216 (u32) source_desc->buffer.length));
217 ACPI_DUMP_BUFFER (source_desc->buffer.pointer,
218 (source_desc->buffer.length < 32) ? source_desc->buffer.length : 32);
219 break;
220
221
222 case ACPI_TYPE_STRING:
223
224 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
225 source_desc->string.length, source_desc->string.pointer));
226 break;
227
228
229 case ACPI_TYPE_PACKAGE:
230
231 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] Elements Ptr - %p\n",
232 source_desc->package.count, source_desc->package.elements));
233 break;
234
235
236 default:
237
238 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n",
239 source_desc));
240 break;
241 }
242
243 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
244 break;
245
246
247 default:
248
249 ACPI_REPORT_ERROR (("ex_store: Unknown Reference opcode %X\n",
250 ref_desc->reference.opcode));
251 ACPI_DUMP_ENTRY (ref_desc, ACPI_LV_ERROR);
252
253 status = AE_AML_INTERNAL;
254 break;
255 }
256
257 return_ACPI_STATUS (status);
258}
259
260
261/*******************************************************************************
262 *
263 * FUNCTION: acpi_ex_store_object_to_index
264 *
265 * PARAMETERS: *source_desc - Value to be stored
266 * *dest_desc - Named object to receive the value
267 * walk_state - Current walk state
268 *
269 * RETURN: Status
270 *
271 * DESCRIPTION: Store the object to indexed Buffer or Package element
272 *
273 ******************************************************************************/
274
275acpi_status
276acpi_ex_store_object_to_index (
277 union acpi_operand_object *source_desc,
278 union acpi_operand_object *index_desc,
279 struct acpi_walk_state *walk_state)
280{
281 acpi_status status = AE_OK;
282 union acpi_operand_object *obj_desc;
283 union acpi_operand_object *new_desc;
284 u8 value = 0;
285 u32 i;
286
287
288 ACPI_FUNCTION_TRACE ("ex_store_object_to_index");
289
290
291 /*
292 * Destination must be a reference pointer, and
293 * must point to either a buffer or a package
294 */
295 switch (index_desc->reference.target_type) {
296 case ACPI_TYPE_PACKAGE:
297 /*
298 * Storing to a package element. Copy the object and replace
299 * any existing object with the new object. No implicit
300 * conversion is performed.
301 *
302 * The object at *(index_desc->Reference.Where) is the
303 * element within the package that is to be modified.
304 * The parent package object is at index_desc->Reference.Object
305 */
306 obj_desc = *(index_desc->reference.where);
307
308 status = acpi_ut_copy_iobject_to_iobject (source_desc, &new_desc, walk_state);
309 if (ACPI_FAILURE (status)) {
310 return_ACPI_STATUS (status);
311 }
312
313 if (obj_desc) {
314 /* Decrement reference count by the ref count of the parent package */
315
316 for (i = 0; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
317 acpi_ut_remove_reference (obj_desc);
318 }
319 }
320
321 *(index_desc->reference.where) = new_desc;
322
323 /* Increment reference count by the ref count of the parent package -1 */
324
325 for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
326 acpi_ut_add_reference (new_desc);
327 }
328
329 break;
330
331
332 case ACPI_TYPE_BUFFER_FIELD:
333
334 /*
335 * Store into a Buffer or String (not actually a real buffer_field)
336 * at a location defined by an Index.
337 *
338 * The first 8-bit element of the source object is written to the
339 * 8-bit Buffer location defined by the Index destination object,
340 * according to the ACPI 2.0 specification.
341 */
342
343 /*
344 * Make sure the target is a Buffer or String. An error should
345 * not happen here, since the reference_object was constructed
346 * by the INDEX_OP code.
347 */
348 obj_desc = index_desc->reference.object;
349 if ((ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) &&
350 (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_STRING)) {
351 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
352 }
353
354 /*
355 * The assignment of the individual elements will be slightly
356 * different for each source type.
357 */
358 switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
359 case ACPI_TYPE_INTEGER:
360
361 /* Use the least-significant byte of the integer */
362
363 value = (u8) (source_desc->integer.value);
364 break;
365
366 case ACPI_TYPE_BUFFER:
367 case ACPI_TYPE_STRING:
368
369 /* Note: Takes advantage of common string/buffer fields */
370
371 value = source_desc->buffer.pointer[0];
372 break;
373
374 default:
375
376 /* All other types are invalid */
377
378 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
379 "Source must be Integer/Buffer/String type, not %s\n",
380 acpi_ut_get_object_type_name (source_desc)));
381 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
382 }
383
384 /* Store the source value into the target buffer byte */
385
386 obj_desc->buffer.pointer[index_desc->reference.offset] = value;
387 break;
388
389
390 default:
391 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
392 "Target is not a Package or buffer_field\n"));
393 status = AE_AML_OPERAND_TYPE;
394 break;
395 }
396
397 return_ACPI_STATUS (status);
398}
399
400
401/*******************************************************************************
402 *
403 * FUNCTION: acpi_ex_store_object_to_node
404 *
405 * PARAMETERS: source_desc - Value to be stored
406 * Node - Named object to receive the value
407 * walk_state - Current walk state
408 * implicit_conversion - Perform implicit conversion (yes/no)
409 *
410 * RETURN: Status
411 *
412 * DESCRIPTION: Store the object to the named object.
413 *
414 * The Assignment of an object to a named object is handled here
415 * The value passed in will replace the current value (if any)
416 * with the input value.
417 *
418 * When storing into an object the data is converted to the
419 * target object type then stored in the object. This means
420 * that the target object type (for an initialized target) will
421 * not be changed by a store operation.
422 *
423 * Assumes parameters are already validated.
424 *
425 ******************************************************************************/
426
427acpi_status
428acpi_ex_store_object_to_node (
429 union acpi_operand_object *source_desc,
430 struct acpi_namespace_node *node,
431 struct acpi_walk_state *walk_state,
432 u8 implicit_conversion)
433{
434 acpi_status status = AE_OK;
435 union acpi_operand_object *target_desc;
436 union acpi_operand_object *new_desc;
437 acpi_object_type target_type;
438
439
440 ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_node", source_desc);
441
442
443 /*
444 * Get current type of the node, and object attached to Node
445 */
446 target_type = acpi_ns_get_type (node);
447 target_desc = acpi_ns_get_attached_object (node);
448
449 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
450 source_desc, acpi_ut_get_object_type_name (source_desc),
451 node, acpi_ut_get_type_name (target_type)));
452
453 /*
454 * Resolve the source object to an actual value
455 * (If it is a reference object)
456 */
457 status = acpi_ex_resolve_object (&source_desc, target_type, walk_state);
458 if (ACPI_FAILURE (status)) {
459 return_ACPI_STATUS (status);
460 }
461
462 /* If no implicit conversion, drop into the default case below */
463
464 if (!implicit_conversion) {
465 /* Force execution of default (no implicit conversion) */
466
467 target_type = ACPI_TYPE_ANY;
468 }
469
470 /*
471 * Do the actual store operation
472 */
473 switch (target_type) {
474 case ACPI_TYPE_BUFFER_FIELD:
475 case ACPI_TYPE_LOCAL_REGION_FIELD:
476 case ACPI_TYPE_LOCAL_BANK_FIELD:
477 case ACPI_TYPE_LOCAL_INDEX_FIELD:
478
479 /*
480 * For fields, copy the source data to the target field.
481 */
482 status = acpi_ex_write_data_to_field (source_desc, target_desc, &walk_state->result_obj);
483 break;
484
485
486 case ACPI_TYPE_INTEGER:
487 case ACPI_TYPE_STRING:
488 case ACPI_TYPE_BUFFER:
489
490 /*
491 * These target types are all of type Integer/String/Buffer, and
492 * therefore support implicit conversion before the store.
493 *
494 * Copy and/or convert the source object to a new target object
495 */
496 status = acpi_ex_store_object_to_object (source_desc, target_desc, &new_desc, walk_state);
497 if (ACPI_FAILURE (status)) {
498 return_ACPI_STATUS (status);
499 }
500
501 if (new_desc != target_desc) {
502 /*
503 * Store the new new_desc as the new value of the Name, and set
504 * the Name's type to that of the value being stored in it.
505 * source_desc reference count is incremented by attach_object.
506 *
507 * Note: This may change the type of the node if an explicit store
508 * has been performed such that the node/object type has been
509 * changed.
510 */
511 status = acpi_ns_attach_object (node, new_desc, new_desc->common.type);
512
513 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
514 "Store %s into %s via Convert/Attach\n",
515 acpi_ut_get_object_type_name (source_desc),
516 acpi_ut_get_object_type_name (new_desc)));
517 }
518 break;
519
520
521 default:
522
523 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
524 "Storing %s (%p) directly into node (%p), no implicit conversion\n",
525 acpi_ut_get_object_type_name (source_desc), source_desc, node));
526
527 /* No conversions for all other types. Just attach the source object */
528
529 status = acpi_ns_attach_object (node, source_desc, ACPI_GET_OBJECT_TYPE (source_desc));
530 break;
531 }
532
533 return_ACPI_STATUS (status);
534}
535
536
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
new file mode 100644
index 000000000000..d3677feb07fd
--- /dev/null
+++ b/drivers/acpi/executer/exstoren.c
@@ -0,0 +1,306 @@
1
2/******************************************************************************
3 *
4 * Module Name: exstoren - AML Interpreter object store support,
5 * Store to Node (namespace object)
6 *
7 *****************************************************************************/
8
9/*
10 * Copyright (C) 2000 - 2005, R. Byron Moore
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions, and the following disclaimer,
18 * without modification.
19 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
20 * substantially similar to the "NO WARRANTY" disclaimer below
21 * ("Disclaimer") and any redistribution must be conditioned upon
22 * including a substantially similar Disclaimer requirement for further
23 * binary redistribution.
24 * 3. Neither the names of the above-listed copyright holders nor the names
25 * of any contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * Alternatively, this software may be distributed under the terms of the
29 * GNU General Public License ("GPL") version 2 as published by the Free
30 * Software Foundation.
31 *
32 * NO WARRANTY
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
36 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 * POSSIBILITY OF SUCH DAMAGES.
44 */
45
46
47#include <acpi/acpi.h>
48#include <acpi/acinterp.h>
49#include <acpi/amlcode.h>
50
51
52#define _COMPONENT ACPI_EXECUTER
53 ACPI_MODULE_NAME ("exstoren")
54
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ex_resolve_object
59 *
60 * PARAMETERS: source_desc_ptr - Pointer to the source object
61 * target_type - Current type of the target
62 * walk_state - Current walk state
63 *
64 * RETURN: Status, resolved object in source_desc_ptr.
65 *
66 * DESCRIPTION: Resolve an object. If the object is a reference, dereference
67 * it and return the actual object in the source_desc_ptr.
68 *
69 ******************************************************************************/
70
71acpi_status
72acpi_ex_resolve_object (
73 union acpi_operand_object **source_desc_ptr,
74 acpi_object_type target_type,
75 struct acpi_walk_state *walk_state)
76{
77 union acpi_operand_object *source_desc = *source_desc_ptr;
78 acpi_status status = AE_OK;
79
80
81 ACPI_FUNCTION_TRACE ("ex_resolve_object");
82
83
84 /*
85 * Ensure we have a Target that can be stored to
86 */
87 switch (target_type) {
88 case ACPI_TYPE_BUFFER_FIELD:
89 case ACPI_TYPE_LOCAL_REGION_FIELD:
90 case ACPI_TYPE_LOCAL_BANK_FIELD:
91 case ACPI_TYPE_LOCAL_INDEX_FIELD:
92 /*
93 * These cases all require only Integers or values that
94 * can be converted to Integers (Strings or Buffers)
95 */
96
97 case ACPI_TYPE_INTEGER:
98 case ACPI_TYPE_STRING:
99 case ACPI_TYPE_BUFFER:
100
101 /*
102 * Stores into a Field/Region or into a Integer/Buffer/String
103 * are all essentially the same. This case handles the
104 * "interchangeable" types Integer, String, and Buffer.
105 */
106 if (ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
107 /* Resolve a reference object first */
108
109 status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state);
110 if (ACPI_FAILURE (status)) {
111 break;
112 }
113 }
114
115 /* For copy_object, no further validation necessary */
116
117 if (walk_state->opcode == AML_COPY_OP) {
118 break;
119 }
120
121 /*
122 * Must have a Integer, Buffer, or String
123 */
124 if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) &&
125 (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) &&
126 (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) &&
127 !((ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) && (source_desc->reference.opcode == AML_LOAD_OP))) {
128 /*
129 * Conversion successful but still not a valid type
130 */
131 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
132 "Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
133 acpi_ut_get_object_type_name (source_desc),
134 acpi_ut_get_type_name (target_type)));
135 status = AE_AML_OPERAND_TYPE;
136 }
137 break;
138
139
140 case ACPI_TYPE_LOCAL_ALIAS:
141 case ACPI_TYPE_LOCAL_METHOD_ALIAS:
142
143 /*
144 * Aliases are resolved by acpi_ex_prep_operands
145 */
146 ACPI_REPORT_ERROR (("Store into Alias - should never happen\n"));
147 status = AE_AML_INTERNAL;
148 break;
149
150
151 case ACPI_TYPE_PACKAGE:
152 default:
153
154 /*
155 * All other types than Alias and the various Fields come here,
156 * including the untyped case - ACPI_TYPE_ANY.
157 */
158 break;
159 }
160
161 return_ACPI_STATUS (status);
162}
163
164
165/*******************************************************************************
166 *
167 * FUNCTION: acpi_ex_store_object_to_object
168 *
169 * PARAMETERS: source_desc - Object to store
170 * dest_desc - Object to receive a copy of the source
171 * new_desc - New object if dest_desc is obsoleted
172 * walk_state - Current walk state
173 *
174 * RETURN: Status
175 *
176 * DESCRIPTION: "Store" an object to another object. This may include
177 * converting the source type to the target type (implicit
178 * conversion), and a copy of the value of the source to
179 * the target.
180 *
181 * The Assignment of an object to another (not named) object
182 * is handled here.
183 * The Source passed in will replace the current value (if any)
184 * with the input value.
185 *
186 * When storing into an object the data is converted to the
187 * target object type then stored in the object. This means
188 * that the target object type (for an initialized target) will
189 * not be changed by a store operation.
190 *
191 * This module allows destination types of Number, String,
192 * Buffer, and Package.
193 *
194 * Assumes parameters are already validated. NOTE: source_desc
195 * resolution (from a reference object) must be performed by
196 * the caller if necessary.
197 *
198 ******************************************************************************/
199
200acpi_status
201acpi_ex_store_object_to_object (
202 union acpi_operand_object *source_desc,
203 union acpi_operand_object *dest_desc,
204 union acpi_operand_object **new_desc,
205 struct acpi_walk_state *walk_state)
206{
207 union acpi_operand_object *actual_src_desc;
208 acpi_status status = AE_OK;
209
210
211 ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc);
212
213
214 actual_src_desc = source_desc;
215 if (!dest_desc) {
216 /*
217 * There is no destination object (An uninitialized node or
218 * package element), so we can simply copy the source object
219 * creating a new destination object
220 */
221 status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, new_desc, walk_state);
222 return_ACPI_STATUS (status);
223 }
224
225 if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
226 /*
227 * The source type does not match the type of the destination.
228 * Perform the "implicit conversion" of the source to the current type
229 * of the target as per the ACPI specification.
230 *
231 * If no conversion performed, actual_src_desc = source_desc.
232 * Otherwise, actual_src_desc is a temporary object to hold the
233 * converted object.
234 */
235 status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc),
236 source_desc, &actual_src_desc, walk_state);
237 if (ACPI_FAILURE (status)) {
238 return_ACPI_STATUS (status);
239 }
240
241 if (source_desc == actual_src_desc) {
242 /*
243 * No conversion was performed. Return the source_desc as the
244 * new object.
245 */
246 *new_desc = source_desc;
247 return_ACPI_STATUS (AE_OK);
248 }
249 }
250
251 /*
252 * We now have two objects of identical types, and we can perform a
253 * copy of the *value* of the source object.
254 */
255 switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
256 case ACPI_TYPE_INTEGER:
257
258 dest_desc->integer.value = actual_src_desc->integer.value;
259
260 /* Truncate value if we are executing from a 32-bit ACPI table */
261
262 acpi_ex_truncate_for32bit_table (dest_desc);
263 break;
264
265 case ACPI_TYPE_STRING:
266
267 status = acpi_ex_store_string_to_string (actual_src_desc, dest_desc);
268 break;
269
270 case ACPI_TYPE_BUFFER:
271
272 /*
273 * Note: There is different store behavior depending on the original
274 * source type
275 */
276 status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc);
277 break;
278
279 case ACPI_TYPE_PACKAGE:
280
281 status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc,
282 walk_state);
283 break;
284
285 default:
286 /*
287 * All other types come here.
288 */
289 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into type %s not implemented\n",
290 acpi_ut_get_object_type_name (dest_desc)));
291
292 status = AE_NOT_IMPLEMENTED;
293 break;
294 }
295
296 if (actual_src_desc != source_desc) {
297 /* Delete the intermediate (temporary) source object */
298
299 acpi_ut_remove_reference (actual_src_desc);
300 }
301
302 *new_desc = dest_desc;
303 return_ACPI_STATUS (status);
304}
305
306
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
new file mode 100644
index 000000000000..05e1ecae8d92
--- /dev/null
+++ b/drivers/acpi/executer/exstorob.c
@@ -0,0 +1,216 @@
1
2/******************************************************************************
3 *
4 * Module Name: exstorob - AML Interpreter object store support, store to object
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acinterp.h>
48
49
50#define _COMPONENT ACPI_EXECUTER
51 ACPI_MODULE_NAME ("exstorob")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ex_store_buffer_to_buffer
57 *
58 * PARAMETERS: source_desc - Source object to copy
59 * target_desc - Destination object of the copy
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Copy a buffer object to another buffer object.
64 *
65 ******************************************************************************/
66
67acpi_status
68acpi_ex_store_buffer_to_buffer (
69 union acpi_operand_object *source_desc,
70 union acpi_operand_object *target_desc)
71{
72 u32 length;
73 u8 *buffer;
74
75
76 ACPI_FUNCTION_TRACE_PTR ("ex_store_buffer_to_buffer", source_desc);
77
78
79 /* We know that source_desc is a buffer by now */
80
81 buffer = (u8 *) source_desc->buffer.pointer;
82 length = source_desc->buffer.length;
83
84 /*
85 * If target is a buffer of length zero or is a static buffer,
86 * allocate a new buffer of the proper length
87 */
88 if ((target_desc->buffer.length == 0) ||
89 (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
90 target_desc->buffer.pointer = ACPI_MEM_ALLOCATE (length);
91 if (!target_desc->buffer.pointer) {
92 return_ACPI_STATUS (AE_NO_MEMORY);
93 }
94
95 target_desc->buffer.length = length;
96 }
97
98 /* Copy source buffer to target buffer */
99
100 if (length <= target_desc->buffer.length) {
101 /* Clear existing buffer and copy in the new one */
102
103 ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
104 ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);
105
106#ifdef ACPI_OBSOLETE_BEHAVIOR
107 /*
108 * NOTE: ACPI versions up to 3.0 specified that the buffer must be
109 * truncated if the string is smaller than the buffer. However, "other"
110 * implementations of ACPI never did this and thus became the defacto
111 * standard. ACPi 3.0_a changes this behavior such that the buffer
112 * is no longer truncated.
113 */
114
115 /*
116 * OBSOLETE BEHAVIOR:
117 * If the original source was a string, we must truncate the buffer,
118 * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
119 * copy must not truncate the original buffer.
120 */
121 if (original_src_type == ACPI_TYPE_STRING) {
122 /* Set the new length of the target */
123
124 target_desc->buffer.length = length;
125 }
126#endif
127 }
128 else {
129 /* Truncate the source, copy only what will fit */
130
131 ACPI_MEMCPY (target_desc->buffer.pointer, buffer, target_desc->buffer.length);
132
133 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
134 "Truncating source buffer from %X to %X\n",
135 length, target_desc->buffer.length));
136 }
137
138 /* Copy flags */
139
140 target_desc->buffer.flags = source_desc->buffer.flags;
141 target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
142 return_ACPI_STATUS (AE_OK);
143}
144
145
146/*******************************************************************************
147 *
148 * FUNCTION: acpi_ex_store_string_to_string
149 *
150 * PARAMETERS: source_desc - Source object to copy
151 * target_desc - Destination object of the copy
152 *
153 * RETURN: Status
154 *
155 * DESCRIPTION: Copy a String object to another String object
156 *
157 ******************************************************************************/
158
159acpi_status
160acpi_ex_store_string_to_string (
161 union acpi_operand_object *source_desc,
162 union acpi_operand_object *target_desc)
163{
164 u32 length;
165 u8 *buffer;
166
167
168 ACPI_FUNCTION_TRACE_PTR ("ex_store_string_to_string", source_desc);
169
170
171 /* We know that source_desc is a string by now */
172
173 buffer = (u8 *) source_desc->string.pointer;
174 length = source_desc->string.length;
175
176 /*
177 * Replace existing string value if it will fit and the string
178 * pointer is not a static pointer (part of an ACPI table)
179 */
180 if ((length < target_desc->string.length) &&
181 (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
182 /*
183 * String will fit in existing non-static buffer.
184 * Clear old string and copy in the new one
185 */
186 ACPI_MEMSET (target_desc->string.pointer, 0, (acpi_size) target_desc->string.length + 1);
187 ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
188 }
189 else {
190 /*
191 * Free the current buffer, then allocate a new buffer
192 * large enough to hold the value
193 */
194 if (target_desc->string.pointer &&
195 (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
196 /* Only free if not a pointer into the DSDT */
197
198 ACPI_MEM_FREE (target_desc->string.pointer);
199 }
200
201 target_desc->string.pointer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1);
202 if (!target_desc->string.pointer) {
203 return_ACPI_STATUS (AE_NO_MEMORY);
204 }
205
206 target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
207 ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
208 }
209
210 /* Set the new target length */
211
212 target_desc->string.length = length;
213 return_ACPI_STATUS (AE_OK);
214}
215
216
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
new file mode 100644
index 000000000000..f92efc512890
--- /dev/null
+++ b/drivers/acpi/executer/exsystem.c
@@ -0,0 +1,378 @@
1
2/******************************************************************************
3 *
4 * Module Name: exsystem - Interface to OS services
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include <acpi/acpi.h>
47#include <acpi/acinterp.h>
48#include <acpi/acevents.h>
49
50#define _COMPONENT ACPI_EXECUTER
51 ACPI_MODULE_NAME ("exsystem")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ex_system_wait_semaphore
57 *
58 * PARAMETERS: Semaphore - OSD semaphore to wait on
59 * Timeout - Max time to wait
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Implements a semaphore wait with a check to see if the
64 * semaphore is available immediately. If it is not, the
65 * interpreter is released.
66 *
67 ******************************************************************************/
68
69acpi_status
70acpi_ex_system_wait_semaphore (
71 acpi_handle semaphore,
72 u16 timeout)
73{
74 acpi_status status;
75 acpi_status status2;
76
77
78 ACPI_FUNCTION_TRACE ("ex_system_wait_semaphore");
79
80
81 status = acpi_os_wait_semaphore (semaphore, 1, 0);
82 if (ACPI_SUCCESS (status)) {
83 return_ACPI_STATUS (status);
84 }
85
86 if (status == AE_TIME) {
87 /* We must wait, so unlock the interpreter */
88
89 acpi_ex_exit_interpreter ();
90
91 status = acpi_os_wait_semaphore (semaphore, 1, timeout);
92
93 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*** Thread awake after blocking, %s\n",
94 acpi_format_exception (status)));
95
96 /* Reacquire the interpreter */
97
98 status2 = acpi_ex_enter_interpreter ();
99 if (ACPI_FAILURE (status2)) {
100 /* Report fatal error, could not acquire interpreter */
101
102 return_ACPI_STATUS (status2);
103 }
104 }
105
106 return_ACPI_STATUS (status);
107}
108
109
110/*******************************************************************************
111 *
112 * FUNCTION: acpi_ex_system_do_stall
113 *
114 * PARAMETERS: how_long - The amount of time to stall,
115 * in microseconds
116 *
117 * RETURN: Status
118 *
119 * DESCRIPTION: Suspend running thread for specified amount of time.
120 * Note: ACPI specification requires that Stall() does not
121 * relinquish the processor, and delays longer than 100 usec
122 * should use Sleep() instead. We allow stalls up to 255 usec
123 * for compatibility with other interpreters and existing BIOSs.
124 *
125 ******************************************************************************/
126
127acpi_status
128acpi_ex_system_do_stall (
129 u32 how_long)
130{
131 acpi_status status = AE_OK;
132
133
134 ACPI_FUNCTION_ENTRY ();
135
136
137 if (how_long > 255) /* 255 microseconds */ {
138 /*
139 * Longer than 255 usec, this is an error
140 *
141 * (ACPI specifies 100 usec as max, but this gives some slack in
142 * order to support existing BIOSs)
143 */
144 ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long));
145 status = AE_AML_OPERAND_VALUE;
146 }
147 else {
148 acpi_os_stall (how_long);
149 }
150
151 return (status);
152}
153
154
155/*******************************************************************************
156 *
157 * FUNCTION: acpi_ex_system_do_suspend
158 *
159 * PARAMETERS: how_long - The amount of time to suspend,
160 * in milliseconds
161 *
162 * RETURN: None
163 *
164 * DESCRIPTION: Suspend running thread for specified amount of time.
165 *
166 ******************************************************************************/
167
168acpi_status
169acpi_ex_system_do_suspend (
170 acpi_integer how_long)
171{
172 acpi_status status;
173
174
175 ACPI_FUNCTION_ENTRY ();
176
177
178 /* Since this thread will sleep, we must release the interpreter */
179
180 acpi_ex_exit_interpreter ();
181
182 acpi_os_sleep (how_long);
183
184 /* And now we must get the interpreter again */
185
186 status = acpi_ex_enter_interpreter ();
187 return (status);
188}
189
190
191/*******************************************************************************
192 *
193 * FUNCTION: acpi_ex_system_acquire_mutex
194 *
195 * PARAMETERS: *time_desc - The 'time to delay' object descriptor
196 * *obj_desc - The object descriptor for this op
197 *
198 * RETURN: Status
199 *
200 * DESCRIPTION: Provides an access point to perform synchronization operations
201 * within the AML. This function will cause a lock to be generated
202 * for the Mutex pointed to by obj_desc.
203 *
204 ******************************************************************************/
205
206acpi_status
207acpi_ex_system_acquire_mutex (
208 union acpi_operand_object *time_desc,
209 union acpi_operand_object *obj_desc)
210{
211 acpi_status status = AE_OK;
212
213
214 ACPI_FUNCTION_TRACE_PTR ("ex_system_acquire_mutex", obj_desc);
215
216
217 if (!obj_desc) {
218 return_ACPI_STATUS (AE_BAD_PARAMETER);
219 }
220
221 /*
222 * Support for the _GL_ Mutex object -- go get the global lock
223 */
224 if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
225 status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value);
226 return_ACPI_STATUS (status);
227 }
228
229 status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore,
230 (u16) time_desc->integer.value);
231 return_ACPI_STATUS (status);
232}
233
234
235/*******************************************************************************
236 *
237 * FUNCTION: acpi_ex_system_release_mutex
238 *
239 * PARAMETERS: *obj_desc - The object descriptor for this op
240 *
241 * RETURN: Status
242 *
243 * DESCRIPTION: Provides an access point to perform synchronization operations
244 * within the AML. This operation is a request to release a
245 * previously acquired Mutex. If the Mutex variable is set then
246 * it will be decremented.
247 *
248 ******************************************************************************/
249
250acpi_status
251acpi_ex_system_release_mutex (
252 union acpi_operand_object *obj_desc)
253{
254 acpi_status status = AE_OK;
255
256
257 ACPI_FUNCTION_TRACE ("ex_system_release_mutex");
258
259
260 if (!obj_desc) {
261 return_ACPI_STATUS (AE_BAD_PARAMETER);
262 }
263
264 /*
265 * Support for the _GL_ Mutex object -- release the global lock
266 */
267 if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
268 status = acpi_ev_release_global_lock ();
269 return_ACPI_STATUS (status);
270 }
271
272 status = acpi_os_signal_semaphore (obj_desc->mutex.semaphore, 1);
273 return_ACPI_STATUS (status);
274}
275
276
277/*******************************************************************************
278 *
279 * FUNCTION: acpi_ex_system_signal_event
280 *
281 * PARAMETERS: *obj_desc - The object descriptor for this op
282 *
283 * RETURN: AE_OK
284 *
285 * DESCRIPTION: Provides an access point to perform synchronization operations
286 * within the AML.
287 *
288 ******************************************************************************/
289
290acpi_status
291acpi_ex_system_signal_event (
292 union acpi_operand_object *obj_desc)
293{
294 acpi_status status = AE_OK;
295
296
297 ACPI_FUNCTION_TRACE ("ex_system_signal_event");
298
299
300 if (obj_desc) {
301 status = acpi_os_signal_semaphore (obj_desc->event.semaphore, 1);
302 }
303
304 return_ACPI_STATUS (status);
305}
306
307
308/*******************************************************************************
309 *
310 * FUNCTION: acpi_ex_system_wait_event
311 *
312 * PARAMETERS: *time_desc - The 'time to delay' object descriptor
313 * *obj_desc - The object descriptor for this op
314 *
315 * RETURN: Status
316 *
317 * DESCRIPTION: Provides an access point to perform synchronization operations
318 * within the AML. This operation is a request to wait for an
319 * event.
320 *
321 ******************************************************************************/
322
323acpi_status
324acpi_ex_system_wait_event (
325 union acpi_operand_object *time_desc,
326 union acpi_operand_object *obj_desc)
327{
328 acpi_status status = AE_OK;
329
330
331 ACPI_FUNCTION_TRACE ("ex_system_wait_event");
332
333
334 if (obj_desc) {
335 status = acpi_ex_system_wait_semaphore (obj_desc->event.semaphore,
336 (u16) time_desc->integer.value);
337 }
338
339 return_ACPI_STATUS (status);
340}
341
342
343/*******************************************************************************
344 *
345 * FUNCTION: acpi_ex_system_reset_event
346 *
347 * PARAMETERS: *obj_desc - The object descriptor for this op
348 *
349 * RETURN: Status
350 *
351 * DESCRIPTION: Reset an event to a known state.
352 *
353 ******************************************************************************/
354
355acpi_status
356acpi_ex_system_reset_event (
357 union acpi_operand_object *obj_desc)
358{
359 acpi_status status = AE_OK;
360 void *temp_semaphore;
361
362
363 ACPI_FUNCTION_ENTRY ();
364
365
366 /*
367 * We are going to simply delete the existing semaphore and
368 * create a new one!
369 */
370 status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
371 if (ACPI_SUCCESS (status)) {
372 (void) acpi_os_delete_semaphore (obj_desc->event.semaphore);
373 obj_desc->event.semaphore = temp_semaphore;
374 }
375
376 return (status);
377}
378
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
new file mode 100644
index 000000000000..40c6abb8b49a
--- /dev/null
+++ b/drivers/acpi/executer/exutils.c
@@ -0,0 +1,378 @@
1
2/******************************************************************************
3 *
4 * Module Name: exutils - interpreter/scanner utilities
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46/*
47 * DEFINE_AML_GLOBALS is tested in amlcode.h
48 * to determine whether certain global names should be "defined" or only
49 * "declared" in the current compilation. This enhances maintainability
50 * by enabling a single header file to embody all knowledge of the names
51 * in question.
52 *
53 * Exactly one module of any executable should #define DEFINE_GLOBALS
54 * before #including the header files which use this convention. The
55 * names in question will be defined and initialized in that module,
56 * and declared as extern in all other modules which #include those
57 * header files.
58 */
59
60#define DEFINE_AML_GLOBALS
61
62#include <acpi/acpi.h>
63#include <acpi/acinterp.h>
64#include <acpi/amlcode.h>
65#include <acpi/acevents.h>
66
67#define _COMPONENT ACPI_EXECUTER
68 ACPI_MODULE_NAME ("exutils")
69
70
71#ifndef ACPI_NO_METHOD_EXECUTION
72
73/*******************************************************************************
74 *
75 * FUNCTION: acpi_ex_enter_interpreter
76 *
77 * PARAMETERS: None
78 *
79 * DESCRIPTION: Enter the interpreter execution region. Failure to enter
80 * the interpreter region is a fatal system error
81 *
82 ******************************************************************************/
83
84acpi_status
85acpi_ex_enter_interpreter (void)
86{
87 acpi_status status;
88
89 ACPI_FUNCTION_TRACE ("ex_enter_interpreter");
90
91
92 status = acpi_ut_acquire_mutex (ACPI_MTX_EXECUTE);
93 if (ACPI_FAILURE (status)) {
94 ACPI_REPORT_ERROR (("Could not acquire interpreter mutex\n"));
95 }
96
97 return_ACPI_STATUS (status);
98}
99
100
101/*******************************************************************************
102 *
103 * FUNCTION: acpi_ex_exit_interpreter
104 *
105 * PARAMETERS: None
106 *
107 * DESCRIPTION: Exit the interpreter execution region
108 *
109 * Cases where the interpreter is unlocked:
110 * 1) Completion of the execution of a control method
111 * 2) Method blocked on a Sleep() AML opcode
112 * 3) Method blocked on an Acquire() AML opcode
113 * 4) Method blocked on a Wait() AML opcode
114 * 5) Method blocked to acquire the global lock
115 * 6) Method blocked to execute a serialized control method that is
116 * already executing
117 * 7) About to invoke a user-installed opregion handler
118 *
119 ******************************************************************************/
120
121void
122acpi_ex_exit_interpreter (void)
123{
124 acpi_status status;
125
126
127 ACPI_FUNCTION_TRACE ("ex_exit_interpreter");
128
129
130 status = acpi_ut_release_mutex (ACPI_MTX_EXECUTE);
131 if (ACPI_FAILURE (status)) {
132 ACPI_REPORT_ERROR (("Could not release interpreter mutex\n"));
133 }
134
135 return_VOID;
136}
137
138
139/*******************************************************************************
140 *
141 * FUNCTION: acpi_ex_truncate_for32bit_table
142 *
143 * PARAMETERS: obj_desc - Object to be truncated
144 *
145 * RETURN: none
146 *
147 * DESCRIPTION: Truncate a number to 32-bits if the currently executing method
148 * belongs to a 32-bit ACPI table.
149 *
150 ******************************************************************************/
151
152void
153acpi_ex_truncate_for32bit_table (
154 union acpi_operand_object *obj_desc)
155{
156
157 ACPI_FUNCTION_ENTRY ();
158
159
160 /*
161 * Object must be a valid number and we must be executing
162 * a control method
163 */
164 if ((!obj_desc) ||
165 (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER)) {
166 return;
167 }
168
169 if (acpi_gbl_integer_byte_width == 4) {
170 /*
171 * We are running a method that exists in a 32-bit ACPI table.
172 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
173 */
174 obj_desc->integer.value &= (acpi_integer) ACPI_UINT32_MAX;
175 }
176}
177
178
179/*******************************************************************************
180 *
181 * FUNCTION: acpi_ex_acquire_global_lock
182 *
183 * PARAMETERS: field_flags - Flags with Lock rule:
184 * always_lock or never_lock
185 *
186 * RETURN: TRUE/FALSE indicating whether the lock was actually acquired
187 *
188 * DESCRIPTION: Obtain the global lock and keep track of this fact via two
189 * methods. A global variable keeps the state of the lock, and
190 * the state is returned to the caller.
191 *
192 ******************************************************************************/
193
194u8
195acpi_ex_acquire_global_lock (
196 u32 field_flags)
197{
198 u8 locked = FALSE;
199 acpi_status status;
200
201
202 ACPI_FUNCTION_TRACE ("ex_acquire_global_lock");
203
204
205 /* Only attempt lock if the always_lock bit is set */
206
207 if (field_flags & AML_FIELD_LOCK_RULE_MASK) {
208 /* We should attempt to get the lock, wait forever */
209
210 status = acpi_ev_acquire_global_lock (ACPI_WAIT_FOREVER);
211 if (ACPI_SUCCESS (status)) {
212 locked = TRUE;
213 }
214 else {
215 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not acquire Global Lock, %s\n",
216 acpi_format_exception (status)));
217 }
218 }
219
220 return_VALUE (locked);
221}
222
223
224/*******************************************************************************
225 *
226 * FUNCTION: acpi_ex_release_global_lock
227 *
228 * PARAMETERS: locked_by_me - Return value from corresponding call to
229 * acquire_global_lock.
230 *
231 * RETURN: Status
232 *
233 * DESCRIPTION: Release the global lock if it is locked.
234 *
235 ******************************************************************************/
236
237void
238acpi_ex_release_global_lock (
239 u8 locked_by_me)
240{
241 acpi_status status;
242
243
244 ACPI_FUNCTION_TRACE ("ex_release_global_lock");
245
246
247 /* Only attempt unlock if the caller locked it */
248
249 if (locked_by_me) {
250 /* OK, now release the lock */
251
252 status = acpi_ev_release_global_lock ();
253 if (ACPI_FAILURE (status)) {
254 /* Report the error, but there isn't much else we can do */
255
256 ACPI_REPORT_ERROR (("Could not release ACPI Global Lock, %s\n",
257 acpi_format_exception (status)));
258 }
259 }
260
261 return_VOID;
262}
263
264
265/*******************************************************************************
266 *
267 * FUNCTION: acpi_ex_digits_needed
268 *
269 * PARAMETERS: Value - Value to be represented
270 * Base - Base of representation
271 *
272 * RETURN: the number of digits needed to represent Value in Base
273 *
274 ******************************************************************************/
275
276u32
277acpi_ex_digits_needed (
278 acpi_integer value,
279 u32 base)
280{
281 u32 num_digits;
282 acpi_integer current_value;
283
284
285 ACPI_FUNCTION_TRACE ("ex_digits_needed");
286
287
288 /* acpi_integer is unsigned, so we don't worry about a '-' prefix */
289
290 if (value == 0) {
291 return_VALUE (1);
292 }
293
294 current_value = value;
295 num_digits = 0;
296
297 /* Count the digits in the requested base */
298
299 while (current_value) {
300 (void) acpi_ut_short_divide (current_value, base, &current_value, NULL);
301 num_digits++;
302 }
303
304 return_VALUE (num_digits);
305}
306
307
308/*******************************************************************************
309 *
310 * FUNCTION: acpi_ex_eisa_id_to_string
311 *
312 * PARAMETERS: numeric_id - EISA ID to be converted
313 * out_string - Where to put the converted string (8 bytes)
314 *
315 * DESCRIPTION: Convert a numeric EISA ID to string representation
316 *
317 ******************************************************************************/
318
319void
320acpi_ex_eisa_id_to_string (
321 u32 numeric_id,
322 char *out_string)
323{
324 u32 eisa_id;
325
326
327 ACPI_FUNCTION_ENTRY ();
328
329
330 /* Swap ID to big-endian to get contiguous bits */
331
332 eisa_id = acpi_ut_dword_byte_swap (numeric_id);
333
334 out_string[0] = (char) ('@' + (((unsigned long) eisa_id >> 26) & 0x1f));
335 out_string[1] = (char) ('@' + ((eisa_id >> 21) & 0x1f));
336 out_string[2] = (char) ('@' + ((eisa_id >> 16) & 0x1f));
337 out_string[3] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 12);
338 out_string[4] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 8);
339 out_string[5] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 4);
340 out_string[6] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 0);
341 out_string[7] = 0;
342}
343
344
345/*******************************************************************************
346 *
347 * FUNCTION: acpi_ex_unsigned_integer_to_string
348 *
349 * PARAMETERS: Value - Value to be converted
350 * out_string - Where to put the converted string (8 bytes)
351 *
352 * RETURN: Convert a number to string representation
353 *
354 ******************************************************************************/
355
356void
357acpi_ex_unsigned_integer_to_string (
358 acpi_integer value,
359 char *out_string)
360{
361 u32 count;
362 u32 digits_needed;
363 u32 remainder;
364
365
366 ACPI_FUNCTION_ENTRY ();
367
368
369 digits_needed = acpi_ex_digits_needed (value, 10);
370 out_string[digits_needed] = 0;
371
372 for (count = digits_needed; count > 0; count--) {
373 (void) acpi_ut_short_divide (value, 10, &value, &remainder);
374 out_string[count-1] = (char) ('0' + remainder);\
375 }
376}
377
378#endif