Import acpica-20050211 from Intel.
[dragonfly.git] / sys / contrib / dev / acpica-unix-20050211 / compiler / asllookup.c
blob3ccee0f36edfffce83d9542a65d1a05ce5005cf0
1 /******************************************************************************
3 * Module Name: asllookup- Namespace lookup
4 * $Revision: 85 $
6 *****************************************************************************/
8 /******************************************************************************
10 * 1. Copyright Notice
12 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
13 * All rights reserved.
15 * 2. License
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.
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
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;
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
41 * 3. Conditions
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.
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.
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.
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
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.
81 * 4. Disclaimer and Export Compliance
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.
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.
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.
115 *****************************************************************************/
118 #include "aslcompiler.h"
119 #include "aslcompiler.y.h"
121 #include "acparser.h"
122 #include "amlcode.h"
123 #include "acnamesp.h"
124 #include "acdispat.h"
127 #define _COMPONENT ACPI_COMPILER
128 ACPI_MODULE_NAME ("asllookup")
131 /*******************************************************************************
133 * FUNCTION: LsDoOneNamespaceObject
135 * PARAMETERS: ACPI_WALK_CALLBACK
137 * RETURN: Status
139 * DESCRIPTION: Dump a namespace object to the namespace output file.
140 * Called during the walk of the namespace to dump all objects.
142 ******************************************************************************/
144 ACPI_STATUS
145 LsDoOneNamespaceObject (
146 ACPI_HANDLE ObjHandle,
147 UINT32 Level,
148 void *Context,
149 void **ReturnValue)
151 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
152 ACPI_PARSE_OBJECT *Op;
155 Gbl_NumNamespaceObjects++;
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));
162 Op = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
164 if (Op)
166 if (Op->Asl.ParseOpcode == PARSEOP_NAME)
168 Op = Op->Asl.Child;
171 switch (Node->Type)
173 case ACPI_TYPE_INTEGER:
175 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
176 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
178 Op = Op->Asl.Next;
181 if (Op->Asl.Value.Integer > ACPI_UINT32_MAX)
183 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Initial Value = 0x%X%X]",
184 ACPI_HIDWORD (Op->Asl.Value.Integer64), (UINT32) Op->Asl.Value.Integer);
186 else
188 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Initial Value = 0x%X]",
189 (UINT32) Op->Asl.Value.Integer);
191 break;
194 case ACPI_TYPE_STRING:
196 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
197 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
199 Op = Op->Asl.Next;
202 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Initial Value = \"%s\"]",
203 Op->Asl.Value.String);
204 break;
207 case ACPI_TYPE_LOCAL_REGION_FIELD:
209 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
210 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
212 Op = Op->Asl.Child;
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;
219 default:
220 /* Nothing to do for other types */
221 break;
225 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
226 return (AE_OK);
230 /*******************************************************************************
232 * FUNCTION: LsDisplayNamespace
234 * PARAMETERS: None
236 * RETURN: None
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.
242 ******************************************************************************/
244 ACPI_STATUS
245 LsDisplayNamespace (
246 void)
248 ACPI_STATUS Status;
251 if (!Gbl_NsOutputFlag)
253 return (AE_OK);
256 /* File header */
258 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
259 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count Depth Name - Type\n\n");
261 /* Walk entire namespace from the root */
263 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
264 ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject,
265 NULL, NULL);
266 return (Status);
270 /*******************************************************************************
272 * FUNCTION: LsCompareOneNamespaceObject
274 * PARAMETERS: ACPI_WALK_CALLBACK
276 * RETURN: Status
278 * DESCRIPTION: Compare name of one object.
280 ******************************************************************************/
282 ACPI_STATUS
283 LsCompareOneNamespaceObject (
284 ACPI_HANDLE ObjHandle,
285 UINT32 Level,
286 void *Context,
287 void **ReturnValue)
289 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
292 /* Simply check the name */
294 if (*((UINT32 *) (Context)) == Node->Name.Integer)
296 /* Abort walk if we found one instance */
298 return (AE_CTRL_TRUE);
301 return (AE_OK);
305 /*******************************************************************************
307 * FUNCTION: LkObjectExists
309 * PARAMETERS: Name - 4 char ACPI name
311 * RETURN: TRUE if name exists in namespace
313 * DESCRIPTION: Walk the namespace to find an object
315 ******************************************************************************/
317 BOOLEAN
318 LkObjectExists (
319 char *Name)
321 ACPI_STATUS Status;
324 /* Walk entire namespace from the supplied root */
326 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
327 ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject,
328 Name, NULL);
329 if (Status == AE_CTRL_TRUE)
331 /* At least one instance of the name was found */
333 return (TRUE);
336 return (FALSE);
340 /*******************************************************************************
342 * FUNCTION: LkCrossReferenceNamespace
344 * PARAMETERS: None
346 * RETURN: Status
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.
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.
358 ******************************************************************************/
360 ACPI_STATUS
361 LkCrossReferenceNamespace (
362 void)
364 ACPI_WALK_STATE *WalkState;
367 DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
370 * Create a new walk state for use when looking up names
371 * within the namespace (Passed as context to the callbacks)
373 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
374 if (!WalkState)
376 return AE_NO_MEMORY;
379 /* Walk the entire parse tree */
381 TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
382 LkNamespaceLocateEnd, WalkState);
383 return AE_OK;
387 /*******************************************************************************
389 * FUNCTION: LkCheckFieldRange
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
396 * RETURN: None
398 * DESCRIPTION: Check one field unit to make sure it fits in the parent
399 * op region.
401 * Note: AccessBitWidth must be either 8,16,32, or 64
403 ******************************************************************************/
405 void
406 LkCheckFieldRange (
407 ACPI_PARSE_OBJECT *Op,
408 UINT32 RegionBitLength,
409 UINT32 FieldBitOffset,
410 UINT32 FieldBitLength,
411 UINT32 AccessBitWidth)
413 UINT32 FieldEndBitOffset;
416 * Check each field unit against the region size. The entire
417 * field unit (start offset plus length) must fit within the
418 * region.
420 FieldEndBitOffset = FieldBitOffset + FieldBitLength;
422 if (FieldEndBitOffset > RegionBitLength)
424 /* Field definition itself is beyond the end-of-region */
426 AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
427 return;
431 * Now check that the field plus AccessWidth doesn't go beyond
432 * the end-of-region. Assumes AccessBitWidth is a power of 2
434 FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
436 if (FieldEndBitOffset > RegionBitLength)
438 /* Field definition combined with the access is beyond EOR */
440 AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
444 /*******************************************************************************
446 * FUNCTION: LkNamespaceLocateBegin
448 * PARAMETERS: ASL_WALK_CALLBACK
450 * RETURN: Status
452 * DESCRIPTION: Descending callback used during cross-reference. For named
453 * object references, attempt to locate the name in the
454 * namespace.
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.
461 ******************************************************************************/
463 ACPI_STATUS
464 LkNamespaceLocateBegin (
465 ACPI_PARSE_OBJECT *Op,
466 UINT32 Level,
467 void *Context)
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;
484 ACPI_FUNCTION_TRACE_PTR ("LkNamespaceLocateBegin", Op);
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
493 if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
495 return (AE_OK);
498 /* We are only interested in opcodes that have an associated name */
500 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
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))
508 return (AE_OK);
512 * We must enable the "search-to-root" for single NameSegs, but
513 * we have to be very careful about opening up scopes
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))
521 * These are name references, do not push the scope stack
522 * for them.
524 Flags |= ACPI_NS_DONT_OPEN_SCOPE;
527 /* Get the NamePath from the appropriate place */
529 if (OpInfo->Flags & AML_NAMED)
531 /* For all NAMED operators, the name reference is the first child */
533 Path = Op->Asl.Child->Asl.Value.String;
534 if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
537 * ALIAS is the only oddball opcode, the name declaration
538 * (alias name) is the second operand
540 Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
543 else if (OpInfo->Flags & AML_CREATE)
545 /* Name must appear as the last parameter */
547 NextOp = Op->Asl.Child;
548 while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
550 NextOp = NextOp->Asl.Next;
552 Path = NextOp->Asl.Value.String;
554 else
556 Path = Op->Asl.Value.String;
559 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
560 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
563 * Lookup the name in the namespace. Name must exist at this point, or it
564 * is an invalid reference.
566 * The namespace is also used as a lookup table for references to resource
567 * descriptors and the fields within them.
569 Gbl_NsLookupCount++;
571 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
572 ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
573 if (ACPI_FAILURE (Status))
575 if (Status == AE_NOT_FOUND)
578 * We didn't find the name reference by path -- we can qualify this
579 * a little better before we print an error message
581 if (strlen (Path) == ACPI_NAME_SIZE)
583 /* A simple, one-segment ACPI name */
585 if (LkObjectExists (Path))
587 /* There exists such a name, but we couldn't get to it from this scope */
589 AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op, Op->Asl.ExternalName);
591 else
593 /* The name doesn't exist, period */
595 AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName);
598 else
600 /* Check for a fully qualified path */
602 if (Path[0] == AML_ROOT_PREFIX)
604 /* Gave full path, the object does not exist */
606 AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName);
608 else
610 /* We can't tell whether it doesn't exist or just can't be reached. */
612 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, Op->Asl.ExternalName);
616 Status = AE_OK;
618 return (Status);
621 /* Attempt to optimize the NamePath */
623 OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
626 * Dereference an alias. (A name reference that is an alias.)
627 * Aliases are not nested; The alias always points to the final object
629 if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) && (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
631 /* This node points back to the original PARSEOP_ALIAS */
633 NextOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
635 /* The first child is the alias target op */
637 NextOp = NextOp->Asl.Child;
639 /* Who in turn points back to original target alias node */
641 if (NextOp->Asl.Node)
643 Node = NextOp->Asl.Node;
645 else
647 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "Missing alias link");
651 /* 1) Check for a reference to a resource descriptor */
653 else if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
654 (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
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
662 Temp = (UINT32) Node->OwnerId;
663 if (Node->Flags & ANOBJ_IS_BIT_OFFSET)
665 Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;
668 /* Perform BitOffset <--> ByteOffset conversion if necessary */
670 switch (Op->Asl.Parent->Asl.AmlOpcode)
672 case AML_CREATE_FIELD_OP:
674 /* We allow a Byte offset to Bit Offset conversion for this op */
676 if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
678 /* Simply multiply byte offset times 8 to get bit offset */
680 Temp = ACPI_MUL_8 (Temp);
682 break;
685 case AML_CREATE_BIT_FIELD_OP:
687 /* This op requires a Bit Offset */
689 if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
691 AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);
693 break;
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:
702 /* These Ops require Byte offsets */
704 if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
706 AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);
708 break;
711 default:
712 /* Nothing to do for other opcodes */
713 break;
716 /* Now convert this node to an integer whose value is the field offset */
718 Op->Asl.AmlLength = 0;
719 Op->Asl.ParseOpcode = PARSEOP_INTEGER;
720 Op->Asl.Value.Integer = (UINT64) Temp;
721 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
723 OpcGenerateAmlOpcode (Op);
726 /* 2) Check for a method invocation */
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)) ||
733 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
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.
742 if (Node->Type != ACPI_TYPE_METHOD)
744 sprintf (MsgBuffer, "%s is a %s", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
746 AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
747 return (AE_OK);
750 /* Save the method node in the caller's op */
752 Op->Asl.Node = Node;
753 if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
755 return (AE_OK);
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
763 Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
764 UtSetParseOpName (Op);
766 PassedArgs = 0;
767 NextOp = Op->Asl.Child;
769 while (NextOp)
771 PassedArgs++;
772 NextOp = NextOp->Asl.Next;
775 if (Node->OwnerId != ASL_EXTERNAL_METHOD)
778 * Check the parsed arguments with the number expected by the
779 * method declaration itself
781 if (PassedArgs != Node->OwnerId)
783 sprintf (MsgBuffer, "%s requires %d", Op->Asl.ExternalName,
784 Node->OwnerId);
786 if (PassedArgs < Node->OwnerId)
788 AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
790 else
792 AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
799 * 3) Check for an ASL Field definition
801 else if ((Op->Asl.Parent) &&
802 ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD) ||
803 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
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.
811 * Note: Index fields do not directly reference an operation region,
812 * thus they are not included in this check.
814 if (Op == Op->Asl.Parent->Asl.Child)
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.
821 OwningOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
822 Op->Asl.Parent->Asl.ExtraValue = ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
824 /* Examine the field access width */
826 switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
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;
835 case AML_FIELD_ACCESS_WORD:
836 MinimumLength = 2;
837 break;
839 case AML_FIELD_ACCESS_DWORD:
840 MinimumLength = 4;
841 break;
843 case AML_FIELD_ACCESS_QWORD:
844 MinimumLength = 8;
845 break;
849 * Is the region at least as big as the access width?
850 * Note: DataTableRegions have 0 length
852 if (((UINT32) OwningOp->Asl.Value.Integer) &&
853 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
855 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
859 * Check EC/CMOS/SMBUS fields to make sure that the correct
860 * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
862 SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
863 switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
865 case REGION_EC:
866 case REGION_CMOS:
868 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
870 AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
872 break;
874 case REGION_SMBUS:
876 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
878 AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
880 break;
882 default:
884 /* Nothing to do for other address spaces */
885 break;
888 else
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.
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)
900 if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
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);
911 Op->Asl.Node = Node;
912 return (Status);
916 /*******************************************************************************
918 * FUNCTION: LkNamespaceLocateEnd
920 * PARAMETERS: ASL_WALK_CALLBACK
922 * RETURN: Status
924 * DESCRIPTION: Ascending callback used during cross reference. We only
925 * need to worry about scope management here.
927 ******************************************************************************/
929 ACPI_STATUS
930 LkNamespaceLocateEnd (
931 ACPI_PARSE_OBJECT *Op,
932 UINT32 Level,
933 void *Context)
935 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
936 const ACPI_OPCODE_INFO *OpInfo;
939 ACPI_FUNCTION_TRACE ("LkNamespaceLocateEnd");
942 /* We are only interested in opcodes that have an associated name */
944 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
945 if (!(OpInfo->Flags & AML_NAMED))
947 return (AE_OK);
950 /* Not interested in name references, we did not open a scope for them */
952 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
953 (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
954 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
956 return (AE_OK);
959 /* Pop the scope stack if necessary */
961 if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
964 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
965 "%s: Popping scope for Op %p\n",
966 AcpiUtGetTypeName (OpInfo->ObjectType), Op));
968 AcpiDsScopeStackPop (WalkState);
971 return (AE_OK);