File: /usr/src/linux/drivers/acpi/executer/exmonad.c

1     
2     /******************************************************************************
3      *
4      * Module Name: exmonad - ACPI AML execution for monadic (1 operand) operators
5      *              $Revision: 111 $
6      *
7      *****************************************************************************/
8     
9     /*
10      *  Copyright (C) 2000, 2001 R. Byron Moore
11      *
12      *  This program is free software; you can redistribute it and/or modify
13      *  it under the terms of the GNU General Public License as published by
14      *  the Free Software Foundation; either version 2 of the License, or
15      *  (at your option) any later version.
16      *
17      *  This program is distributed in the hope that it will be useful,
18      *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19      *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20      *  GNU General Public License for more details.
21      *
22      *  You should have received a copy of the GNU General Public License
23      *  along with this program; if not, write to the Free Software
24      *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25      */
26     
27     
28     #include "acpi.h"
29     #include "acparser.h"
30     #include "acdispat.h"
31     #include "acinterp.h"
32     #include "amlcode.h"
33     #include "acnamesp.h"
34     
35     
36     #define _COMPONENT          ACPI_EXECUTER
37     	 MODULE_NAME         ("exmonad")
38     
39     
40     /*******************************************************************************
41      *
42      * FUNCTION:    Acpi_ex_get_object_reference
43      *
44      * PARAMETERS:  Obj_desc        - Create a reference to this object
45      *              Ret_desc        - Where to store the reference
46      *
47      * RETURN:      Status
48      *
49      * DESCRIPTION: Obtain and return a "reference" to the target object
50      *              Common code for the Ref_of_op and the Cond_ref_of_op.
51      *
52      ******************************************************************************/
53     
54     static acpi_status
55     acpi_ex_get_object_reference (
56     	acpi_operand_object     *obj_desc,
57     	acpi_operand_object     **ret_desc,
58     	acpi_walk_state         *walk_state)
59     {
60     	acpi_status             status = AE_OK;
61     
62     
63     	FUNCTION_TRACE_PTR ("Ex_get_object_reference", obj_desc);
64     
65     
66     	if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
67     		if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) {
68     			*ret_desc = NULL;
69     			status = AE_TYPE;
70     			goto cleanup;
71     		}
72     
73     		/*
74     		 * Not a Name -- an indirect name pointer would have
75     		 * been converted to a direct name pointer in Acpi_ex_resolve_operands
76     		 */
77     		switch (obj_desc->reference.opcode) {
78     		case AML_LOCAL_OP:
79     		case AML_ARG_OP:
80     
81     			*ret_desc = (void *) acpi_ds_method_data_get_node (obj_desc->reference.opcode,
82     					  obj_desc->reference.offset, walk_state);
83     			break;
84     
85     		default:
86     
87     			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(Internal) Unknown Ref subtype %02x\n",
88     				obj_desc->reference.opcode));
89     			*ret_desc = NULL;
90     			status = AE_AML_INTERNAL;
91     			goto cleanup;
92     		}
93     
94     	}
95     
96     	else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
97     		/* Must be a named object;  Just return the Node */
98     
99     		*ret_desc = obj_desc;
100     	}
101     
102     	else {
103     		*ret_desc = NULL;
104     		status = AE_TYPE;
105     	}
106     
107     
108     cleanup:
109     
110     	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p Ref=%p\n", obj_desc, *ret_desc));
111     	return_ACPI_STATUS (status);
112     }
113     
114     #define obj_desc            operand[0]
115     #define res_desc            operand[1]
116     
117     
118     /*******************************************************************************
119      *
120      * FUNCTION:    Acpi_ex_monadic1
121      *
122      * PARAMETERS:  Opcode              - The opcode to be executed
123      *
124      * RETURN:      Status
125      *
126      * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
127      *              object stack
128      *
129      ******************************************************************************/
130     
131     acpi_status
132     acpi_ex_monadic1 (
133     	u16                     opcode,
134     	acpi_walk_state         *walk_state)
135     {
136     	acpi_operand_object     **operand = &walk_state->operands[0];
137     	acpi_status             status;
138     
139     
140     	FUNCTION_TRACE_PTR ("Ex_monadic1", WALK_OPERANDS);
141     
142     
143     	/* Examine the opcode */
144     
145     	switch (opcode) {
146     
147     	/*  Def_release :=  Release_op  Mutex_object */
148     
149     	case AML_RELEASE_OP:
150     
151     		status = acpi_ex_release_mutex (obj_desc, walk_state);
152     		break;
153     
154     
155     	/*  Def_reset   :=  Reset_op    Acpi_event_object */
156     
157     	case AML_RESET_OP:
158     
159     		status = acpi_ex_system_reset_event (obj_desc);
160     		break;
161     
162     
163     	/*  Def_signal  :=  Signal_op   Acpi_event_object */
164     
165     	case AML_SIGNAL_OP:
166     
167     		status = acpi_ex_system_signal_event (obj_desc);
168     		break;
169     
170     
171     	/*  Def_sleep   :=  Sleep_op    Msec_time   */
172     
173     	case AML_SLEEP_OP:
174     
175     		acpi_ex_system_do_suspend ((u32) obj_desc->integer.value);
176     		break;
177     
178     
179     	/*  Def_stall   :=  Stall_op    Usec_time   */
180     
181     	case AML_STALL_OP:
182     
183     		acpi_ex_system_do_stall ((u32) obj_desc->integer.value);
184     		break;
185     
186     
187     	/*  Unknown opcode  */
188     
189     	default:
190     
191     		REPORT_ERROR (("Acpi_ex_monadic1: Unknown monadic opcode %X\n",
192     			opcode));
193     		status = AE_AML_BAD_OPCODE;
194     		break;
195     
196     	} /* switch */
197     
198     
199     	/* Always delete the operand */
200     
201     	acpi_ut_remove_reference (obj_desc);
202     
203     	return_ACPI_STATUS (AE_OK);
204     }
205     
206     
207     /*******************************************************************************
208      *
209      * FUNCTION:    Acpi_ex_monadic2_r
210      *
211      * PARAMETERS:  Opcode              - The opcode to be executed
212      *
213      * RETURN:      Status
214      *
215      * DESCRIPTION: Execute Type 2 monadic operator with numeric operand and
216      *              result operand on operand stack
217      *
218      ******************************************************************************/
219     
220     acpi_status
221     acpi_ex_monadic2_r (
222     	u16                     opcode,
223     	acpi_walk_state         *walk_state,
224     	acpi_operand_object     **return_desc)
225     {
226     	acpi_operand_object     **operand = &walk_state->operands[0];
227     	acpi_operand_object     *ret_desc = NULL;
228     	acpi_operand_object     *ret_desc2 = NULL;
229     	u32                     res_val;
230     	acpi_status             status = AE_OK;
231     	u32                     i;
232     	u32                     j;
233     	acpi_integer            digit;
234     
235     
236     	FUNCTION_TRACE_PTR ("Ex_monadic2_r", WALK_OPERANDS);
237     
238     
239     	/* Create a return object of type NUMBER for most opcodes */
240     
241     	switch (opcode) {
242     	case AML_BIT_NOT_OP:
243     	case AML_FIND_SET_LEFT_BIT_OP:
244     	case AML_FIND_SET_RIGHT_BIT_OP:
245     	case AML_FROM_BCD_OP:
246     	case AML_TO_BCD_OP:
247     	case AML_COND_REF_OF_OP:
248     
249     		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
250     		if (!ret_desc) {
251     			status = AE_NO_MEMORY;
252     			goto cleanup;
253     		}
254     
255     		break;
256     	}
257     
258     
259     	switch (opcode) {
260     	/*  Def_not :=  Not_op  Operand Result  */
261     
262     	case AML_BIT_NOT_OP:
263     
264     		ret_desc->integer.value = ~obj_desc->integer.value;
265     		break;
266     
267     
268     	/*  Def_find_set_left_bit := Find_set_left_bit_op Operand Result */
269     
270     	case AML_FIND_SET_LEFT_BIT_OP:
271     
272     		ret_desc->integer.value = obj_desc->integer.value;
273     
274     		/*
275     		 * Acpi specification describes Integer type as a little
276     		 * endian unsigned value, so this boundary condition is valid.
277     		 */
278     		for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) {
279     			ret_desc->integer.value >>= 1;
280     		}
281     
282     		ret_desc->integer.value = res_val;
283     		break;
284     
285     
286     	/*  Def_find_set_right_bit := Find_set_right_bit_op Operand Result */
287     
288     	case AML_FIND_SET_RIGHT_BIT_OP:
289     
290     		ret_desc->integer.value = obj_desc->integer.value;
291     
292     		/*
293     		 * Acpi specification describes Integer type as a little
294     		 * endian unsigned value, so this boundary condition is valid.
295     		 */
296     		for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) {
297     			ret_desc->integer.value <<= 1;
298     		}
299     
300     		/* Since returns must be 1-based, subtract from 33 (65) */
301     
302     		ret_desc->integer.value = res_val == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - res_val;
303     		break;
304     
305     
306     	/*  Def_from_bDC := From_bCDOp  BCDValue    Result  */
307     
308     	case AML_FROM_BCD_OP:
309     
310     		/*
311     		 * The 64-bit ACPI integer can hold 16 4-bit BCD integers
312     		 */
313     		ret_desc->integer.value = 0;
314     		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
315     			/* Get one BCD digit */
316     
317     			digit = (acpi_integer) ((obj_desc->integer.value >> (i * 4)) & 0xF);
318     
319     			/* Check the range of the digit */
320     
321     			if (digit > 9) {
322     				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD digit too large: \n",
323     					digit));
324     				status = AE_AML_NUMERIC_OVERFLOW;
325     				goto cleanup;
326     			}
327     
328     			if (digit > 0) {
329     				/* Sum into the result with the appropriate power of 10 */
330     
331     				for (j = 0; j < i; j++) {
332     					digit *= 10;
333     				}
334     
335     				ret_desc->integer.value += digit;
336     			}
337     		}
338     		break;
339     
340     
341     	/*  Def_to_bDC  :=  To_bCDOp Operand Result */
342     
343     	case AML_TO_BCD_OP:
344     
345     
346     		if (obj_desc->integer.value > ACPI_MAX_BCD_VALUE) {
347     			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD overflow: %d\n",
348     				obj_desc->integer.value));
349     			status = AE_AML_NUMERIC_OVERFLOW;
350     			goto cleanup;
351     		}
352     
353     		ret_desc->integer.value = 0;
354     		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
355     			/* Divide by nth factor of 10 */
356     
357     			digit = obj_desc->integer.value;
358     			for (j = 0; j < i; j++) {
359     				digit = ACPI_DIVIDE (digit, 10);
360     			}
361     
362     			/* Create the BCD digit */
363     
364     			if (digit > 0) {
365     				ret_desc->integer.value += (ACPI_MODULO (digit, 10) << (i * 4));
366     			}
367     		}
368     		break;
369     
370     
371     	/*  Def_cond_ref_of     :=  Cond_ref_of_op  Source_object   Result  */
372     
373     	case AML_COND_REF_OF_OP:
374     
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 ((acpi_namespace_node *) obj_desc == acpi_gbl_root_node) {
381     			/*
382     			 * This means that the object does not exist in the namespace,
383     			 * return FALSE
384     			 */
385     			ret_desc->integer.value = 0;
386     
387     			/*
388     			 * Must delete the result descriptor since there is no reference
389     			 * being returned
390     			 */
391     			acpi_ut_remove_reference (res_desc);
392     			goto cleanup;
393     		}
394     
395     		/* Get the object reference and store it */
396     
397     		status = acpi_ex_get_object_reference (obj_desc, &ret_desc2, walk_state);
398     		if (ACPI_FAILURE (status)) {
399     			goto cleanup;
400     		}
401     
402     		status = acpi_ex_store (ret_desc2, res_desc, walk_state);
403     
404     		/* The object exists in the namespace, return TRUE */
405     
406     		ret_desc->integer.value = ACPI_INTEGER_MAX;
407     		goto cleanup;
408     		break;
409     
410     
411     	case AML_STORE_OP:
412     
413     		/*
414     		 * A store operand is typically a number, string, buffer or lvalue
415     		 * TBD: [Unhandled] What about a store to a package?
416     		 */
417     
418     		/*
419     		 * Do the store, and be careful about deleting the source object,
420     		 * since the object itself may have been stored.
421     		 */
422     		status = acpi_ex_store (obj_desc, res_desc, walk_state);
423     		if (ACPI_FAILURE (status)) {
424     			/* On failure, just delete the Obj_desc */
425     
426     			acpi_ut_remove_reference (obj_desc);
427     			return_ACPI_STATUS (status);
428     		}
429     
430     		/*
431     		 * Normally, we would remove a reference on the Obj_desc parameter;
432     		 * But since it is being used as the internal return object
433     		 * (meaning we would normally increment it), the two cancel out,
434     		 * and we simply don't do anything.
435     		 */
436     		*return_desc = obj_desc;
437     		return_ACPI_STATUS (status);
438     		break;
439     
440     
441     	case AML_DEBUG_OP:
442     
443     		/* Reference, returning an Reference */
444     
445     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Debug_op should never get here!\n"));
446     		return_ACPI_STATUS (AE_OK);
447     		break;
448     
449     
450     	/*
451     	 * ACPI 2.0 Opcodes
452     	 */
453     	case AML_TO_DECSTRING_OP:
454     		status = acpi_ex_convert_to_string (obj_desc, &ret_desc, 10, ACPI_UINT32_MAX, walk_state);
455     		break;
456     
457     
458     	case AML_TO_HEXSTRING_OP:
459     		status = acpi_ex_convert_to_string (obj_desc, &ret_desc, 16, ACPI_UINT32_MAX, walk_state);
460     		break;
461     
462     	case AML_TO_BUFFER_OP:
463     		status = acpi_ex_convert_to_buffer (obj_desc, &ret_desc, walk_state);
464     		break;
465     
466     	case AML_TO_INTEGER_OP:
467     		status = acpi_ex_convert_to_integer (obj_desc, &ret_desc, walk_state);
468     		break;
469     
470     
471     	/*
472     	 * These are obsolete opcodes
473     	 */
474     
475     	/*  Def_shift_left_bit  :=  Shift_left_bit_op   Source          Bit_num */
476     	/*  Def_shift_right_bit :=  Shift_right_bit_op  Source          Bit_num */
477     
478     	case AML_SHIFT_LEFT_BIT_OP:
479     	case AML_SHIFT_RIGHT_BIT_OP:
480     
481     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is unimplemented\n",
482     				  acpi_ps_get_opcode_name (opcode)));
483     		status = AE_SUPPORT;
484     		goto cleanup;
485     		break;
486     
487     
488     	default:
489     
490     		REPORT_ERROR (("Acpi_ex_monadic2_r: Unknown monadic opcode %X\n",
491     			opcode));
492     		status = AE_AML_BAD_OPCODE;
493     		goto cleanup;
494     	}
495     
496     
497     	status = acpi_ex_store (ret_desc, res_desc, walk_state);
498     
499     
500     cleanup:
501     	/* Always delete the operand object */
502     
503     	acpi_ut_remove_reference (obj_desc);
504     
505     	/* Delete return object(s) on error */
506     
507     	if (ACPI_FAILURE (status)) {
508     		acpi_ut_remove_reference (res_desc); /* Result descriptor */
509     		if (ret_desc) {
510     			acpi_ut_remove_reference (ret_desc);
511     			ret_desc = NULL;
512     		}
513     	}
514     
515     	/* Set the return object and exit */
516     
517     	*return_desc = ret_desc;
518     	return_ACPI_STATUS (status);
519     }
520     
521     
522     /*******************************************************************************
523      *
524      * FUNCTION:    Acpi_ex_monadic2
525      *
526      * PARAMETERS:  Opcode              - The opcode to be executed
527      *
528      * RETURN:      Status
529      *
530      * DESCRIPTION: Execute Type 2 monadic operator with numeric operand:
531      *              Deref_of_op, Ref_of_op, Size_of_op, Type_op, Increment_op,
532      *              Decrement_op, LNot_op,
533      *
534      ******************************************************************************/
535     
536     acpi_status
537     acpi_ex_monadic2 (
538     	u16                     opcode,
539     	acpi_walk_state         *walk_state,
540     	acpi_operand_object     **return_desc)
541     {
542     	acpi_operand_object     **operand = &walk_state->operands[0];
543     	acpi_operand_object     *tmp_desc;
544     	acpi_operand_object     *ret_desc = NULL;
545     	acpi_status             status = AE_OK;
546     	u32                     type;
547     	acpi_integer            value;
548     
549     
550     	FUNCTION_TRACE_PTR ("Ex_monadic2", WALK_OPERANDS);
551     
552     
553     	/* Get the operand and decode the opcode */
554     
555     	switch (opcode) {
556     
557     	/*  Def_lNot := LNot_op Operand */
558     
559     	case AML_LNOT_OP:
560     
561     		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
562     		if (!ret_desc) {
563     			status = AE_NO_MEMORY;
564     			goto cleanup;
565     		}
566     
567     		ret_desc->integer.value = !obj_desc->integer.value;
568     		break;
569     
570     
571     	/*  Def_decrement   :=  Decrement_op Target */
572     	/*  Def_increment   :=  Increment_op Target */
573     
574     	case AML_DECREMENT_OP:
575     	case AML_INCREMENT_OP:
576     
577     		/*
578     		 * Since we are expecting an Reference on the top of the stack, it
579     		 * can be either an Node or an internal object.
580     		 *
581     		 * TBD: [Future] This may be the prototype code for all cases where
582     		 * a Reference is expected!! 10/99
583     		 */
584     		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
585     			ret_desc = obj_desc;
586     		}
587     
588     		else {
589     			/*
590     			 * Duplicate the Reference in a new object so that we can resolve it
591     			 * without destroying the original Reference object
592     			 */
593     			ret_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
594     			if (!ret_desc) {
595     				status = AE_NO_MEMORY;
596     				goto cleanup;
597     			}
598     
599     			ret_desc->reference.opcode = obj_desc->reference.opcode;
600     			ret_desc->reference.offset = obj_desc->reference.offset;
601     			ret_desc->reference.object = obj_desc->reference.object;
602     		}
603     
604     
605     		/*
606     		 * Convert the Ret_desc Reference to a Number
607     		 * (This deletes the original Ret_desc)
608     		 */
609     		status = acpi_ex_resolve_operands (AML_LNOT_OP, &ret_desc, walk_state);
610     		if (ACPI_FAILURE (status)) {
611     			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n",
612     				acpi_ps_get_opcode_name (opcode), acpi_format_exception(status)));
613     
614     			goto cleanup;
615     		}
616     
617     		/* Do the actual increment or decrement */
618     
619     		if (AML_INCREMENT_OP == opcode) {
620     			ret_desc->integer.value++;
621     		}
622     		else {
623     			ret_desc->integer.value--;
624     		}
625     
626     		/* Store the result back in the original descriptor */
627     
628     		status = acpi_ex_store (ret_desc, obj_desc, walk_state);
629     
630     		/* Objdesc was just deleted (because it is an Reference) */
631     
632     		obj_desc = NULL;
633     
634     		break;
635     
636     
637     	/*  Def_object_type :=  Object_type_op  Source_object   */
638     
639     	case AML_TYPE_OP:
640     
641     		if (INTERNAL_TYPE_REFERENCE == obj_desc->common.type) {
642     			/*
643     			 * Not a Name -- an indirect name pointer would have
644     			 * been converted to a direct name pointer in Resolve_operands
645     			 */
646     			switch (obj_desc->reference.opcode) {
647     			case AML_ZERO_OP:
648     			case AML_ONE_OP:
649     			case AML_ONES_OP:
650     			case AML_REVISION_OP:
651     
652     				/* Constants are of type Number */
653     
654     				type = ACPI_TYPE_INTEGER;
655     				break;
656     
657     
658     			case AML_DEBUG_OP:
659     
660     				/* Per 1.0b spec, Debug object is of type Debug_object */
661     
662     				type = ACPI_TYPE_DEBUG_OBJECT;
663     				break;
664     
665     
666     			case AML_INDEX_OP:
667     
668     				/* Get the type of this reference (index into another object) */
669     
670     				type = obj_desc->reference.target_type;
671     				if (type == ACPI_TYPE_PACKAGE) {
672     					/*
673     					 * The main object is a package, we want to get the type
674     					 * of the individual package element that is referenced by
675     					 * the index.
676     					 */
677     					type = (*(obj_desc->reference.where))->common.type;
678     				}
679     
680     				break;
681     
682     
683     			case AML_LOCAL_OP:
684     			case AML_ARG_OP:
685     
686     				type = acpi_ds_method_data_get_type (obj_desc->reference.opcode,
687     						  obj_desc->reference.offset, walk_state);
688     				break;
689     
690     
691     			default:
692     
693     				REPORT_ERROR (("Acpi_ex_monadic2/Type_op: Internal error - Unknown Reference subtype %X\n",
694     					obj_desc->reference.opcode));
695     				status = AE_AML_INTERNAL;
696     				goto cleanup;
697     			}
698     		}
699     
700     		else {
701     			/*
702     			 * It's not a Reference, so it must be a direct name pointer.
703     			 */
704     			type = acpi_ns_get_type ((acpi_namespace_node *) obj_desc);
705     
706     			/* Convert internal types to external types */
707     
708     			switch (type) {
709     			case INTERNAL_TYPE_REGION_FIELD:
710     			case INTERNAL_TYPE_BANK_FIELD:
711     			case INTERNAL_TYPE_INDEX_FIELD:
712     
713     				type = ACPI_TYPE_FIELD_UNIT;
714     			}
715     
716     		}
717     
718     		/* Allocate a descriptor to hold the type. */
719     
720     		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
721     		if (!ret_desc) {
722     			status = AE_NO_MEMORY;
723     			goto cleanup;
724     		}
725     
726     		ret_desc->integer.value = type;
727     		break;
728     
729     
730     	/*  Def_size_of :=  Size_of_op  Source_object   */
731     
732     	case AML_SIZE_OF_OP:
733     
734     		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
735     			obj_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) obj_desc);
736     		}
737     
738     		if (!obj_desc) {
739     			value = 0;
740     		}
741     
742     		else {
743     			switch (obj_desc->common.type) {
744     
745     			case ACPI_TYPE_BUFFER:
746     
747     				value = obj_desc->buffer.length;
748     				break;
749     
750     
751     			case ACPI_TYPE_STRING:
752     
753     				value = obj_desc->string.length;
754     				break;
755     
756     
757     			case ACPI_TYPE_PACKAGE:
758     
759     				value = obj_desc->package.count;
760     				break;
761     
762     			case INTERNAL_TYPE_REFERENCE:
763     
764     				value = 4;
765     				break;
766     
767     			default:
768     
769     				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Not Buf/Str/Pkg - found type %X\n",
770     					obj_desc->common.type));
771     				status = AE_AML_OPERAND_TYPE;
772     				goto cleanup;
773     			}
774     		}
775     
776     		/*
777     		 * Now that we have the size of the object, create a result
778     		 * object to hold the value
779     		 */
780     		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
781     		if (!ret_desc) {
782     			status = AE_NO_MEMORY;
783     			goto cleanup;
784     		}
785     
786     		ret_desc->integer.value = value;
787     		break;
788     
789     
790     	/*  Def_ref_of  :=  Ref_of_op   Source_object   */
791     
792     	case AML_REF_OF_OP:
793     
794     		status = acpi_ex_get_object_reference (obj_desc, &ret_desc, walk_state);
795     		if (ACPI_FAILURE (status)) {
796     			goto cleanup;
797     		}
798     		break;
799     
800     
801     	/*  Def_deref_of := Deref_of_op Obj_reference   */
802     
803     	case AML_DEREF_OF_OP:
804     
805     
806     		/* Check for a method local or argument */
807     
808     		if (!VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
809     			/*
810     			 * Must resolve/dereference the local/arg reference first
811     			 */
812     			switch (obj_desc->reference.opcode) {
813     			/* Set Obj_desc to the value of the local/arg */
814     
815     			case AML_LOCAL_OP:
816     			case AML_ARG_OP:
817     
818     				acpi_ds_method_data_get_value (obj_desc->reference.opcode,
819     						obj_desc->reference.offset, walk_state, &tmp_desc);
820     
821     				/*
822     				 * Delete our reference to the input object and
823     				 * point to the object just retrieved
824     				 */
825     				acpi_ut_remove_reference (obj_desc);
826     				obj_desc = tmp_desc;
827     				break;
828     
829     			default:
830     
831     				/* Index op - handled below */
832     				break;
833     			}
834     		}
835     
836     
837     		/* Obj_desc may have changed from the code above */
838     
839     		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
840     			/* Get the actual object from the Node (This is the dereference) */
841     
842     			ret_desc = ((acpi_namespace_node *) obj_desc)->object;
843     
844     			/* Returning a pointer to the object, add another reference! */
845     
846     			acpi_ut_add_reference (ret_desc);
847     		}
848     
849     		else {
850     			/*
851     			 * This must be a reference object produced by the Index
852     			 * ASL operation -- check internal opcode
853     			 */
854     			if ((obj_desc->reference.opcode != AML_INDEX_OP) &&
855     				(obj_desc->reference.opcode != AML_REF_OF_OP)) {
856     				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n",
857     					obj_desc, obj_desc->reference.opcode));
858     
859     				status = AE_TYPE;
860     				goto cleanup;
861     			}
862     
863     
864     			switch (obj_desc->reference.opcode) {
865     			case AML_INDEX_OP:
866     
867     				/*
868     				 * Supported target types for the Index operator are
869     				 * 1) A Buffer
870     				 * 2) A Package
871     				 */
872     				if (obj_desc->reference.target_type == ACPI_TYPE_BUFFER_FIELD) {
873     					/*
874     					 * The target is a buffer, we must create a new object that
875     					 * contains one element of the buffer, the element pointed
876     					 * to by the index.
877     					 *
878     					 * NOTE: index into a buffer is NOT a pointer to a
879     					 * sub-buffer of the main buffer, it is only a pointer to a
880     					 * single element (byte) of the buffer!
881     					 */
882     					ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
883     					if (!ret_desc) {
884     						status = AE_NO_MEMORY;
885     						goto cleanup;
886     					}
887     
888     					tmp_desc = obj_desc->reference.object;
889     					ret_desc->integer.value =
890     						tmp_desc->buffer.pointer[obj_desc->reference.offset];
891     
892     					/* TBD: [Investigate] (see below) Don't add an additional
893     					 * ref!
894     					 */
895     				}
896     
897     				else if (obj_desc->reference.target_type == ACPI_TYPE_PACKAGE) {
898     					/*
899     					 * The target is a package, we want to return the referenced
900     					 * element of the package.  We must add another reference to
901     					 * this object, however.
902     					 */
903     					ret_desc = *(obj_desc->reference.where);
904     					if (!ret_desc) {
905     						/*
906     						 * We can't return a NULL dereferenced value.  This is
907     						 * an uninitialized package element and is thus a
908     						 * severe error.
909     						 */
910     
911     						ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n",
912     							obj_desc));
913     						status = AE_AML_UNINITIALIZED_ELEMENT;
914     						goto cleanup;
915     					}
916     
917     					acpi_ut_add_reference (ret_desc);
918     				}
919     
920     				else {
921     					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Target_type %X in obj %p\n",
922     						obj_desc->reference.target_type, obj_desc));
923     					status = AE_AML_OPERAND_TYPE;
924     					goto cleanup;
925     				}
926     
927     				break;
928     
929     
930     			case AML_REF_OF_OP:
931     
932     				ret_desc = obj_desc->reference.object;
933     
934     				/* Add another reference to the object! */
935     
936     				acpi_ut_add_reference (ret_desc);
937     				break;
938     			}
939     		}
940     
941     		break;
942     
943     
944     	default:
945     
946     		REPORT_ERROR (("Acpi_ex_monadic2: Unknown monadic opcode %X\n",
947     			opcode));
948     		status = AE_AML_BAD_OPCODE;
949     		goto cleanup;
950     	}
951     
952     
953     cleanup:
954     
955     	if (obj_desc) {
956     		acpi_ut_remove_reference (obj_desc);
957     	}
958     
959     	/* Delete return object on error */
960     
961     	if (ACPI_FAILURE (status) &&
962     		(ret_desc)) {
963     		acpi_ut_remove_reference (ret_desc);
964     		ret_desc = NULL;
965     	}
966     
967     	*return_desc = ret_desc;
968     	return_ACPI_STATUS (status);
969     }
970     
971