]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/acpi/executer/exstore.c
ACPICA 20050408 from Bob Moore
[linux-2.6.git] / drivers / acpi / executer / exstore.c
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 #include <acpi/acparser.h>
52
53
54 #define _COMPONENT          ACPI_EXECUTER
55          ACPI_MODULE_NAME    ("exstore")
56
57 /* Local prototypes */
58
59 static void
60 acpi_ex_do_debug_object (
61         union acpi_operand_object       *source_desc,
62         u32                             level,
63         u32                             index);
64
65 static acpi_status
66 acpi_ex_store_object_to_index (
67         union acpi_operand_object       *val_desc,
68         union acpi_operand_object       *dest_desc,
69         struct acpi_walk_state          *walk_state);
70
71
72 /*******************************************************************************
73  *
74  * FUNCTION:    acpi_ex_do_debug_object
75  *
76  * PARAMETERS:  source_desc         - Value to be stored
77  *              Level               - Indentation level (used for packages)
78  *              Index               - Current package element, zero if not pkg
79  *
80  * RETURN:      None
81  *
82  * DESCRIPTION: Handles stores to the Debug Object.
83  *
84  ******************************************************************************/
85
86 static void
87 acpi_ex_do_debug_object (
88         union acpi_operand_object       *source_desc,
89         u32                             level,
90         u32                             index)
91 {
92         u32                             i;
93
94
95         ACPI_FUNCTION_TRACE_PTR ("ex_do_debug_object", source_desc);
96
97
98         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
99                 level, " "));
100
101         /* Display index for package output only */
102
103         if (index > 0) {
104            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
105                    "(%.2u) ", index -1));
106         }
107
108         if (!source_desc) {
109                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n"));
110                 return_VOID;
111         }
112
113         if (ACPI_GET_DESCRIPTOR_TYPE (source_desc) == ACPI_DESC_TYPE_OPERAND) {
114                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: ",
115                         acpi_ut_get_object_type_name (source_desc)));
116
117                 if (!acpi_ut_valid_internal_object (source_desc)) {
118                    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
119                            "%p, Invalid Internal Object!\n", source_desc));
120                    return_VOID;
121                 }
122         }
123         else if (ACPI_GET_DESCRIPTOR_TYPE (source_desc) == ACPI_DESC_TYPE_NAMED) {
124                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
125                         acpi_ut_get_type_name (((struct acpi_namespace_node *) source_desc)->type),
126                         source_desc));
127                 return_VOID;
128         }
129         else {
130                 return_VOID;
131         }
132
133         switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
134         case ACPI_TYPE_INTEGER:
135
136                 /* Output correct integer width */
137
138                 if (acpi_gbl_integer_byte_width == 4) {
139                         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
140                                 (u32) source_desc->integer.value));
141                 }
142                 else {
143                         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
144                                 ACPI_FORMAT_UINT64 (source_desc->integer.value)));
145                 }
146                 break;
147
148         case ACPI_TYPE_BUFFER:
149
150                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]",
151                         (u32) source_desc->buffer.length));
152                 ACPI_DUMP_BUFFER (source_desc->buffer.pointer,
153                         (source_desc->buffer.length < 32) ? source_desc->buffer.length : 32);
154                 break;
155
156         case ACPI_TYPE_STRING:
157
158                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
159                         source_desc->string.length, source_desc->string.pointer));
160                 break;
161
162         case ACPI_TYPE_PACKAGE:
163
164                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X Elements]\n",
165                         source_desc->package.count));
166
167                 /* Output the entire contents of the package */
168
169                 for (i = 0; i < source_desc->package.count; i++) {
170                         acpi_ex_do_debug_object (source_desc->package.elements[i],
171                                 level+4, i+1);
172                 }
173                 break;
174
175         case ACPI_TYPE_LOCAL_REFERENCE:
176
177                 if (source_desc->reference.opcode == AML_INDEX_OP) {
178                         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s, 0x%X]\n",
179                                 acpi_ps_get_opcode_name (source_desc->reference.opcode),
180                                 source_desc->reference.offset));
181                 }
182                 else {
183                         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s]\n",
184                                 acpi_ps_get_opcode_name (source_desc->reference.opcode)));
185                 }
186
187
188                 if (source_desc->reference.object) {
189                         if (ACPI_GET_DESCRIPTOR_TYPE (source_desc->reference.object) ==
190                                         ACPI_DESC_TYPE_NAMED) {
191                                 acpi_ex_do_debug_object (((struct acpi_namespace_node *)
192                                         source_desc->reference.object)->object,
193                                         level+4, 0);
194                         }
195                         else {
196                                 acpi_ex_do_debug_object (source_desc->reference.object, level+4, 0);
197                         }
198                 }
199                 else if (source_desc->reference.node) {
200                         acpi_ex_do_debug_object ((source_desc->reference.node)->object,
201                                 level+4, 0);
202                 }
203                 break;
204
205         default:
206
207                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p %s\n",
208                         source_desc, acpi_ut_get_object_type_name (source_desc)));
209                 break;
210         }
211
212         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
213         return_VOID;
214 }
215
216
217 /*******************************************************************************
218  *
219  * FUNCTION:    acpi_ex_store
220  *
221  * PARAMETERS:  *source_desc        - Value to be stored
222  *              *dest_desc          - Where to store it.  Must be an NS node
223  *                                    or an union acpi_operand_object of type
224  *                                    Reference;
225  *              walk_state          - Current walk state
226  *
227  * RETURN:      Status
228  *
229  * DESCRIPTION: Store the value described by source_desc into the location
230  *              described by dest_desc. Called by various interpreter
231  *              functions to store the result of an operation into
232  *              the destination operand -- not just simply the actual "Store"
233  *              ASL operator.
234  *
235  ******************************************************************************/
236
237 acpi_status
238 acpi_ex_store (
239         union acpi_operand_object       *source_desc,
240         union acpi_operand_object       *dest_desc,
241         struct acpi_walk_state          *walk_state)
242 {
243         acpi_status                     status = AE_OK;
244         union acpi_operand_object       *ref_desc = dest_desc;
245
246
247         ACPI_FUNCTION_TRACE_PTR ("ex_store", dest_desc);
248
249
250         /* Validate parameters */
251
252         if (!source_desc || !dest_desc) {
253                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null parameter\n"));
254                 return_ACPI_STATUS (AE_AML_NO_OPERAND);
255         }
256
257         /* dest_desc can be either a namespace node or an ACPI object */
258
259         if (ACPI_GET_DESCRIPTOR_TYPE (dest_desc) == ACPI_DESC_TYPE_NAMED) {
260                 /*
261                  * Dest is a namespace node,
262                  * Storing an object into a Named node.
263                  */
264                 status = acpi_ex_store_object_to_node (source_desc,
265                                  (struct acpi_namespace_node *) dest_desc, walk_state,
266                                  ACPI_IMPLICIT_CONVERSION);
267
268                 return_ACPI_STATUS (status);
269         }
270
271         /* Destination object must be a Reference or a Constant object */
272
273         switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
274         case ACPI_TYPE_LOCAL_REFERENCE:
275                 break;
276
277         case ACPI_TYPE_INTEGER:
278
279                 /* Allow stores to Constants -- a Noop as per ACPI spec */
280
281                 if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
282                         return_ACPI_STATUS (AE_OK);
283                 }
284
285                 /*lint -fallthrough */
286
287         default:
288
289                 /* Destination is not a Reference object */
290
291                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
292                         "Target is not a Reference or Constant object - %s [%p]\n",
293                         acpi_ut_get_object_type_name (dest_desc), dest_desc));
294
295                 ACPI_DUMP_STACK_ENTRY (source_desc);
296                 ACPI_DUMP_STACK_ENTRY (dest_desc);
297                 ACPI_DUMP_OPERANDS (&dest_desc, ACPI_IMODE_EXECUTE, "ex_store",
298                                   2, "Target is not a Reference or Constant object");
299
300                 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
301         }
302
303         /*
304          * Examine the Reference opcode.  These cases are handled:
305          *
306          * 1) Store to Name (Change the object associated with a name)
307          * 2) Store to an indexed area of a Buffer or Package
308          * 3) Store to a Method Local or Arg
309          * 4) Store to the debug object
310          */
311         switch (ref_desc->reference.opcode) {
312         case AML_NAME_OP:
313         case AML_REF_OF_OP:
314
315                 /* Storing an object into a Name "container" */
316
317                 status = acpi_ex_store_object_to_node (source_desc,
318                                  ref_desc->reference.object,
319                                  walk_state, ACPI_IMPLICIT_CONVERSION);
320                 break;
321
322
323         case AML_INDEX_OP:
324
325                 /* Storing to an Index (pointer into a packager or buffer) */
326
327                 status = acpi_ex_store_object_to_index (source_desc, ref_desc, walk_state);
328                 break;
329
330
331         case AML_LOCAL_OP:
332         case AML_ARG_OP:
333
334                 /* Store to a method local/arg  */
335
336                 status = acpi_ds_store_object_to_local (ref_desc->reference.opcode,
337                                  ref_desc->reference.offset, source_desc, walk_state);
338                 break;
339
340
341         case AML_DEBUG_OP:
342
343                 /*
344                  * Storing to the Debug object causes the value stored to be
345                  * displayed and otherwise has no effect -- see ACPI Specification
346                  */
347                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
348                         "**** Write to Debug Object: Object %p %s ****:\n\n",
349                         source_desc, acpi_ut_get_object_type_name (source_desc)));
350
351                 acpi_ex_do_debug_object (source_desc, 0, 0);
352                 break;
353
354
355         default:
356
357                 ACPI_REPORT_ERROR (("ex_store: Unknown Reference opcode %X\n",
358                         ref_desc->reference.opcode));
359                 ACPI_DUMP_ENTRY (ref_desc, ACPI_LV_ERROR);
360
361                 status = AE_AML_INTERNAL;
362                 break;
363         }
364
365         return_ACPI_STATUS (status);
366 }
367
368
369 /*******************************************************************************
370  *
371  * FUNCTION:    acpi_ex_store_object_to_index
372  *
373  * PARAMETERS:  *source_desc            - Value to be stored
374  *              *dest_desc              - Named object to receive the value
375  *              walk_state              - Current walk state
376  *
377  * RETURN:      Status
378  *
379  * DESCRIPTION: Store the object to indexed Buffer or Package element
380  *
381  ******************************************************************************/
382
383 static acpi_status
384 acpi_ex_store_object_to_index (
385         union acpi_operand_object       *source_desc,
386         union acpi_operand_object       *index_desc,
387         struct acpi_walk_state          *walk_state)
388 {
389         acpi_status                     status = AE_OK;
390         union acpi_operand_object       *obj_desc;
391         union acpi_operand_object       *new_desc;
392         u8                              value = 0;
393         u32                             i;
394
395
396         ACPI_FUNCTION_TRACE ("ex_store_object_to_index");
397
398
399         /*
400          * Destination must be a reference pointer, and
401          * must point to either a buffer or a package
402          */
403         switch (index_desc->reference.target_type) {
404         case ACPI_TYPE_PACKAGE:
405                 /*
406                  * Storing to a package element. Copy the object and replace
407                  * any existing object with the new object. No implicit
408                  * conversion is performed.
409                  *
410                  * The object at *(index_desc->Reference.Where) is the
411                  * element within the package that is to be modified.
412                  * The parent package object is at index_desc->Reference.Object
413                  */
414                 obj_desc = *(index_desc->reference.where);
415
416                 status = acpi_ut_copy_iobject_to_iobject (source_desc, &new_desc, walk_state);
417                 if (ACPI_FAILURE (status)) {
418                         return_ACPI_STATUS (status);
419                 }
420
421                 if (obj_desc) {
422                         /* Decrement reference count by the ref count of the parent package */
423
424                         for (i = 0;
425                                  i < ((union acpi_operand_object *)
426                                                 index_desc->reference.object)->common.reference_count;
427                                  i++) {
428                                 acpi_ut_remove_reference (obj_desc);
429                         }
430                 }
431
432                 *(index_desc->reference.where) = new_desc;
433
434                 /* Increment ref count by the ref count of the parent package-1 */
435
436                 for (i = 1;
437                          i < ((union acpi_operand_object *)
438                                         index_desc->reference.object)->common.reference_count;
439                          i++) {
440                         acpi_ut_add_reference (new_desc);
441                 }
442
443                 break;
444
445
446         case ACPI_TYPE_BUFFER_FIELD:
447
448                 /*
449                  * Store into a Buffer or String (not actually a real buffer_field)
450                  * at a location defined by an Index.
451                  *
452                  * The first 8-bit element of the source object is written to the
453                  * 8-bit Buffer location defined by the Index destination object,
454                  * according to the ACPI 2.0 specification.
455                  */
456
457                 /*
458                  * Make sure the target is a Buffer or String. An error should
459                  * not happen here, since the reference_object was constructed
460                  * by the INDEX_OP code.
461                  */
462                 obj_desc = index_desc->reference.object;
463                 if ((ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) &&
464                         (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_STRING)) {
465                         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
466                 }
467
468                 /*
469                  * The assignment of the individual elements will be slightly
470                  * different for each source type.
471                  */
472                 switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
473                 case ACPI_TYPE_INTEGER:
474
475                         /* Use the least-significant byte of the integer */
476
477                         value = (u8) (source_desc->integer.value);
478                         break;
479
480                 case ACPI_TYPE_BUFFER:
481                 case ACPI_TYPE_STRING:
482
483                         /* Note: Takes advantage of common string/buffer fields */
484
485                         value = source_desc->buffer.pointer[0];
486                         break;
487
488                 default:
489
490                         /* All other types are invalid */
491
492                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
493                                 "Source must be Integer/Buffer/String type, not %s\n",
494                                 acpi_ut_get_object_type_name (source_desc)));
495                         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
496                 }
497
498                 /* Store the source value into the target buffer byte */
499
500                 obj_desc->buffer.pointer[index_desc->reference.offset] = value;
501                 break;
502
503
504         default:
505                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
506                         "Target is not a Package or buffer_field\n"));
507                 status = AE_AML_OPERAND_TYPE;
508                 break;
509         }
510
511         return_ACPI_STATUS (status);
512 }
513
514
515 /*******************************************************************************
516  *
517  * FUNCTION:    acpi_ex_store_object_to_node
518  *
519  * PARAMETERS:  source_desc             - Value to be stored
520  *              Node                    - Named object to receive the value
521  *              walk_state              - Current walk state
522  *              implicit_conversion     - Perform implicit conversion (yes/no)
523  *
524  * RETURN:      Status
525  *
526  * DESCRIPTION: Store the object to the named object.
527  *
528  *              The Assignment of an object to a named object is handled here
529  *              The value passed in will replace the current value (if any)
530  *              with the input value.
531  *
532  *              When storing into an object the data is converted to the
533  *              target object type then stored in the object.  This means
534  *              that the target object type (for an initialized target) will
535  *              not be changed by a store operation.
536  *
537  *              Assumes parameters are already validated.
538  *
539  ******************************************************************************/
540
541 acpi_status
542 acpi_ex_store_object_to_node (
543         union acpi_operand_object       *source_desc,
544         struct acpi_namespace_node      *node,
545         struct acpi_walk_state          *walk_state,
546         u8                              implicit_conversion)
547 {
548         acpi_status                     status = AE_OK;
549         union acpi_operand_object       *target_desc;
550         union acpi_operand_object       *new_desc;
551         acpi_object_type                target_type;
552
553
554         ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_node", source_desc);
555
556
557         /* Get current type of the node, and object attached to Node */
558
559         target_type = acpi_ns_get_type (node);
560         target_desc = acpi_ns_get_attached_object (node);
561
562         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
563                 source_desc, acpi_ut_get_object_type_name (source_desc),
564                           node, acpi_ut_get_type_name (target_type)));
565
566         /*
567          * Resolve the source object to an actual value
568          * (If it is a reference object)
569          */
570         status = acpi_ex_resolve_object (&source_desc, target_type, walk_state);
571         if (ACPI_FAILURE (status)) {
572                 return_ACPI_STATUS (status);
573         }
574
575         /* If no implicit conversion, drop into the default case below */
576
577         if (!implicit_conversion) {
578                 /* Force execution of default (no implicit conversion) */
579
580                 target_type = ACPI_TYPE_ANY;
581         }
582
583         /* Do the actual store operation */
584
585         switch (target_type) {
586         case ACPI_TYPE_BUFFER_FIELD:
587         case ACPI_TYPE_LOCAL_REGION_FIELD:
588         case ACPI_TYPE_LOCAL_BANK_FIELD:
589         case ACPI_TYPE_LOCAL_INDEX_FIELD:
590
591                 /* For fields, copy the source data to the target field. */
592
593                 status = acpi_ex_write_data_to_field (source_desc, target_desc,
594                                  &walk_state->result_obj);
595                 break;
596
597
598         case ACPI_TYPE_INTEGER:
599         case ACPI_TYPE_STRING:
600         case ACPI_TYPE_BUFFER:
601
602                 /*
603                  * These target types are all of type Integer/String/Buffer, and
604                  * therefore support implicit conversion before the store.
605                  *
606                  * Copy and/or convert the source object to a new target object
607                  */
608                 status = acpi_ex_store_object_to_object (source_desc, target_desc,
609                                  &new_desc, walk_state);
610                 if (ACPI_FAILURE (status)) {
611                         return_ACPI_STATUS (status);
612                 }
613
614                 if (new_desc != target_desc) {
615                         /*
616                          * Store the new new_desc as the new value of the Name, and set
617                          * the Name's type to that of the value being stored in it.
618                          * source_desc reference count is incremented by attach_object.
619                          *
620                          * Note: This may change the type of the node if an explicit store
621                          * has been performed such that the node/object type has been
622                          * changed.
623                          */
624                         status = acpi_ns_attach_object (node, new_desc, new_desc->common.type);
625
626                         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
627                                 "Store %s into %s via Convert/Attach\n",
628                                 acpi_ut_get_object_type_name (source_desc),
629                                 acpi_ut_get_object_type_name (new_desc)));
630                 }
631                 break;
632
633
634         default:
635
636                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
637                         "Storing %s (%p) directly into node (%p), no implicit conversion\n",
638                         acpi_ut_get_object_type_name (source_desc), source_desc, node));
639
640                 /* No conversions for all other types.  Just attach the source object */
641
642                 status = acpi_ns_attach_object (node, source_desc,
643                                  ACPI_GET_OBJECT_TYPE (source_desc));
644                 break;
645         }
646
647         return_ACPI_STATUS (status);
648 }
649
650