Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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