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