]> err.no Git - linux-2.6/blob - drivers/acpi/executer/exoparg1.c
ffc61ddeb659e9c7b6eec4cc2fdd196d4aecba13
[linux-2.6] / 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",
101                 acpi_ps_get_opcode_name (walk_state->opcode));
102
103
104         /* Examine the AML opcode */
105
106         switch (walk_state->opcode) {
107         case AML_TIMER_OP:      /*  Timer () */
108
109                 /* Create a return object of type Integer */
110
111                 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
112                 if (!return_desc) {
113                         status = AE_NO_MEMORY;
114                         goto cleanup;
115                 }
116
117                 return_desc->integer.value = acpi_os_get_timer ();
118                 break;
119
120         default:                /*  Unknown opcode  */
121
122                 ACPI_REPORT_ERROR (("acpi_ex_opcode_0A_0T_1R: Unknown opcode %X\n",
123                         walk_state->opcode));
124                 status = AE_AML_BAD_OPCODE;
125                 break;
126         }
127
128 cleanup:
129
130         /* Delete return object on error */
131
132         if ((ACPI_FAILURE (status)) || walk_state->result_obj) {
133                 acpi_ut_remove_reference (return_desc);
134         }
135         else {
136                 /* Save the return value */
137
138                 walk_state->result_obj = return_desc;
139         }
140
141         return_ACPI_STATUS (status);
142 }
143
144
145 /*******************************************************************************
146  *
147  * FUNCTION:    acpi_ex_opcode_1A_0T_0R
148  *
149  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
150  *
151  * RETURN:      Status
152  *
153  * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
154  *              object stack
155  *
156  ******************************************************************************/
157
158 acpi_status
159 acpi_ex_opcode_1A_0T_0R (
160         struct acpi_walk_state          *walk_state)
161 {
162         union acpi_operand_object       **operand = &walk_state->operands[0];
163         acpi_status                     status = AE_OK;
164
165
166         ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R",
167                 acpi_ps_get_opcode_name (walk_state->opcode));
168
169
170         /* Examine the AML opcode */
171
172         switch (walk_state->opcode) {
173         case AML_RELEASE_OP:    /*  Release (mutex_object) */
174
175                 status = acpi_ex_release_mutex (operand[0], walk_state);
176                 break;
177
178
179         case AML_RESET_OP:      /*  Reset (event_object) */
180
181                 status = acpi_ex_system_reset_event (operand[0]);
182                 break;
183
184
185         case AML_SIGNAL_OP:     /*  Signal (event_object) */
186
187                 status = acpi_ex_system_signal_event (operand[0]);
188                 break;
189
190
191         case AML_SLEEP_OP:      /*  Sleep (msec_time) */
192
193                 status = acpi_ex_system_do_suspend (operand[0]->integer.value);
194                 break;
195
196
197         case AML_STALL_OP:      /*  Stall (usec_time) */
198
199                 status = acpi_ex_system_do_stall ((u32) operand[0]->integer.value);
200                 break;
201
202
203         case AML_UNLOAD_OP:     /*  Unload (Handle) */
204
205                 status = acpi_ex_unload_table (operand[0]);
206                 break;
207
208
209         default:                /*  Unknown opcode  */
210
211                 ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n",
212                         walk_state->opcode));
213                 status = AE_AML_BAD_OPCODE;
214                 break;
215         }
216
217         return_ACPI_STATUS (status);
218 }
219
220
221 /*******************************************************************************
222  *
223  * FUNCTION:    acpi_ex_opcode_1A_1T_0R
224  *
225  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
226  *
227  * RETURN:      Status
228  *
229  * DESCRIPTION: Execute opcode with one argument, one target, and no
230  *              return value.
231  *
232  ******************************************************************************/
233
234 acpi_status
235 acpi_ex_opcode_1A_1T_0R (
236         struct acpi_walk_state          *walk_state)
237 {
238         acpi_status                     status = AE_OK;
239         union acpi_operand_object       **operand = &walk_state->operands[0];
240
241
242         ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R",
243                 acpi_ps_get_opcode_name (walk_state->opcode));
244
245
246         /* Examine the AML opcode */
247
248         switch (walk_state->opcode) {
249         case AML_LOAD_OP:
250
251                 status = acpi_ex_load_op (operand[0], operand[1], walk_state);
252                 break;
253
254         default:                        /* Unknown opcode */
255
256                 ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n",
257                         walk_state->opcode));
258                 status = AE_AML_BAD_OPCODE;
259                 goto cleanup;
260         }
261
262
263 cleanup:
264
265         return_ACPI_STATUS (status);
266 }
267
268
269 /*******************************************************************************
270  *
271  * FUNCTION:    acpi_ex_opcode_1A_1T_1R
272  *
273  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
274  *
275  * RETURN:      Status
276  *
277  * DESCRIPTION: Execute opcode with one argument, one target, and a
278  *              return value.
279  *
280  ******************************************************************************/
281
282 acpi_status
283 acpi_ex_opcode_1A_1T_1R (
284         struct acpi_walk_state          *walk_state)
285 {
286         acpi_status                     status = AE_OK;
287         union acpi_operand_object       **operand = &walk_state->operands[0];
288         union acpi_operand_object       *return_desc = NULL;
289         union acpi_operand_object       *return_desc2 = NULL;
290         u32                             temp32;
291         u32                             i;
292         acpi_integer                    power_of_ten;
293         acpi_integer                    digit;
294
295
296         ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R",
297                 acpi_ps_get_opcode_name (walk_state->opcode));
298
299
300         /* Examine the AML opcode */
301
302         switch (walk_state->opcode) {
303         case AML_BIT_NOT_OP:
304         case AML_FIND_SET_LEFT_BIT_OP:
305         case AML_FIND_SET_RIGHT_BIT_OP:
306         case AML_FROM_BCD_OP:
307         case AML_TO_BCD_OP:
308         case AML_COND_REF_OF_OP:
309
310                 /* Create a return object of type Integer for these opcodes */
311
312                 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
313                 if (!return_desc) {
314                         status = AE_NO_MEMORY;
315                         goto cleanup;
316                 }
317
318                 switch (walk_state->opcode) {
319                 case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
320
321                         return_desc->integer.value = ~operand[0]->integer.value;
322                         break;
323
324
325                 case AML_FIND_SET_LEFT_BIT_OP:  /* find_set_left_bit (Operand, Result) */
326
327                         return_desc->integer.value = operand[0]->integer.value;
328
329                         /*
330                          * Acpi specification describes Integer type as a little
331                          * endian unsigned value, so this boundary condition is valid.
332                          */
333                         for (temp32 = 0; return_desc->integer.value &&
334                                            temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
335                                 return_desc->integer.value >>= 1;
336                         }
337
338                         return_desc->integer.value = temp32;
339                         break;
340
341
342                 case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */
343
344                         return_desc->integer.value = operand[0]->integer.value;
345
346                         /*
347                          * The Acpi specification describes Integer type as a little
348                          * endian unsigned value, so this boundary condition is valid.
349                          */
350                         for (temp32 = 0; return_desc->integer.value &&
351                                            temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
352                                 return_desc->integer.value <<= 1;
353                         }
354
355                         /* Since the bit position is one-based, subtract from 33 (65) */
356
357                         return_desc->integer.value = temp32 == 0 ? 0 :
358                                           (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
359                         break;
360
361
362                 case AML_FROM_BCD_OP:           /* from_bcd (BCDValue, Result) */
363
364                         /*
365                          * The 64-bit ACPI integer can hold 16 4-bit BCD characters
366                          * (if table is 32-bit, integer can hold 8 BCD characters)
367                          * Convert each 4-bit BCD value
368                          */
369                         power_of_ten = 1;
370                         return_desc->integer.value = 0;
371                         digit = operand[0]->integer.value;
372
373                         /* Convert each BCD digit (each is one nybble wide) */
374
375                         for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
376                                 /* Get the least significant 4-bit BCD digit */
377
378                                 temp32 = ((u32) digit) & 0xF;
379
380                                 /* Check the range of the digit */
381
382                                 if (temp32 > 9) {
383                                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
384                                                 "BCD digit too large (not decimal): 0x%X\n",
385                                                 temp32));
386
387                                         status = AE_AML_NUMERIC_OVERFLOW;
388                                         goto cleanup;
389                                 }
390
391                                 /* Sum the digit into the result with the current power of 10 */
392
393                                 return_desc->integer.value += (((acpi_integer) temp32) *
394                                                  power_of_ten);
395
396                                 /* Shift to next BCD digit */
397
398                                 digit >>= 4;
399
400                                 /* Next power of 10 */
401
402                                 power_of_ten *= 10;
403                         }
404                         break;
405
406
407                 case AML_TO_BCD_OP:             /* to_bcd (Operand, Result) */
408
409                         return_desc->integer.value = 0;
410                         digit = operand[0]->integer.value;
411
412                         /* Each BCD digit is one nybble wide */
413
414                         for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
415                                 (void) acpi_ut_short_divide (digit, 10, &digit, &temp32);
416
417                                 /*
418                                  * Insert the BCD digit that resides in the
419                                  * remainder from above
420                                  */
421                                 return_desc->integer.value |= (((acpi_integer) temp32) <<
422                                                    ACPI_MUL_4 (i));
423                         }
424
425                         /* Overflow if there is any data left in Digit */
426
427                         if (digit > 0) {
428                                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
429                                         "Integer too large to convert to BCD: %8.8X%8.8X\n",
430                                         ACPI_FORMAT_UINT64 (operand[0]->integer.value)));
431                                 status = AE_AML_NUMERIC_OVERFLOW;
432                                 goto cleanup;
433                         }
434                         break;
435
436
437                 case AML_COND_REF_OF_OP:        /* cond_ref_of (source_object, Result) */
438
439                         /*
440                          * This op is a little strange because the internal return value is
441                          * different than the return value stored in the result descriptor
442                          * (There are really two return values)
443                          */
444                         if ((struct acpi_namespace_node *) operand[0] == acpi_gbl_root_node) {
445                                 /*
446                                  * This means that the object does not exist in the namespace,
447                                  * return FALSE
448                                  */
449                                 return_desc->integer.value = 0;
450                                 goto cleanup;
451                         }
452
453                         /* Get the object reference, store it, and remove our reference */
454
455                         status = acpi_ex_get_object_reference (operand[0],
456                                          &return_desc2, walk_state);
457                         if (ACPI_FAILURE (status)) {
458                                 goto cleanup;
459                         }
460
461                         status = acpi_ex_store (return_desc2, operand[1], walk_state);
462                         acpi_ut_remove_reference (return_desc2);
463
464                         /* The object exists in the namespace, return TRUE */
465
466                         return_desc->integer.value = ACPI_INTEGER_MAX;
467                         goto cleanup;
468
469
470                 default:
471                         /* No other opcodes get here */
472                         break;
473                 }
474                 break;
475
476
477         case AML_STORE_OP:              /* Store (Source, Target) */
478
479                 /*
480                  * A store operand is typically a number, string, buffer or lvalue
481                  * Be careful about deleting the source object,
482                  * since the object itself may have been stored.
483                  */
484                 status = acpi_ex_store (operand[0], operand[1], walk_state);
485                 if (ACPI_FAILURE (status)) {
486                         return_ACPI_STATUS (status);
487                 }
488
489                 /* It is possible that the Store already produced a return object */
490
491                 if (!walk_state->result_obj) {
492                         /*
493                          * Normally, we would remove a reference on the Operand[0]
494                          * parameter; But since it is being used as the internal return
495                          * object (meaning we would normally increment it), the two
496                          * cancel out, and we simply don't do anything.
497                          */
498                         walk_state->result_obj = operand[0];
499                         walk_state->operands[0] = NULL; /* Prevent deletion */
500                 }
501                 return_ACPI_STATUS (status);
502
503
504         /*
505          * ACPI 2.0 Opcodes
506          */
507         case AML_COPY_OP:               /* Copy (Source, Target) */
508
509                 status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc,
510                                  walk_state);
511                 break;
512
513
514         case AML_TO_DECSTRING_OP:       /* to_decimal_string (Data, Result) */
515
516                 status = acpi_ex_convert_to_string (operand[0], &return_desc,
517                                  ACPI_EXPLICIT_CONVERT_DECIMAL);
518                 if (return_desc == operand[0]) {
519                         /* No conversion performed, add ref to handle return value */
520                         acpi_ut_add_reference (return_desc);
521                 }
522                 break;
523
524
525         case AML_TO_HEXSTRING_OP:       /* to_hex_string (Data, Result) */
526
527                 status = acpi_ex_convert_to_string (operand[0], &return_desc,
528                                  ACPI_EXPLICIT_CONVERT_HEX);
529                 if (return_desc == operand[0]) {
530                         /* No conversion performed, add ref to handle return value */
531                         acpi_ut_add_reference (return_desc);
532                 }
533                 break;
534
535
536         case AML_TO_BUFFER_OP:          /* to_buffer (Data, Result) */
537
538                 status = acpi_ex_convert_to_buffer (operand[0], &return_desc);
539                 if (return_desc == operand[0]) {
540                         /* No conversion performed, add ref to handle return value */
541                         acpi_ut_add_reference (return_desc);
542                 }
543                 break;
544
545
546         case AML_TO_INTEGER_OP:         /* to_integer (Data, Result) */
547
548                 status = acpi_ex_convert_to_integer (operand[0], &return_desc,
549                                  ACPI_ANY_BASE);
550                 if (return_desc == operand[0]) {
551                         /* No conversion performed, add ref to handle return value */
552                         acpi_ut_add_reference (return_desc);
553                 }
554                 break;
555
556
557         case AML_SHIFT_LEFT_BIT_OP:     /* shift_left_bit (Source, bit_num) */
558         case AML_SHIFT_RIGHT_BIT_OP:    /* shift_right_bit (Source, bit_num) */
559
560                 /* These are two obsolete opcodes */
561
562                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
563                         "%s is obsolete and not implemented\n",
564                         acpi_ps_get_opcode_name (walk_state->opcode)));
565                 status = AE_SUPPORT;
566                 goto cleanup;
567
568
569         default:                        /* Unknown opcode */
570
571                 ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n",
572                         walk_state->opcode));
573                 status = AE_AML_BAD_OPCODE;
574                 goto cleanup;
575         }
576
577         if (ACPI_SUCCESS (status)) {
578                 /* Store the return value computed above into the target object */
579
580                 status = acpi_ex_store (return_desc, operand[1], walk_state);
581         }
582
583
584 cleanup:
585
586         if (!walk_state->result_obj) {
587                 walk_state->result_obj = return_desc;
588         }
589
590         /* Delete return object on error */
591
592         if (ACPI_FAILURE (status)) {
593                 acpi_ut_remove_reference (return_desc);
594         }
595
596         return_ACPI_STATUS (status);
597 }
598
599
600 /*******************************************************************************
601  *
602  * FUNCTION:    acpi_ex_opcode_1A_0T_1R
603  *
604  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
605  *
606  * RETURN:      Status
607  *
608  * DESCRIPTION: Execute opcode with one argument, no target, and a return value
609  *
610  ******************************************************************************/
611
612 acpi_status
613 acpi_ex_opcode_1A_0T_1R (
614         struct acpi_walk_state          *walk_state)
615 {
616         union acpi_operand_object       **operand = &walk_state->operands[0];
617         union acpi_operand_object       *temp_desc;
618         union acpi_operand_object       *return_desc = NULL;
619         acpi_status                     status = AE_OK;
620         u32                             type;
621         acpi_integer                    value;
622
623
624         ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R",
625                 acpi_ps_get_opcode_name (walk_state->opcode));
626
627
628         /* Examine the AML opcode */
629
630         switch (walk_state->opcode) {
631         case AML_LNOT_OP:               /* LNot (Operand) */
632
633                 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
634                 if (!return_desc) {
635                         status = AE_NO_MEMORY;
636                         goto cleanup;
637                 }
638
639                 /*
640                  * Set result to ONES (TRUE) if Value == 0.  Note:
641                  * return_desc->Integer.Value is initially == 0 (FALSE) from above.
642                  */
643                 if (!operand[0]->integer.value) {
644                         return_desc->integer.value = ACPI_INTEGER_MAX;
645                 }
646                 break;
647
648
649         case AML_DECREMENT_OP:          /* Decrement (Operand)  */
650         case AML_INCREMENT_OP:          /* Increment (Operand)  */
651
652                 /*
653                  * Create a new integer.  Can't just get the base integer and
654                  * increment it because it may be an Arg or Field.
655                  */
656                 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
657                 if (!return_desc) {
658                         status = AE_NO_MEMORY;
659                         goto cleanup;
660                 }
661
662                 /*
663                  * Since we are expecting a Reference operand, it can be either a
664                  * NS Node or an internal object.
665                  */
666                 temp_desc = operand[0];
667                 if (ACPI_GET_DESCRIPTOR_TYPE (temp_desc) == ACPI_DESC_TYPE_OPERAND) {
668                         /* Internal reference object - prevent deletion */
669
670                         acpi_ut_add_reference (temp_desc);
671                 }
672
673                 /*
674                  * Convert the Reference operand to an Integer (This removes a
675                  * reference on the Operand[0] object)
676                  *
677                  * NOTE:  We use LNOT_OP here in order to force resolution of the
678                  * reference operand to an actual integer.
679                  */
680                 status = acpi_ex_resolve_operands (AML_LNOT_OP, &temp_desc, walk_state);
681                 if (ACPI_FAILURE (status)) {
682                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n",
683                                 acpi_ps_get_opcode_name (walk_state->opcode),
684                                 acpi_format_exception(status)));
685
686                         goto cleanup;
687                 }
688
689                 /*
690                  * temp_desc is now guaranteed to be an Integer object --
691                  * Perform the actual increment or decrement
692                  */
693                 if (walk_state->opcode == AML_INCREMENT_OP) {
694                         return_desc->integer.value = temp_desc->integer.value +1;
695                 }
696                 else {
697                         return_desc->integer.value = temp_desc->integer.value -1;
698                 }
699
700                 /* Finished with this Integer object */
701
702                 acpi_ut_remove_reference (temp_desc);
703
704                 /*
705                  * Store the result back (indirectly) through the original
706                  * Reference object
707                  */
708                 status = acpi_ex_store (return_desc, operand[0], walk_state);
709                 break;
710
711
712         case AML_TYPE_OP:               /* object_type (source_object) */
713
714                 /*
715                  * Note: The operand is not resolved at this point because we want to
716                  * get the associated object, not its value.  For example, we don't
717                  * want to resolve a field_unit to its value, we want the actual
718                  * field_unit object.
719                  */
720
721                 /* Get the type of the base object */
722
723                 status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, NULL);
724                 if (ACPI_FAILURE (status)) {
725                         goto cleanup;
726                 }
727                 /* Allocate a descriptor to hold the type. */
728
729                 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
730                 if (!return_desc) {
731                         status = AE_NO_MEMORY;
732                         goto cleanup;
733                 }
734
735                 return_desc->integer.value = type;
736                 break;
737
738
739         case AML_SIZE_OF_OP:            /* size_of (source_object) */
740
741                 /*
742                  * Note: The operand is not resolved at this point because we want to
743                  * get the associated object, not its value.
744                  */
745
746                 /* Get the base object */
747
748                 status = acpi_ex_resolve_multiple (walk_state,
749                                  operand[0], &type, &temp_desc);
750                 if (ACPI_FAILURE (status)) {
751                         goto cleanup;
752                 }
753
754                 /*
755                  * The type of the base object must be integer, buffer, string, or
756                  * package.  All others are not supported.
757                  *
758                  * NOTE: Integer is not specifically supported by the ACPI spec,
759                  * but is supported implicitly via implicit operand conversion.
760                  * rather than bother with conversion, we just use the byte width
761                  * global (4 or 8 bytes).
762                  */
763                 switch (type) {
764                 case ACPI_TYPE_INTEGER:
765                         value = acpi_gbl_integer_byte_width;
766                         break;
767
768                 case ACPI_TYPE_BUFFER:
769                         value = temp_desc->buffer.length;
770                         break;
771
772                 case ACPI_TYPE_STRING:
773                         value = temp_desc->string.length;
774                         break;
775
776                 case ACPI_TYPE_PACKAGE:
777                         value = temp_desc->package.count;
778                         break;
779
780                 default:
781                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
782                                 "size_of - Operand is not Buf/Int/Str/Pkg - found type %s\n",
783                                 acpi_ut_get_type_name (type)));
784                         status = AE_AML_OPERAND_TYPE;
785                         goto cleanup;
786                 }
787
788                 /*
789                  * Now that we have the size of the object, create a result
790                  * object to hold the value
791                  */
792                 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
793                 if (!return_desc) {
794                         status = AE_NO_MEMORY;
795                         goto cleanup;
796                 }
797
798                 return_desc->integer.value = value;
799                 break;
800
801
802         case AML_REF_OF_OP:             /* ref_of (source_object) */
803
804                 status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state);
805                 if (ACPI_FAILURE (status)) {
806                         goto cleanup;
807                 }
808                 break;
809
810
811         case AML_DEREF_OF_OP:           /* deref_of (obj_reference | String) */
812
813                 /* Check for a method local or argument, or standalone String */
814
815                 if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) != ACPI_DESC_TYPE_NAMED) {
816                         switch (ACPI_GET_OBJECT_TYPE (operand[0])) {
817                         case ACPI_TYPE_LOCAL_REFERENCE:
818                                 /*
819                                  * This is a deref_of (local_x | arg_x)
820                                  *
821                                  * Must resolve/dereference the local/arg reference first
822                                  */
823                                 switch (operand[0]->reference.opcode) {
824                                 case AML_LOCAL_OP:
825                                 case AML_ARG_OP:
826
827                                         /* Set Operand[0] to the value of the local/arg */
828
829                                         status = acpi_ds_method_data_get_value (
830                                                          operand[0]->reference.opcode,
831                                                          operand[0]->reference.offset,
832                                                          walk_state, &temp_desc);
833                                         if (ACPI_FAILURE (status)) {
834                                                 goto cleanup;
835                                         }
836
837                                         /*
838                                          * Delete our reference to the input object and
839                                          * point to the object just retrieved
840                                          */
841                                         acpi_ut_remove_reference (operand[0]);
842                                         operand[0] = temp_desc;
843                                         break;
844
845                                 case AML_REF_OF_OP:
846
847                                         /* Get the object to which the reference refers */
848
849                                         temp_desc = operand[0]->reference.object;
850                                         acpi_ut_remove_reference (operand[0]);
851                                         operand[0] = temp_desc;
852                                         break;
853
854                                 default:
855
856                                         /* Must be an Index op - handled below */
857                                         break;
858                                 }
859                                 break;
860
861
862                         case ACPI_TYPE_STRING:
863
864                                 /*
865                                  * This is a deref_of (String). The string is a reference
866                                  * to a named ACPI object.
867                                  *
868                                  * 1) Find the owning Node
869                                  * 2) Dereference the node to an actual object.  Could be a
870                                  *    Field, so we need to resolve the node to a value.
871                                  */
872                                 status = acpi_ns_get_node_by_path (operand[0]->string.pointer,
873                                                  walk_state->scope_info->scope.node,
874                                                  ACPI_NS_SEARCH_PARENT,
875                                                  ACPI_CAST_INDIRECT_PTR (
876                                                                 struct acpi_namespace_node, &return_desc));
877                                 if (ACPI_FAILURE (status)) {
878                                         goto cleanup;
879                                 }
880
881                                 status = acpi_ex_resolve_node_to_value (
882                                                   ACPI_CAST_INDIRECT_PTR (
883                                                                  struct acpi_namespace_node, &return_desc),
884                                                                 walk_state);
885                                 goto cleanup;
886
887
888                         default:
889
890                                 status = AE_AML_OPERAND_TYPE;
891                                 goto cleanup;
892                         }
893                 }
894
895                 /* Operand[0] may have changed from the code above */
896
897                 if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_NAMED) {
898                         /*
899                          * This is a deref_of (object_reference)
900                          * Get the actual object from the Node (This is the dereference).
901                          * This case may only happen when a local_x or arg_x is
902                          * dereferenced above.
903                          */
904                         return_desc = acpi_ns_get_attached_object (
905                                           (struct acpi_namespace_node *) operand[0]);
906                 }
907                 else {
908                         /*
909                          * This must be a reference object produced by either the
910                          * Index() or ref_of() operator
911                          */
912                         switch (operand[0]->reference.opcode) {
913                         case AML_INDEX_OP:
914
915                                 /*
916                                  * The target type for the Index operator must be
917                                  * either a Buffer or a Package
918                                  */
919                                 switch (operand[0]->reference.target_type) {
920                                 case ACPI_TYPE_BUFFER_FIELD:
921
922                                         temp_desc = operand[0]->reference.object;
923
924                                         /*
925                                          * Create a new object that contains one element of the
926                                          * buffer -- the element pointed to by the index.
927                                          *
928                                          * NOTE: index into a buffer is NOT a pointer to a
929                                          * sub-buffer of the main buffer, it is only a pointer to a
930                                          * single element (byte) of the buffer!
931                                          */
932                                         return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
933                                         if (!return_desc) {
934                                                 status = AE_NO_MEMORY;
935                                                 goto cleanup;
936                                         }
937
938                                         /*
939                                          * Since we are returning the value of the buffer at the
940                                          * indexed location, we don't need to add an additional
941                                          * reference to the buffer itself.
942                                          */
943                                         return_desc->integer.value =
944                                                 temp_desc->buffer.pointer[operand[0]->reference.offset];
945                                         break;
946
947
948                                 case ACPI_TYPE_PACKAGE:
949
950                                         /*
951                                          * Return the referenced element of the package.  We must
952                                          * add another reference to the referenced object, however.
953                                          */
954                                         return_desc = *(operand[0]->reference.where);
955                                         if (!return_desc) {
956                                                 /*
957                                                  * We can't return a NULL dereferenced value.  This is
958                                                  * an uninitialized package element and is thus a
959                                                  * severe error.
960                                                  */
961                                                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
962                                                         "NULL package element obj %p\n",
963                                                         operand[0]));
964                                                 status = AE_AML_UNINITIALIZED_ELEMENT;
965                                                 goto cleanup;
966                                         }
967
968                                         acpi_ut_add_reference (return_desc);
969                                         break;
970
971
972                                 default:
973
974                                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
975                                                 "Unknown Index target_type %X in obj %p\n",
976                                                 operand[0]->reference.target_type, operand[0]));
977                                         status = AE_AML_OPERAND_TYPE;
978                                         goto cleanup;
979                                 }
980                                 break;
981
982
983                         case AML_REF_OF_OP:
984
985                                 return_desc = operand[0]->reference.object;
986
987                                 if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) ==
988                                                 ACPI_DESC_TYPE_NAMED) {
989
990                                         return_desc = acpi_ns_get_attached_object (
991                                                           (struct acpi_namespace_node *) return_desc);
992                                 }
993
994                                 /* Add another reference to the object! */
995
996                                 acpi_ut_add_reference (return_desc);
997                                 break;
998
999
1000                         default:
1001                                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
1002                                         "Unknown opcode in ref(%p) - %X\n",
1003                                         operand[0], operand[0]->reference.opcode));
1004
1005                                 status = AE_TYPE;
1006                                 goto cleanup;
1007                         }
1008                 }
1009                 break;
1010
1011
1012         default:
1013
1014                 ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n",
1015                         walk_state->opcode));
1016                 status = AE_AML_BAD_OPCODE;
1017                 goto cleanup;
1018         }
1019
1020
1021 cleanup:
1022
1023         /* Delete return object on error */
1024
1025         if (ACPI_FAILURE (status)) {
1026                 acpi_ut_remove_reference (return_desc);
1027         }
1028
1029         walk_state->result_obj = return_desc;
1030         return_ACPI_STATUS (status);
1031 }
1032