exresop.c revision 67754
1
2/******************************************************************************
3 *
4 * Module Name: amresop - AML Interpreter operand/object resolution
5 *              $Revision: 15 $
6 *
7 *****************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999, Intel Corp.  All rights
14 * reserved.
15 *
16 * 2. License
17 *
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights.  You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
21 * property rights.
22 *
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
29 *
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code.  No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
38 *
39 * The above copyright and patent license is granted only if the following
40 * conditions are met:
41 *
42 * 3. Conditions
43 *
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision.  In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change.  Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee.  Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
55 *
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution.  In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
66 * make.
67 *
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
72 * distribution.
73 *
74 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * Intel Code.
76 *
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
81 *
82 * 4. Disclaimer and Export Compliance
83 *
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * PARTICULAR PURPOSE.
91 *
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * LIMITED REMEDY.
100 *
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government.  In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
115 *
116 *****************************************************************************/
117
118#define __AMRESOP_C__
119
120#include "acpi.h"
121#include "amlcode.h"
122#include "acparser.h"
123#include "acdispat.h"
124#include "acinterp.h"
125#include "acnamesp.h"
126#include "actables.h"
127#include "acevents.h"
128
129
130#define _COMPONENT          INTERPRETER
131        MODULE_NAME         ("amresop")
132
133
134/*******************************************************************************
135 *
136 * FUNCTION:    AcpiAmlResolveOperands
137 *
138 * PARAMETERS:  Opcode              Opcode being interpreted
139 *              StackPtr            Top of operand stack
140 *
141 * RETURN:      Status
142 *
143 * DESCRIPTION: Convert stack entries to required types
144 *
145 *      Each nibble in ArgTypes represents one required operand
146 *      and indicates the required Type:
147 *
148 *      The corresponding stack entry will be converted to the
149 *      required type if possible, else return an exception
150 *
151 ******************************************************************************/
152
153ACPI_STATUS
154AcpiAmlResolveOperands (
155    UINT16                  Opcode,
156    ACPI_OPERAND_OBJECT     **StackPtr,
157    ACPI_WALK_STATE         *WalkState)
158{
159    ACPI_OPERAND_OBJECT     *ObjDesc;
160    ACPI_STATUS             Status = AE_OK;
161    UINT8                   ObjectType;
162    ACPI_HANDLE             TempHandle;
163    UINT32                  ArgTypes;
164    ACPI_OPCODE_INFO        *OpInfo;
165    UINT32                  ThisArgType;
166
167
168    FUNCTION_TRACE_U32 ("AmlResolveOperands", Opcode);
169
170
171    OpInfo = AcpiPsGetOpcodeInfo (Opcode);
172    if (ACPI_GET_OP_TYPE (OpInfo) != ACPI_OP_TYPE_OPCODE)
173    {
174        return_ACPI_STATUS (AE_AML_BAD_OPCODE);
175    }
176
177
178    ArgTypes = OpInfo->RuntimeArgs;
179    if (ArgTypes == ARGI_INVALID_OPCODE)
180    {
181        DEBUG_PRINT (ACPI_ERROR,
182            ("AmlResolveOperands: Internal error - %X is not a runtime opcode\n", Opcode));
183        Status = AE_AML_INTERNAL;
184        goto Cleanup;
185    }
186
187    DEBUG_PRINT (TRACE_EXEC,
188        ("AmlResolveOperands: Opcode %X OperandTypes=%X \n",
189        Opcode, ArgTypes));
190
191
192   /*
193     * Normal exit is with *Types == '\0' at end of string.
194     * Function will return an exception from within the loop upon
195     * finding an entry which is not, and cannot be converted
196     * to, the required type; if stack underflows; or upon
197     * finding a NULL stack entry (which "should never happen").
198     */
199
200    while (GET_CURRENT_ARG_TYPE (ArgTypes))
201    {
202        if (!StackPtr || !*StackPtr)
203        {
204            DEBUG_PRINT (ACPI_ERROR,
205                ("AmlResolveOperands: Internal error - null stack entry at %X\n", StackPtr));
206            Status = AE_AML_INTERNAL;
207            goto Cleanup;
208        }
209
210        /* Extract useful items */
211
212        ObjDesc = *StackPtr;
213
214        /* Decode the descriptor type */
215
216        if (VALID_DESCRIPTOR_TYPE (ObjDesc, ACPI_DESC_TYPE_NAMED))
217        {
218            /* Node */
219
220            ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
221        }
222
223        else if (VALID_DESCRIPTOR_TYPE (ObjDesc, ACPI_DESC_TYPE_INTERNAL))
224        {
225            /* ACPI internal object */
226
227            ObjectType = ObjDesc->Common.Type;
228
229            /* Check for bad ACPI_OBJECT_TYPE */
230
231            if (!AcpiAmlValidateObjectType (ObjectType))
232            {
233                DEBUG_PRINT (ACPI_ERROR,
234                    ("AmlResolveOperands: Bad operand object type [0x%x]\n",
235                    ObjectType));
236                Status = AE_AML_OPERAND_TYPE;
237                goto Cleanup;
238            }
239
240            if (ObjectType == (UINT8) INTERNAL_TYPE_REFERENCE)
241            {
242                /*
243                 * Decode the Reference
244                 */
245
246                OpInfo = AcpiPsGetOpcodeInfo (Opcode);
247                if (ACPI_GET_OP_TYPE (OpInfo) != ACPI_OP_TYPE_OPCODE)
248                {
249                    return_ACPI_STATUS (AE_AML_BAD_OPCODE);
250                }
251
252
253                switch (ObjDesc->Reference.OpCode)
254                {
255                case AML_ZERO_OP:
256                case AML_ONE_OP:
257                case AML_ONES_OP:
258                case AML_DEBUG_OP:
259                case AML_NAME_OP:
260                case AML_INDEX_OP:
261                case AML_ARG_OP:
262                case AML_LOCAL_OP:
263
264                    DEBUG_ONLY_MEMBERS (DEBUG_PRINT (ACPI_INFO,
265                        ("Reference Opcode: %s\n", OpInfo->Name)));
266                    break;
267
268                default:
269                    DEBUG_PRINT (ACPI_INFO,
270                        ("Reference Opcode: Unknown [%02x]\n",
271                        ObjDesc->Reference.OpCode));
272
273                    Status = AE_AML_OPERAND_TYPE;
274                    goto Cleanup;
275                    break;
276                }
277            }
278
279        }
280
281        else
282        {
283            /* Invalid descriptor */
284
285            DEBUG_PRINT (ACPI_ERROR,
286                ("Bad descriptor type 0x%X in Obj %p\n",
287                ObjDesc->Common.DataType, ObjDesc));
288
289            Status = AE_AML_OPERAND_TYPE;
290            goto Cleanup;
291        }
292
293
294        /*
295         * Decode a character from the type string
296         */
297
298        ThisArgType = GET_CURRENT_ARG_TYPE (ArgTypes);
299        INCREMENT_ARG_LIST (ArgTypes);
300
301
302        switch (ThisArgType)
303        {
304
305        case ARGI_REFERENCE:   /* Reference */
306        case ARGI_TARGETREF:
307
308            /* Need an operand of type INTERNAL_TYPE_REFERENCE */
309
310            if (VALID_DESCRIPTOR_TYPE (ObjDesc, ACPI_DESC_TYPE_NAMED))             /* direct name ptr OK as-is */
311            {
312                break;
313            }
314
315            if (INTERNAL_TYPE_REFERENCE != ObjectType)
316            {
317                DEBUG_PRINT (ACPI_INFO,
318                    ("AmlResolveOperands: Needed Reference, found %s Obj=%p\n",
319                    AcpiCmGetTypeName (ObjectType), *StackPtr));
320                Status = AE_AML_OPERAND_TYPE;
321                goto Cleanup;
322            }
323
324            if (AML_NAME_OP == ObjDesc->Reference.OpCode)
325            {
326                /*
327                 * Convert an indirect name ptr to direct name ptr and put
328                 * it on the stack
329                 */
330
331                TempHandle = ObjDesc->Reference.Object;
332                AcpiCmRemoveReference (ObjDesc);
333                (*StackPtr) = TempHandle;
334            }
335            break;
336
337
338        case ARGI_NUMBER:   /* Number */
339
340            /* Need an operand of type ACPI_TYPE_NUMBER */
341
342            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
343            if (ACPI_FAILURE (Status))
344            {
345                goto Cleanup;
346            }
347
348            if (ACPI_TYPE_NUMBER != (*StackPtr)->Common.Type)
349            {
350                DEBUG_PRINT (ACPI_INFO,
351                    ("AmlResolveOperands: Needed Number, found %s Obj=%p\n",
352                    AcpiCmGetTypeName (ObjectType), *StackPtr));
353                Status = AE_AML_OPERAND_TYPE;
354                goto Cleanup;
355            }
356            break;
357
358
359        case ARGI_STRING:
360
361            /* Need an operand of type ACPI_TYPE_STRING or ACPI_TYPE_BUFFER */
362
363            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
364            if (ACPI_FAILURE (Status))
365            {
366                goto Cleanup;
367            }
368
369            if ((ACPI_TYPE_STRING != (*StackPtr)->Common.Type) &&
370                (ACPI_TYPE_BUFFER != (*StackPtr)->Common.Type))
371            {
372                DEBUG_PRINT (ACPI_INFO,
373                    ("AmlResolveOperands: Needed String or Buffer, found %s Obj=%p\n",
374                    AcpiCmGetTypeName (ObjectType), *StackPtr));
375                Status = AE_AML_OPERAND_TYPE;
376                goto Cleanup;
377            }
378            break;
379
380
381        case ARGI_BUFFER:
382
383            /* Need an operand of type ACPI_TYPE_BUFFER */
384
385            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
386            if (ACPI_FAILURE (Status))
387            {
388                goto Cleanup;
389            }
390
391            if (ACPI_TYPE_BUFFER != (*StackPtr)->Common.Type)
392            {
393                DEBUG_PRINT (ACPI_INFO,
394                    ("AmlResolveOperands: Needed Buffer, found %s Obj=%p\n",
395                    AcpiCmGetTypeName (ObjectType), *StackPtr));
396                Status = AE_AML_OPERAND_TYPE;
397                goto Cleanup;
398            }
399            break;
400
401
402        case ARGI_MUTEX:
403
404            /* Need an operand of type ACPI_TYPE_MUTEX */
405
406            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
407            if (ACPI_FAILURE (Status))
408            {
409                goto Cleanup;
410            }
411
412            if (ACPI_TYPE_MUTEX != (*StackPtr)->Common.Type)
413            {
414                DEBUG_PRINT (ACPI_INFO,
415                    ("AmlResolveOperands: Needed Mutex, found %s Obj=%p\n",
416                    AcpiCmGetTypeName (ObjectType), *StackPtr));
417                Status = AE_AML_OPERAND_TYPE;
418                goto Cleanup;
419            }
420            break;
421
422
423        case ARGI_EVENT:
424
425            /* Need an operand of type ACPI_TYPE_EVENT */
426
427            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
428            if (ACPI_FAILURE (Status))
429            {
430                goto Cleanup;
431            }
432
433            if (ACPI_TYPE_EVENT != (*StackPtr)->Common.Type)
434            {
435                DEBUG_PRINT (ACPI_INFO,
436                    ("AmlResolveOperands: Needed AcpiEvent, found %s Obj=%p\n",
437                    AcpiCmGetTypeName (ObjectType), *StackPtr));
438                Status = AE_AML_OPERAND_TYPE;
439                goto Cleanup;
440            }
441            break;
442
443
444        case ARGI_REGION:
445
446            /* Need an operand of type ACPI_TYPE_REGION */
447
448            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
449            if (ACPI_FAILURE (Status))
450            {
451                goto Cleanup;
452            }
453
454            if (ACPI_TYPE_REGION != (*StackPtr)->Common.Type)
455            {
456                DEBUG_PRINT (ACPI_INFO,
457                    ("AmlResolveOperands: Needed Region, found %s Obj=%p\n",
458                    AcpiCmGetTypeName (ObjectType), *StackPtr));
459                Status = AE_AML_OPERAND_TYPE;
460                goto Cleanup;
461            }
462            break;
463
464
465         case ARGI_IF:   /* If */
466
467            /* Need an operand of type INTERNAL_TYPE_IF */
468
469            if (INTERNAL_TYPE_IF != (*StackPtr)->Common.Type)
470            {
471                DEBUG_PRINT (ACPI_INFO,
472                    ("AmlResolveOperands: Needed If, found %s Obj=%p\n",
473                    AcpiCmGetTypeName (ObjectType), *StackPtr));
474                Status = AE_AML_OPERAND_TYPE;
475                goto Cleanup;
476            }
477            break;
478
479
480        case ARGI_PACKAGE:   /* Package */
481
482            /* Need an operand of type ACPI_TYPE_PACKAGE */
483
484            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
485            if (ACPI_FAILURE (Status))
486            {
487                goto Cleanup;
488            }
489
490            if (ACPI_TYPE_PACKAGE != (*StackPtr)->Common.Type)
491            {
492                DEBUG_PRINT (ACPI_INFO,
493                    ("AmlResolveOperands: Needed Package, found %s Obj=%p\n",
494                    AcpiCmGetTypeName (ObjectType), *StackPtr));
495                Status = AE_AML_OPERAND_TYPE;
496                goto Cleanup;
497            }
498            break;
499
500
501        case ARGI_ANYTYPE:
502
503
504            /*
505             * We don't want to resolve IndexOp reference objects during
506             * a store because this would be an implicit DeRefOf operation.
507             * Instead, we just want to store the reference object.
508             */
509
510            if ((Opcode == AML_STORE_OP) &&
511                ((*StackPtr)->Common.Type == INTERNAL_TYPE_REFERENCE) &&
512                ((*StackPtr)->Reference.OpCode == AML_INDEX_OP))
513            {
514                break;
515            }
516
517            /* All others must be resolved */
518
519            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
520            if (ACPI_FAILURE (Status))
521            {
522                goto Cleanup;
523            }
524
525            /* All types OK, so we don't perform any typechecks */
526
527            break;
528
529
530        case ARGI_DATAOBJECT:
531            /*
532             * ARGI_DATAOBJECT is only used by the SizeOf operator.
533             *
534             * The ACPI specification allows SizeOf to return the size of
535             *  a Buffer, String or Package.  However, the MS ACPI.SYS AML
536             *  Interpreter also allows an Node reference to return without
537             *  error with a size of 4.
538             */
539
540            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
541            if (ACPI_FAILURE (Status))
542            {
543                goto Cleanup;
544            }
545
546            /* Need a buffer, string, package or Node reference */
547
548            if (((*StackPtr)->Common.Type != ACPI_TYPE_BUFFER) &&
549                ((*StackPtr)->Common.Type != ACPI_TYPE_STRING) &&
550                ((*StackPtr)->Common.Type != ACPI_TYPE_PACKAGE) &&
551                ((*StackPtr)->Common.Type != INTERNAL_TYPE_REFERENCE))
552            {
553                DEBUG_PRINT (ACPI_INFO,
554                    ("AmlResolveOperands: Needed Buf/Str/Pkg, found %s Obj=%p\n",
555                    AcpiCmGetTypeName (ObjectType), *StackPtr));
556                Status = AE_AML_OPERAND_TYPE;
557                goto Cleanup;
558            }
559
560            /*
561             * If this is a reference, only allow a reference to an Node.
562             */
563            if ((*StackPtr)->Common.Type == INTERNAL_TYPE_REFERENCE)
564            {
565                if (!(*StackPtr)->Reference.Node)
566                {
567                    DEBUG_PRINT (ACPI_INFO,
568                        ("AmlResolveOperands: Needed Node reference, found %s Obj=%p\n",
569                        AcpiCmGetTypeName (ObjectType), *StackPtr));
570                    Status = AE_AML_OPERAND_TYPE;
571                    goto Cleanup;
572                }
573            }
574
575            break;
576
577
578        case ARGI_COMPLEXOBJ:
579
580            Status = AcpiAmlResolveToValue (StackPtr, WalkState);
581            if (ACPI_FAILURE (Status))
582            {
583                goto Cleanup;
584            }
585
586            /* Need a buffer or package */
587
588            if (((*StackPtr)->Common.Type != ACPI_TYPE_BUFFER) &&
589                ((*StackPtr)->Common.Type != ACPI_TYPE_PACKAGE))
590            {
591                DEBUG_PRINT (ACPI_INFO,
592                    ("AmlResolveOperands: Needed Package, Buf/Pkg %s Obj=%p\n",
593                    AcpiCmGetTypeName (ObjectType), *StackPtr));
594                Status = AE_AML_OPERAND_TYPE;
595                goto Cleanup;
596            }
597            break;
598
599
600        /* Unknown abbreviation passed in */
601
602        default:
603            DEBUG_PRINT (ACPI_ERROR,
604                ("AmlResolveOperands: Internal error - Unknown arg type %X\n",
605                ThisArgType));
606            Status = AE_BAD_PARAMETER;
607            goto Cleanup;
608
609        }   /* switch (*Types++) */
610
611
612        /*
613         * If more operands needed, decrement StackPtr to point
614         * to next operand on stack (after checking for underflow).
615         */
616        if (GET_CURRENT_ARG_TYPE (ArgTypes))
617        {
618            StackPtr--;
619        }
620
621    }   /* while (*Types) */
622
623
624Cleanup:
625
626  return_ACPI_STATUS (Status);
627}
628
629
630