Some laptops return other values for working toucpads. Allow test_aux_port to
[dragonfly.git] / sys / contrib / dev / acpica-unix-20031203 / compiler / asllookup.c
1 /******************************************************************************
2  *
3  * Module Name: asllookup- Namespace lookup
4  *              $Revision: 82 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116
117
118 #include "aslcompiler.h"
119 #include "aslcompiler.y.h"
120
121 #include "acparser.h"
122 #include "amlcode.h"
123 #include "acnamesp.h"
124 #include "acdispat.h"
125
126
127 #define _COMPONENT          ACPI_COMPILER
128         ACPI_MODULE_NAME    ("asllookup")
129
130
131 /*******************************************************************************
132  *
133  * FUNCTION:    LsDoOneNamespaceObject
134  *
135  * PARAMETERS:  ACPI_WALK_CALLBACK
136  *
137  * RETURN:      Status
138  *
139  * DESCRIPTION: Dump a namespace object to the namespace output file.
140  *              Called during the walk of the namespace to dump all objects.
141  *
142  ******************************************************************************/
143
144 ACPI_STATUS
145 LsDoOneNamespaceObject (
146     ACPI_HANDLE             ObjHandle,
147     UINT32                  Level,
148     void                    *Context,
149     void                    **ReturnValue)
150 {
151     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
152     ACPI_PARSE_OBJECT       *Op;
153
154
155     Gbl_NumNamespaceObjects++;
156
157     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5d  [%d]  %*s %4.4s - %s",
158                         Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
159                         &Node->Name,
160                         AcpiUtGetTypeName (Node->Type));
161
162     Op = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
163
164     if (Op)
165     {
166         if (Op->Asl.ParseOpcode == PARSEOP_NAME)
167         {
168             Op = Op->Asl.Child;
169         }
170
171         switch (Node->Type)
172         {
173         case ACPI_TYPE_INTEGER:
174
175             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
176                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
177             {
178                 Op = Op->Asl.Next;
179             }
180
181             if (Op->Asl.Value.Integer > ACPI_UINT32_MAX)
182             {
183                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "    [Initial Value = 0x%X%X]",
184                             ACPI_HIDWORD (Op->Asl.Value.Integer64), (UINT32) Op->Asl.Value.Integer);
185             }
186             else
187             {
188                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "    [Initial Value = 0x%X]",
189                             (UINT32) Op->Asl.Value.Integer);
190             }
191             break;
192
193
194         case ACPI_TYPE_STRING:
195
196             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
197                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
198             {
199                 Op = Op->Asl.Next;
200             }
201
202             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "    [Initial Value = \"%s\"]",
203                         Op->Asl.Value.String);
204             break;
205
206
207         case ACPI_TYPE_LOCAL_REGION_FIELD:
208
209             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
210                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
211             {
212                 Op = Op->Asl.Child;
213             }
214             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "    [Offset 0x%02X, Length 0x%02X]",
215                         Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
216             break;
217
218
219         default:
220             /* Nothing to do for other types */
221             break;
222         }
223     }
224
225     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
226     return (AE_OK);
227 }
228
229
230 /*******************************************************************************
231  *
232  * FUNCTION:    LsDisplayNamespace
233  *
234  * PARAMETERS:  None
235  *
236  * RETURN:      None
237  *
238  * DESCRIPTION: Walk the namespace an display information about each node
239  *              in the tree.  Information is written to the optional
240  *              namespace output file.
241  *
242  ******************************************************************************/
243
244 ACPI_STATUS
245 LsDisplayNamespace (
246     void)
247 {
248     ACPI_STATUS             Status;
249
250
251     if (!Gbl_NsOutputFlag)
252     {
253         return (AE_OK);
254     }
255
256     /* File header */
257
258     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
259     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");
260
261     /* Walk entire namespace from the root */
262
263     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
264                                 ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject,
265                                 NULL, NULL);
266     return (Status);
267 }
268
269
270 /*******************************************************************************
271  *
272  * FUNCTION:    LsCompareOneNamespaceObject
273  *
274  * PARAMETERS:  ACPI_WALK_CALLBACK
275  *
276  * RETURN:      Status
277  *
278  * DESCRIPTION: Compare name of one object.
279  *
280  ******************************************************************************/
281
282 ACPI_STATUS
283 LsCompareOneNamespaceObject (
284     ACPI_HANDLE             ObjHandle,
285     UINT32                  Level,
286     void                    *Context,
287     void                    **ReturnValue)
288 {
289     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
290
291
292     /* Simply check the name */
293
294     if (*((UINT32 *) (Context)) == Node->Name.Integer)
295     {
296         /* Abort walk if we found one instance */
297
298         return (AE_CTRL_TRUE);
299     }
300
301     return (AE_OK);
302 }
303
304
305 /*******************************************************************************
306  *
307  * FUNCTION:    LkObjectExists
308  *
309  * PARAMETERS:  Name            - 4 char ACPI name
310  *
311  * RETURN:      TRUE if name exists in namespace
312  *
313  * DESCRIPTION: Walk the namespace to find an object
314  *
315  ******************************************************************************/
316
317 BOOLEAN
318 LkObjectExists (
319     char                    *Name)
320 {
321     ACPI_STATUS             Status;
322
323
324     /* Walk entire namespace from the supplied root */
325
326     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
327                                 ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject,
328                                 Name, NULL);
329     if (Status == AE_CTRL_TRUE)
330     {
331         /* At least one instance of the name was found */
332
333         return (TRUE);
334     }
335
336     return (FALSE);
337 }
338
339
340 /*******************************************************************************
341  *
342  * FUNCTION:    LkCrossReferenceNamespace
343  *
344  * PARAMETERS:  None
345  *
346  * RETURN:      Status
347  *
348  * DESCRIPTION: Perform a cross reference check of the parse tree against the
349  *              namespace.  Every named referenced within the parse tree
350  *              should be get resolved with a namespace lookup.  If not, the
351  *              original reference in the ASL code is invalid -- i.e., refers
352  *              to a non-existent object.
353  *
354  * NOTE:  The ASL "External" operator causes the name to be inserted into the
355  *        namespace so that references to the external name will be resolved
356  *        correctly here.
357  *
358  ******************************************************************************/
359
360 ACPI_STATUS
361 LkCrossReferenceNamespace (
362     void)
363 {
364     ACPI_WALK_STATE         *WalkState;
365
366
367     DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
368
369     /*
370      * Create a new walk state for use when looking up names
371      * within the namespace (Passed as context to the callbacks)
372      */
373     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
374     if (!WalkState)
375     {
376         return AE_NO_MEMORY;
377     }
378
379     /* Walk the entire parse tree */
380
381     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
382                         LkNamespaceLocateEnd, WalkState);
383     return AE_OK;
384 }
385
386
387 /*******************************************************************************
388  *
389  * FUNCTION:    LkCheckFieldRange
390  *
391  * PARAMETERS:  RegionBitLength     - Length of entire parent region
392  *              FieldBitOffset      - Start of the field unit (within region)
393  *              FieldBitLength      - Entire length of field unit
394  *              AccessBitWidth      - Access width of the field unit
395  *
396  * RETURN:      None
397  *
398  * DESCRIPTION: Check one field unit to make sure it fits in the parent
399  *              op region.
400  *
401  * Note: AccessBitWidth must be either 8,16,32, or 64
402  *
403  ******************************************************************************/
404
405 void
406 LkCheckFieldRange (
407     ACPI_PARSE_OBJECT       *Op,
408     UINT32                  RegionBitLength,
409     UINT32                  FieldBitOffset,
410     UINT32                  FieldBitLength,
411     UINT32                  AccessBitWidth)
412 {
413     UINT32                  FieldEndBitOffset;
414
415     /*
416      * Check each field unit against the region size.  The entire
417      * field unit (start offset plus length) must fit within the
418      * region.
419      */
420     FieldEndBitOffset = FieldBitOffset + FieldBitLength;
421
422     if (FieldEndBitOffset > RegionBitLength)
423     {
424         /* Field definition itself is beyond the end-of-region */
425
426         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
427         return;
428     }
429
430     /*
431      * Now check that the field plus AccessWidth doesn't go beyond
432      * the end-of-region.  Assumes AccessBitWidth is a power of 2
433      */
434     FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
435
436     if (FieldEndBitOffset > RegionBitLength)
437     {
438         /* Field definition combined with the access is beyond EOR */
439
440         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
441     }
442 }
443
444 /*******************************************************************************
445  *
446  * FUNCTION:    LkNamespaceLocateBegin
447  *
448  * PARAMETERS:  ASL_WALK_CALLBACK
449  *
450  * RETURN:      Status
451  *
452  * DESCRIPTION: Descending callback used during cross-reference.  For named
453  *              object references, attempt to locate the name in the
454  *              namespace.
455  *
456  * NOTE: ASL references to named fields within resource descriptors are
457  *       resolved to integer values here.  Therefore, this step is an
458  *       important part of the code generation.  We don't know that the
459  *       name refers to a resource descriptor until now.
460  *
461  ******************************************************************************/
462
463 ACPI_STATUS
464 LkNamespaceLocateBegin (
465     ACPI_PARSE_OBJECT       *Op,
466     UINT32                  Level,
467     void                    *Context)
468 {
469     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
470     ACPI_NAMESPACE_NODE     *Node;
471     ACPI_STATUS             Status;
472     ACPI_OBJECT_TYPE        ObjectType;
473     char                    *Path;
474     UINT8                   PassedArgs;
475     ACPI_PARSE_OBJECT       *NextOp;
476     ACPI_PARSE_OBJECT       *OwningOp;
477     ACPI_PARSE_OBJECT       *SpaceIdOp;
478     UINT32                  MinimumLength;
479     UINT32                  Temp;
480     const ACPI_OPCODE_INFO  *OpInfo;
481     UINT32                  Flags;
482
483
484     ACPI_FUNCTION_TRACE_PTR ("LkNamespaceLocateBegin", Op);
485
486     /*
487      * If this node is the actual declaration of a name
488      * [such as the XXXX name in "Method (XXXX)"],
489      * we are not interested in it here.  We only care about names that are
490      * references to other objects within the namespace and the parent objects
491      * of name declarations
492      */
493     if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
494     {
495         return (AE_OK);
496     }
497
498     /* We are only interested in opcodes that have an associated name */
499
500     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
501
502     if ((!(OpInfo->Flags & AML_NAMED)) &&
503         (!(OpInfo->Flags & AML_CREATE)) &&
504         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
505         (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
506         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
507     {
508         return (AE_OK);
509     }
510
511     /*
512      * We must enable the "search-to-root" for single NameSegs, but
513      * we have to be very careful about opening up scopes
514      */
515     Flags = ACPI_NS_SEARCH_PARENT;
516     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
517         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
518         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
519     {
520         /*
521          * These are name references, do not push the scope stack
522          * for them.
523          */
524         Flags |= ACPI_NS_DONT_OPEN_SCOPE;
525     }
526
527     /* Get the NamePath from the appropriate place */
528
529     if (OpInfo->Flags & AML_NAMED)
530     {
531         /* For all NAMED operators, the name reference is the first child */
532
533         Path = Op->Asl.Child->Asl.Value.String;
534         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
535         {
536             /*
537              * ALIAS is the only oddball opcode, the name declaration
538              * (alias name) is the second operand
539              */
540             Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
541         }
542     }
543     else if (OpInfo->Flags & AML_CREATE)
544     {
545         /* Name must appear as the last parameter */
546
547         NextOp = Op->Asl.Child;
548         while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
549         {
550             NextOp = NextOp->Asl.Next;
551         }
552         Path = NextOp->Asl.Value.String;
553     }
554     else
555     {
556         Path = Op->Asl.Value.String;
557     }
558
559     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
560     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
561
562     /*
563      * Lookup the name in the namespace.  Name must exist at this point, or it
564      * is an invalid reference.
565      *
566      * The namespace is also used as a lookup table for references to resource
567      * descriptors and the fields within them.
568      */
569     Gbl_NsLookupCount++;
570
571     Status = AcpiNsLookup (WalkState->ScopeInfo,  Path, ObjectType,
572                     ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
573     if (ACPI_FAILURE (Status))
574     {
575         if (Status == AE_NOT_FOUND)
576         {
577             /*
578              * We didn't find the name reference by path -- we can qualify this
579              * a little better before we print an error message
580              */
581             if (strlen (Path) == ACPI_NAME_SIZE)
582             {
583                 /* A simple, one-segment ACPI name */
584
585                 if (LkObjectExists (Path))
586                 {
587                     /* There exists such a name, but we couldn't get to it from this scope */
588
589                     AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op, Op->Asl.ExternalName);
590                 }
591                 else
592                 {
593                     /* The name doesn't exist, period */
594
595                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName);
596                 }
597             }
598             else
599             {
600                 /* Check for a fully qualified path */
601
602                 if (Path[0] == AML_ROOT_PREFIX)
603                 {
604                     /* Gave full path, the object does not exist */
605
606                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName);
607                 }
608                 else
609                 {
610                     /* We can't tell whether it doesn't exist or just can't be reached. */
611
612                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, Op->Asl.ExternalName);
613                 }
614             }
615
616             Status = AE_OK;
617         }
618         return (Status);
619     }
620
621     /* Attempt to optimize the NamePath */
622
623     OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
624
625     /*
626      * Dereference an alias. (A name reference that is an alias.)
627      * Aliases are not nested;  The alias always points to the final object
628      */
629     if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) && (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
630     {
631         /* This node points back to the original PARSEOP_ALIAS */
632
633         NextOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
634
635         /* The first child is the alias target op */
636
637         NextOp = NextOp->Asl.Child;
638
639         /* Who in turn points back to original target alias node */
640
641         if (NextOp->Asl.Node)
642         {
643             Node = NextOp->Asl.Node;
644         }
645         else
646         {
647             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "Missing alias link");
648         }
649     }
650
651     /* 1) Check for a reference to a resource descriptor */
652
653     else if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
654              (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
655     {
656         /*
657          * This was a reference to a field within a resource descriptor.  Extract
658          * the associated field offset (either a bit or byte offset depending on
659          * the field type) and change the named reference into an integer for
660          * AML code generation
661          */
662         Temp = (UINT32) Node->OwnerId;
663         if (Node->Flags & ANOBJ_IS_BIT_OFFSET)
664         {
665             Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;
666         }
667
668         /* Perform BitOffset <--> ByteOffset conversion if necessary */
669
670         switch (Op->Asl.Parent->Asl.AmlOpcode)
671         {
672         case AML_CREATE_FIELD_OP:
673
674             /* We allow a Byte offset to Bit Offset conversion for this op */
675
676             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
677             {
678                 /* Simply multiply byte offset times 8 to get bit offset */
679
680                 Temp = ACPI_MUL_8 (Temp);
681             }
682             break;
683
684
685         case AML_CREATE_BIT_FIELD_OP:
686
687             /* This op requires a Bit Offset */
688
689             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
690             {
691                 AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);
692             }
693             break;
694
695
696         case AML_CREATE_BYTE_FIELD_OP:
697         case AML_CREATE_WORD_FIELD_OP:
698         case AML_CREATE_DWORD_FIELD_OP:
699         case AML_CREATE_QWORD_FIELD_OP:
700         case AML_INDEX_OP:
701
702             /* These Ops require Byte offsets */
703
704             if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
705             {
706                 AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);
707             }
708             break;
709
710
711         default:
712             /* Nothing to do for other opcodes */
713             break;
714         }
715
716         /* Now convert this node to an integer whose value is the field offset */
717
718         Op->Asl.ParseOpcode     = PARSEOP_INTEGER;
719         Op->Asl.Value.Integer   = (UINT64) Temp;
720         Op->Asl.CompileFlags   |= NODE_IS_RESOURCE_FIELD;
721
722         OpcGenerateAmlOpcode (Op);
723         Op->Asl.AmlLength = OpcSetOptimalIntegerSize (Op);
724     }
725
726     /* 2) Check for a method invocation */
727
728     else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
729                 (Node->Type == ACPI_TYPE_METHOD) &&
730                 (Op->Asl.Parent) &&
731                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
732
733                 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
734     {
735
736         /*
737          * There are two types of method invocation:
738          * 1) Invocation with arguments -- the parser recognizes this as a METHODCALL
739          * 2) Invocation with no arguments --the parser cannot determine that this is a method
740          *    invocation, therefore we have to figure it out here.
741          */
742         if (Node->Type != ACPI_TYPE_METHOD)
743         {
744             sprintf (MsgBuffer, "%s is a %s", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
745
746             AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
747             return (AE_OK);
748         }
749
750         /* Save the method node in the caller's op */
751
752         Op->Asl.Node = Node;
753         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
754         {
755             return (AE_OK);
756         }
757
758         /*
759          * This is a method invocation, with or without arguments.
760          * Count the number of arguments, each appears as a child
761          * under the parent node
762          */
763         Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
764         UtSetParseOpName (Op);
765
766         PassedArgs = 0;
767         NextOp     = Op->Asl.Child;
768
769         while (NextOp)
770         {
771             PassedArgs++;
772             NextOp = NextOp->Asl.Next;
773         }
774
775         if (Node->OwnerId != ASL_EXTERNAL_METHOD)
776         {
777             /*
778              * Check the parsed arguments with the number expected by the
779              * method declaration itself
780              */
781             if (PassedArgs != Node->OwnerId)
782             {
783                 sprintf (MsgBuffer, "%s requires %d", Op->Asl.ExternalName,
784                             Node->OwnerId);
785
786                 if (PassedArgs < Node->OwnerId)
787                 {
788                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
789                 }
790                 else
791                 {
792                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
793                 }
794             }
795         }
796     }
797
798     /*
799      * 3) Check for an ASL Field definition
800      */
801     else if ((Op->Asl.Parent) &&
802             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
803              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
804     {
805         /*
806          * Offset checking for fields.  If the parent operation region has a
807          * constant length (known at compile time), we can check fields
808          * defined in that region against the region length.  This will catch
809          * fields and field units that cannot possibly fit within the region.
810          *
811          * Note: Index fields do not directly reference an operation region,
812          * thus they are not included in this check.
813          */
814         if (Op == Op->Asl.Parent->Asl.Child)
815         {
816             /*
817              * This is the first child of the field node, which is
818              * the name of the region.  Get the parse node for the
819              * region -- which contains the length of the region.
820              */
821             OwningOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
822             Op->Asl.Parent->Asl.ExtraValue = ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
823
824             /* Examine the field access width */
825
826             switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
827             {
828             case AML_FIELD_ACCESS_ANY:
829             case AML_FIELD_ACCESS_BYTE:
830             case AML_FIELD_ACCESS_BUFFER:
831             default:
832                 MinimumLength = 1;
833                 break;
834
835             case AML_FIELD_ACCESS_WORD:
836                 MinimumLength = 2;
837                 break;
838
839             case AML_FIELD_ACCESS_DWORD:
840                 MinimumLength = 4;
841                 break;
842
843             case AML_FIELD_ACCESS_QWORD:
844                 MinimumLength = 8;
845                 break;
846             }
847
848             /*
849              * Is the region at least as big as the access width?
850              * Note: DataTableRegions have 0 length
851              */
852             if (((UINT32) OwningOp->Asl.Value.Integer) &&
853                 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
854             {
855                 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
856             }
857
858             /*
859              * Check EC/CMOS/SMBUS fields to make sure that the correct
860              * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
861              */
862             SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
863             switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
864             {
865             case REGION_EC:
866             case REGION_CMOS:
867
868                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
869                 {
870                     AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
871                 }
872                 break;
873
874             case REGION_SMBUS:
875
876                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
877                 {
878                     AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
879                 }
880                 break;
881
882             default:
883
884                 /* Nothing to do for other address spaces */
885                 break;
886             }
887         }
888         else
889         {
890             /*
891              * This is one element of the field list.  Check to make sure
892              * that it does not go beyond the end of the parent operation region.
893              *
894              * In the code below:
895              *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
896              *    Op->Asl.ExtraValue                  - Field start offset (bits)
897              *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
898              *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
899              */
900             if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
901             {
902                 LkCheckFieldRange (Op,
903                             Op->Asl.Parent->Asl.ExtraValue,
904                             Op->Asl.ExtraValue,
905                             (UINT32) Op->Asl.Child->Asl.Value.Integer,
906                             Op->Asl.Child->Asl.ExtraValue);
907             }
908         }
909     }
910
911     Op->Asl.Node = Node;
912     return (Status);
913 }
914
915
916 /*******************************************************************************
917  *
918  * FUNCTION:    LkNamespaceLocateEnd
919  *
920  * PARAMETERS:  ASL_WALK_CALLBACK
921  *
922  * RETURN:      Status
923  *
924  * DESCRIPTION: Ascending callback used during cross reference.  We only
925  *              need to worry about scope management here.
926  *
927  ******************************************************************************/
928
929 ACPI_STATUS
930 LkNamespaceLocateEnd (
931     ACPI_PARSE_OBJECT       *Op,
932     UINT32                  Level,
933     void                    *Context)
934 {
935     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
936     const ACPI_OPCODE_INFO  *OpInfo;
937
938
939     ACPI_FUNCTION_TRACE ("LkNamespaceLocateEnd");
940
941
942     /* We are only interested in opcodes that have an associated name */
943
944     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
945     if (!(OpInfo->Flags & AML_NAMED))
946     {
947         return (AE_OK);
948     }
949
950     /* Not interested in name references, we did not open a scope for them */
951
952     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
953         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
954         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
955     {
956         return (AE_OK);
957     }
958
959     /* Pop the scope stack if necessary */
960
961     if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
962     {
963
964         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
965             "%s: Popping scope for Op %p\n",
966             AcpiUtGetTypeName (OpInfo->ObjectType), Op));
967
968         AcpiDsScopeStackPop (WalkState);
969     }
970
971     return (AE_OK);
972 }
973
974