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