1/******************************************************************************
2 *
3 * Module Name: asllookup- Namespace lookup
4 * $Revision: 83 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2004, 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
144ACPI_STATUS
145LsDoOneNamespaceObject (
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
244ACPI_STATUS
245LsDisplayNamespace (
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
282ACPI_STATUS
283LsCompareOneNamespaceObject (
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
317BOOLEAN
318LkObjectExists (
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
360ACPI_STATUS
361LkCrossReferenceNamespace (
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
405void
406LkCheckFieldRange (
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
463ACPI_STATUS
464LkNamespaceLocateBegin (
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
929ACPI_STATUS
930LkNamespaceLocateEnd (
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
2 *
3 * Module Name: asllookup- Namespace lookup
4 * $Revision: 83 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2004, 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
144ACPI_STATUS
145LsDoOneNamespaceObject (
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
244ACPI_STATUS
245LsDisplayNamespace (
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
282ACPI_STATUS
283LsCompareOneNamespaceObject (
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
317BOOLEAN
318LkObjectExists (
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
360ACPI_STATUS
361LkCrossReferenceNamespace (
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
405void
406LkCheckFieldRange (
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
463ACPI_STATUS
464LkNamespaceLocateBegin (
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
929ACPI_STATUS
930LkNamespaceLocateEnd (
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