Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / acpi / executer / exoparg1.c
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
92 acpi_status
93 acpi_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
127 cleanup:
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
156 acpi_status
157 acpi_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
231 acpi_status
232 acpi_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
259 cleanup:
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
278 acpi_status
279 acpi_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
578 cleanup:
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
606 acpi_status
607 acpi_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
1002 cleanup:
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