1
2/******************************************************************************
3 *
4 * Module Name: exoparg1 - AML execution - opcodes with 1 argument
5 *              $Revision: 1.1.1.1 $
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         ("exoparg1")
38
39
40/*!
41 * Naming convention for AML interpreter execution routines.
42 *
43 * The routines that begin execution of AML opcodes are named with a common
44 * convention based upon the number of arguments, the number of target operands,
45 * and whether or not a value is returned:
46 *
47 *      AcpiExOpcode_xA_yT_zR
48 *
49 * Where:
50 *
51 * xA - ARGUMENTS:    The number of arguments (input operands) that are
52 *                    required for this opcode type (1 through 6 args).
53 * yT - TARGETS:      The number of targets (output operands) that are required
54 *                    for this opcode type (0, 1, or 2 targets).
55 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
56 *                    as the function return (0 or 1).
57 *
58 * The AcpiExOpcode* functions are called via the Dispatcher component with
59 * fully resolved operands.
60!*/
61
62
63/*******************************************************************************
64 *
65 * FUNCTION:    Acpi_ex_opcode_1A_0T_0R
66 *
67 * PARAMETERS:  Walk_state          - Current state (contains AML opcode)
68 *
69 * RETURN:      Status
70 *
71 * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
72 *              object stack
73 *
74 ******************************************************************************/
75
76acpi_status
77acpi_ex_opcode_1A_0T_0R (
78	acpi_walk_state         *walk_state)
79{
80	acpi_operand_object     **operand = &walk_state->operands[0];
81	acpi_status             status = AE_OK;
82
83
84	FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
85
86
87	/* Examine the opcode */
88
89	switch (walk_state->opcode) {
90	case AML_RELEASE_OP:    /*  Release (Mutex_object) */
91
92		status = acpi_ex_release_mutex (operand[0], walk_state);
93		break;
94
95
96	case AML_RESET_OP:      /*  Reset (Event_object) */
97
98		status = acpi_ex_system_reset_event (operand[0]);
99		break;
100
101
102	case AML_SIGNAL_OP:     /*  Signal (Event_object) */
103
104		status = acpi_ex_system_signal_event (operand[0]);
105		break;
106
107
108	case AML_SLEEP_OP:      /*  Sleep (Msec_time) */
109
110		acpi_ex_system_do_suspend ((u32) operand[0]->integer.value);
111		break;
112
113
114	case AML_STALL_OP:      /*  Stall (Usec_time) */
115
116		acpi_ex_system_do_stall ((u32) operand[0]->integer.value);
117		break;
118
119
120	case AML_UNLOAD_OP:     /*  Unload (Handle) */
121
122		status = acpi_ex_unload_table (operand[0]);
123		break;
124
125
126	default:                /*  Unknown opcode  */
127
128		REPORT_ERROR (("Acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n",
129			walk_state->opcode));
130		status = AE_AML_BAD_OPCODE;
131		break;
132	}
133
134	return_ACPI_STATUS (status);
135}
136
137
138/*******************************************************************************
139 *
140 * FUNCTION:    Acpi_ex_opcode_1A_1T_0R
141 *
142 * PARAMETERS:  Walk_state          - Current state (contains AML opcode)
143 *
144 * RETURN:      Status
145 *
146 * DESCRIPTION: Execute opcode with one argument, one target, and no
147 *              return value.
148 *
149 ******************************************************************************/
150
151acpi_status
152acpi_ex_opcode_1A_1T_0R (
153	acpi_walk_state         *walk_state)
154{
155	acpi_status             status = AE_OK;
156	acpi_operand_object     **operand = &walk_state->operands[0];
157
158
159	FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
160
161
162	switch (walk_state->opcode) {
163
164	case AML_LOAD_OP:
165
166		status = acpi_ex_load_op (operand[0], operand[1]);
167		break;
168
169	default:                        /* Unknown opcode */
170
171		REPORT_ERROR (("Acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n",
172			walk_state->opcode));
173		status = AE_AML_BAD_OPCODE;
174		goto cleanup;
175	}
176
177
178cleanup:
179
180	return_ACPI_STATUS (status);
181}
182
183
184/*******************************************************************************
185 *
186 * FUNCTION:    Acpi_ex_opcode_1A_1T_1R
187 *
188 * PARAMETERS:  Walk_state          - Current state (contains AML opcode)
189 *
190 * RETURN:      Status
191 *
192 * DESCRIPTION: Execute opcode with one argument, one target, and a
193 *              return value.
194 *
195 ******************************************************************************/
196
197acpi_status
198acpi_ex_opcode_1A_1T_1R (
199	acpi_walk_state         *walk_state)
200{
201	acpi_status             status = AE_OK;
202	acpi_operand_object     **operand = &walk_state->operands[0];
203	acpi_operand_object     *return_desc = NULL;
204	acpi_operand_object     *return_desc2 = NULL;
205	u32                     temp32;
206	u32                     i;
207	u32                     j;
208	acpi_integer            digit;
209
210
211	FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
212
213
214	/* Create a return object of type Integer for most opcodes */
215
216	switch (walk_state->opcode) {
217	case AML_BIT_NOT_OP:
218	case AML_FIND_SET_LEFT_BIT_OP:
219	case AML_FIND_SET_RIGHT_BIT_OP:
220	case AML_FROM_BCD_OP:
221	case AML_TO_BCD_OP:
222	case AML_COND_REF_OF_OP:
223
224		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
225		if (!return_desc) {
226			status = AE_NO_MEMORY;
227			goto cleanup;
228		}
229
230		break;
231	}
232
233
234	switch (walk_state->opcode) {
235
236	case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
237
238		return_desc->integer.value = ~operand[0]->integer.value;
239		break;
240
241
242	case AML_FIND_SET_LEFT_BIT_OP:  /* Find_set_left_bit (Operand, Result) */
243
244
245		return_desc->integer.value = operand[0]->integer.value;
246
247		/*
248		 * Acpi specification describes Integer type as a little
249		 * endian unsigned value, so this boundary condition is valid.
250		 */
251		for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
252			return_desc->integer.value >>= 1;
253		}
254
255		return_desc->integer.value = temp32;
256		break;
257
258
259	case AML_FIND_SET_RIGHT_BIT_OP: /* Find_set_right_bit (Operand, Result) */
260
261
262		return_desc->integer.value = operand[0]->integer.value;
263
264		/*
265		 * The Acpi specification describes Integer type as a little
266		 * endian unsigned value, so this boundary condition is valid.
267		 */
268		for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
269			return_desc->integer.value <<= 1;
270		}
271
272		/* Since the bit position is one-based, subtract from 33 (65) */
273
274		return_desc->integer.value = temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
275		break;
276
277
278	case AML_FROM_BCD_OP:           /* From_bcd (BCDValue, Result) */
279
280		/*
281		 * The 64-bit ACPI integer can hold 16 4-bit BCD integers
282		 */
283		return_desc->integer.value = 0;
284		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
285			/* Get one BCD digit */
286
287			digit = (acpi_integer) ((operand[0]->integer.value >> (i * 4)) & 0xF);
288
289			/* Check the range of the digit */
290
291			if (digit > 9) {
292				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD digit too large: %d\n",
293					(u32) digit));
294				status = AE_AML_NUMERIC_OVERFLOW;
295				goto cleanup;
296			}
297
298			if (digit > 0) {
299				/* Sum into the result with the appropriate power of 10 */
300
301				for (j = 0; j < i; j++) {
302					digit *= 10;
303				}
304
305				return_desc->integer.value += digit;
306			}
307		}
308		break;
309
310
311	case AML_TO_BCD_OP:             /* To_bcd (Operand, Result) */
312
313		if (operand[0]->integer.value > ACPI_MAX_BCD_VALUE) {
314			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD overflow: %8.8X%8.8X\n",
315				HIDWORD(operand[0]->integer.value), LODWORD(operand[0]->integer.value)));
316			status = AE_AML_NUMERIC_OVERFLOW;
317			goto cleanup;
318		}
319
320		return_desc->integer.value = 0;
321		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
322			/* Divide by nth factor of 10 */
323
324			temp32 = 0;
325			digit = operand[0]->integer.value;
326			for (j = 0; j < i; j++) {
327				acpi_ut_short_divide (&digit, 10, &digit, &temp32);
328			}
329
330			/* Create the BCD digit from the remainder above */
331
332			if (digit > 0) {
333				return_desc->integer.value += (temp32 << (i * 4));
334			}
335		}
336		break;
337
338
339	case AML_COND_REF_OF_OP:        /* Cond_ref_of (Source_object, Result) */
340
341		/*
342		 * This op is a little strange because the internal return value is
343		 * different than the return value stored in the result descriptor
344		 * (There are really two return values)
345		 */
346		if ((acpi_namespace_node *) operand[0] == acpi_gbl_root_node) {
347			/*
348			 * This means that the object does not exist in the namespace,
349			 * return FALSE
350			 */
351			return_desc->integer.value = 0;
352
353			/*
354			 * Must delete the result descriptor since there is no reference
355			 * being returned
356			 */
357			acpi_ut_remove_reference (operand[1]);
358			goto cleanup;
359		}
360
361		/* Get the object reference and store it */
362
363		status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state);
364		if (ACPI_FAILURE (status)) {
365			goto cleanup;
366		}
367
368		status = acpi_ex_store (return_desc2, operand[1], walk_state);
369
370		/* The object exists in the namespace, return TRUE */
371
372		return_desc->integer.value = ACPI_INTEGER_MAX;
373		goto cleanup;
374		break;
375
376
377	case AML_STORE_OP:              /* Store (Source, Target) */
378
379		/*
380		 * A store operand is typically a number, string, buffer or lvalue
381		 * Be careful about deleting the source object,
382		 * since the object itself may have been stored.
383		 */
384		status = acpi_ex_store (operand[0], operand[1], walk_state);
385		if (ACPI_FAILURE (status)) {
386			return_ACPI_STATUS (status);
387		}
388
389		/*
390		 * Normally, we would remove a reference on the Operand[0] parameter;
391		 * But since it is being used as the internal return object
392		 * (meaning we would normally increment it), the two cancel out,
393		 * and we simply don't do anything.
394		 */
395		walk_state->result_obj = operand[0];
396		walk_state->operands[0] = NULL; /* Prevent deletion */
397		return_ACPI_STATUS (status);
398		break;
399
400
401	/*
402	 * ACPI 2.0 Opcodes
403	 */
404	case AML_COPY_OP:               /* Copy (Source, Target) */
405
406		status = AE_NOT_IMPLEMENTED;
407		goto cleanup;
408		break;
409
410
411	case AML_TO_DECSTRING_OP:       /* To_decimal_string (Data, Result) */
412
413		status = acpi_ex_convert_to_string (operand[0], &return_desc, 10, ACPI_UINT32_MAX, walk_state);
414		break;
415
416
417	case AML_TO_HEXSTRING_OP:       /* To_hex_string (Data, Result) */
418
419		status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, ACPI_UINT32_MAX, walk_state);
420		break;
421
422
423	case AML_TO_BUFFER_OP:          /* To_buffer (Data, Result) */
424
425		status = acpi_ex_convert_to_buffer (operand[0], &return_desc, walk_state);
426		break;
427
428
429	case AML_TO_INTEGER_OP:         /* To_integer (Data, Result) */
430
431		status = acpi_ex_convert_to_integer (operand[0], &return_desc, walk_state);
432		break;
433
434
435	/*
436	 * These are two obsolete opcodes
437	 */
438	case AML_SHIFT_LEFT_BIT_OP:     /*  Shift_left_bit (Source, Bit_num) */
439	case AML_SHIFT_RIGHT_BIT_OP:    /*  Shift_right_bit (Source, Bit_num) */
440
441
442		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n",
443				  acpi_ps_get_opcode_name (walk_state->opcode)));
444		status = AE_SUPPORT;
445		goto cleanup;
446		break;
447
448
449	default:                        /* Unknown opcode */
450
451		REPORT_ERROR (("Acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n",
452			walk_state->opcode));
453		status = AE_AML_BAD_OPCODE;
454		goto cleanup;
455	}
456
457
458	/*
459	 * Store the return value computed above into the target object
460	 */
461	status = acpi_ex_store (return_desc, operand[1], walk_state);
462
463
464cleanup:
465
466	walk_state->result_obj = return_desc;
467
468	/* Delete return object on error */
469
470	if (ACPI_FAILURE (status)) {
471		acpi_ut_remove_reference (return_desc);
472	}
473
474	return_ACPI_STATUS (status);
475}
476
477
478/*******************************************************************************
479 *
480 * FUNCTION:    Acpi_ex_opcode_1A_0T_1R
481 *
482 * PARAMETERS:  Walk_state          - Current state (contains AML opcode)
483 *
484 * RETURN:      Status
485 *
486 * DESCRIPTION: Execute opcode with one argument, no target, and a return value
487 *
488 ******************************************************************************/
489
490acpi_status
491acpi_ex_opcode_1A_0T_1R (
492	acpi_walk_state         *walk_state)
493{
494	acpi_operand_object     **operand = &walk_state->operands[0];
495	acpi_operand_object     *temp_desc;
496	acpi_operand_object     *return_desc = NULL;
497	acpi_status             status = AE_OK;
498	u32                     type;
499	acpi_integer            value;
500
501
502	FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
503
504
505	/* Get the operand and decode the opcode */
506
507	switch (walk_state->opcode) {
508
509	case AML_LNOT_OP:               /* LNot (Operand) */
510
511		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
512		if (!return_desc) {
513			status = AE_NO_MEMORY;
514			goto cleanup;
515		}
516
517		return_desc->integer.value = !operand[0]->integer.value;
518		break;
519
520
521	case AML_DECREMENT_OP:          /* Decrement (Operand)  */
522	case AML_INCREMENT_OP:          /* Increment (Operand)  */
523
524		/*
525		 * Since we are expecting a Reference operand, it
526		 * can be either a Node or an internal object.
527		 */
528		return_desc = operand[0];
529		if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_INTERNAL)) {
530			/* Internal reference object - prevent deletion */
531
532			acpi_ut_add_reference (return_desc);
533		}
534
535		/*
536		 * Convert the Return_desc Reference to a Number
537		 * (This removes a reference on the Return_desc object)
538		 */
539		status = acpi_ex_resolve_operands (AML_LNOT_OP, &return_desc, walk_state);
540		if (ACPI_FAILURE (status)) {
541			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n",
542				acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception(status)));
543
544			goto cleanup;
545		}
546
547		/*
548		 * Return_desc is now guaranteed to be an Integer object
549		 * Do the actual increment or decrement
550		 */
551		if (AML_INCREMENT_OP == walk_state->opcode) {
552			return_desc->integer.value++;
553		}
554		else {
555			return_desc->integer.value--;
556		}
557
558		/* Store the result back in the original descriptor */
559
560		status = acpi_ex_store (return_desc, operand[0], walk_state);
561		break;
562
563
564	case AML_TYPE_OP:               /* Object_type (Source_object) */
565
566		if (INTERNAL_TYPE_REFERENCE == operand[0]->common.type) {
567			/*
568			 * Not a Name -- an indirect name pointer would have
569			 * been converted to a direct name pointer in Resolve_operands
570			 */
571			switch (operand[0]->reference.opcode) {
572			case AML_ZERO_OP:
573			case AML_ONE_OP:
574			case AML_ONES_OP:
575			case AML_REVISION_OP:
576
577				/* Constants are of type Integer */
578
579				type = ACPI_TYPE_INTEGER;
580				break;
581
582
583			case AML_DEBUG_OP:
584
585				/* Per 1.0b spec, Debug object is of type "Debug_object" */
586
587				type = ACPI_TYPE_DEBUG_OBJECT;
588				break;
589
590
591			case AML_INDEX_OP:
592
593				/* Get the type of this reference (index into another object) */
594
595				type = operand[0]->reference.target_type;
596				if (type == ACPI_TYPE_PACKAGE) {
597					/*
598					 * The main object is a package, we want to get the type
599					 * of the individual package element that is referenced by
600					 * the index.
601					 */
602					type = (*(operand[0]->reference.where))->common.type;
603				}
604
605				break;
606
607
608			case AML_LOCAL_OP:
609			case AML_ARG_OP:
610
611				type = acpi_ds_method_data_get_type (operand[0]->reference.opcode,
612						  operand[0]->reference.offset, walk_state);
613				break;
614
615
616			default:
617
618				REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R/Type_op: Internal error - Unknown Reference subtype %X\n",
619					operand[0]->reference.opcode));
620				status = AE_AML_INTERNAL;
621				goto cleanup;
622			}
623		}
624
625		else {
626			/*
627			 * It's not a Reference, so it must be a direct name pointer.
628			 */
629			type = acpi_ns_get_type ((acpi_namespace_node *) operand[0]);
630
631			/* Convert internal types to external types */
632
633			switch (type) {
634			case INTERNAL_TYPE_REGION_FIELD:
635			case INTERNAL_TYPE_BANK_FIELD:
636			case INTERNAL_TYPE_INDEX_FIELD:
637
638				type = ACPI_TYPE_FIELD_UNIT;
639			}
640
641		}
642
643		/* Allocate a descriptor to hold the type. */
644
645		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
646		if (!return_desc) {
647			status = AE_NO_MEMORY;
648			goto cleanup;
649		}
650
651		return_desc->integer.value = type;
652		break;
653
654
655	case AML_SIZE_OF_OP:            /* Size_of (Source_object) */
656
657		temp_desc = operand[0];
658		if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) {
659			temp_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) operand[0]);
660		}
661
662		if (!temp_desc) {
663			value = 0;
664		}
665
666		else {
667			switch (temp_desc->common.type) {
668			case ACPI_TYPE_BUFFER:
669				value = temp_desc->buffer.length;
670				break;
671
672			case ACPI_TYPE_STRING:
673				value = temp_desc->string.length;
674				break;
675
676			case ACPI_TYPE_PACKAGE:
677				value = temp_desc->package.count;
678				break;
679
680			case INTERNAL_TYPE_REFERENCE:
681
682				/* TBD: this must be a reference to a buf/str/pkg?? */
683
684				value = 4;
685				break;
686
687			default:
688				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Not Buf/Str/Pkg - found type %X\n",
689					temp_desc->common.type));
690				status = AE_AML_OPERAND_TYPE;
691				goto cleanup;
692			}
693		}
694
695		/*
696		 * Now that we have the size of the object, create a result
697		 * object to hold the value
698		 */
699		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
700		if (!return_desc) {
701			status = AE_NO_MEMORY;
702			goto cleanup;
703		}
704
705		return_desc->integer.value = value;
706		break;
707
708
709	case AML_REF_OF_OP:             /* Ref_of (Source_object) */
710
711		status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state);
712		if (ACPI_FAILURE (status)) {
713			goto cleanup;
714		}
715		break;
716
717
718	case AML_DEREF_OF_OP:           /* Deref_of (Obj_reference) */
719
720		/* Check for a method local or argument */
721
722		if (!VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) {
723			/*
724			 * Must resolve/dereference the local/arg reference first
725			 */
726			switch (operand[0]->reference.opcode) {
727			/* Set Operand[0] to the value of the local/arg */
728
729			case AML_LOCAL_OP:
730			case AML_ARG_OP:
731
732				acpi_ds_method_data_get_value (operand[0]->reference.opcode,
733						operand[0]->reference.offset, walk_state, &temp_desc);
734
735				/*
736				 * Delete our reference to the input object and
737				 * point to the object just retrieved
738				 */
739				acpi_ut_remove_reference (operand[0]);
740				operand[0] = temp_desc;
741				break;
742
743			default:
744
745				/* Index op - handled below */
746				break;
747			}
748		}
749
750
751		/* Operand[0] may have changed from the code above */
752
753		if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) {
754			/* Get the actual object from the Node (This is the dereference) */
755
756			return_desc = ((acpi_namespace_node *) operand[0])->object;
757
758			/* Returning a pointer to the object, add another reference! */
759
760			acpi_ut_add_reference (return_desc);
761		}
762
763		else {
764			/*
765			 * This must be a reference object produced by the Index
766			 * ASL operation -- check internal opcode
767			 */
768			if ((operand[0]->reference.opcode != AML_INDEX_OP) &&
769				(operand[0]->reference.opcode != AML_REF_OF_OP)) {
770				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n",
771					operand[0], operand[0]->reference.opcode));
772
773				status = AE_TYPE;
774				goto cleanup;
775			}
776
777
778			switch (operand[0]->reference.opcode) {
779			case AML_INDEX_OP:
780
781				/*
782				 * Supported target types for the Index operator are
783				 * 1) A Buffer
784				 * 2) A Package
785				 */
786				if (operand[0]->reference.target_type == ACPI_TYPE_BUFFER_FIELD) {
787					/*
788					 * The target is a buffer, we must create a new object that
789					 * contains one element of the buffer, the element pointed
790					 * to by the index.
791					 *
792					 * NOTE: index into a buffer is NOT a pointer to a
793					 * sub-buffer of the main buffer, it is only a pointer to a
794					 * single element (byte) of the buffer!
795					 */
796					return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
797					if (!return_desc) {
798						status = AE_NO_MEMORY;
799						goto cleanup;
800					}
801
802					temp_desc = operand[0]->reference.object;
803					return_desc->integer.value =
804						temp_desc->buffer.pointer[operand[0]->reference.offset];
805
806					/* TBD: [Investigate] (see below) Don't add an additional
807					 * ref!
808					 */
809				}
810
811				else if (operand[0]->reference.target_type == ACPI_TYPE_PACKAGE) {
812					/*
813					 * The target is a package, we want to return the referenced
814					 * element of the package.  We must add another reference to
815					 * this object, however.
816					 */
817					return_desc = *(operand[0]->reference.where);
818					if (!return_desc) {
819						/*
820						 * We can't return a NULL dereferenced value.  This is
821						 * an uninitialized package element and is thus a
822						 * severe error.
823						 */
824
825						ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n",
826							operand[0]));
827						status = AE_AML_UNINITIALIZED_ELEMENT;
828						goto cleanup;
829					}
830
831					acpi_ut_add_reference (return_desc);
832				}
833
834				else {
835					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Target_type %X in obj %p\n",
836						operand[0]->reference.target_type, operand[0]));
837					status = AE_AML_OPERAND_TYPE;
838					goto cleanup;
839				}
840
841				break;
842
843
844			case AML_REF_OF_OP:
845
846				return_desc = operand[0]->reference.object;
847
848				/* Add another reference to the object! */
849
850				acpi_ut_add_reference (return_desc);
851				break;
852			}
853		}
854
855		break;
856
857
858	default:
859
860		REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n",
861			walk_state->opcode));
862		status = AE_AML_BAD_OPCODE;
863		goto cleanup;
864	}
865
866
867cleanup:
868
869	/* Delete return object on error */
870
871	if (ACPI_FAILURE (status)) {
872		acpi_ut_remove_reference (return_desc);
873	}
874
875	walk_state->result_obj = return_desc;
876	return_ACPI_STATUS (status);
877}
878
879