Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/******************************************************************************
2
 *
3
 * Module Name: asllookup- Namespace lookup
4
 *
5
 *****************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
11
 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12
 * All rights reserved.
13
 *
14
 * 2. License
15
 *
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
17
 * rights.  You may have additional license terms from the party that provided
18
 * you this software, covering your right to use that party's intellectual
19
 * property rights.
20
 *
21
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
 * copy of the source code appearing in this file ("Covered Code") an
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * make derivatives, distribute, use and display any portion of the Covered
26
 * Code in any form, with the right to sublicense such rights; and
27
 *
28
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
 * license (with the right to sublicense), under only those claims of Intel
30
 * patents that are infringed by the Original Intel Code, to make, use, sell,
31
 * offer to sell, and import the Covered Code and derivative works thereof
32
 * solely to the minimum extent necessary to exercise the above copyright
33
 * license, and in no event shall the patent license extend to any additions
34
 * to or modifications of the Original Intel Code.  No other license or right
35
 * is granted directly or by implication, estoppel or otherwise;
36
 *
37
 * The above copyright and patent license is granted only if the following
38
 * conditions are met:
39
 *
40
 * 3. Conditions
41
 *
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * Redistribution of source code of any substantial portion of the Covered
44
 * Code or modification with rights to further distribute source must include
45
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * Licensee must cause all Covered Code to which Licensee contributes to
48
 * contain a file documenting the changes Licensee made to create that Covered
49
 * Code and the date of any change.  Licensee must include in that file the
50
 * documentation of any changes made by any predecessor Licensee.  Licensee
51
 * must include a prominent statement that the modification is derived,
52
 * directly or indirectly, from Original Intel Code.
53
 *
54
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
 * Redistribution of source code of any substantial portion of the Covered
56
 * Code or modification without rights to further distribute source must
57
 * include the following Disclaimer and Export Compliance provision in the
58
 * documentation and/or other materials provided with distribution.  In
59
 * addition, Licensee may not authorize further sublicense of source of any
60
 * portion of the Covered Code, and must include terms to the effect that the
61
 * license from Licensee to its licensee is limited to the intellectual
62
 * property embodied in the software Licensee provides to its licensee, and
63
 * not to intellectual property embodied in modifications its licensee may
64
 * make.
65
 *
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * substantial portion of the Covered Code or modification must reproduce the
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * provision in the documentation and/or other materials provided with the
70
 * distribution.
71
 *
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * Intel Code.
74
 *
75
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
 * Intel shall be used in advertising or otherwise to promote the sale, use or
77
 * other dealings in products derived from or relating to the Covered Code
78
 * without prior written authorization from Intel.
79
 *
80
 * 4. Disclaimer and Export Compliance
81
 *
82
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * PARTICULAR PURPOSE.
89
 *
90
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * LIMITED REMEDY.
98
 *
99
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100
 * software or system incorporating such software without first obtaining any
101
 * required license or other approval from the U. S. Department of Commerce or
102
 * any other agency or department of the United States Government.  In the
103
 * event Licensee exports any such software from the United States or
104
 * re-exports any such software from a foreign destination, Licensee shall
105
 * ensure that the distribution and export/re-export of the software is in
106
 * compliance with all laws, regulations, orders, or other restrictions of the
107
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
 * any of its subsidiaries will export/re-export any technical data, process,
109
 * software, or service, directly or indirectly, to any country for which the
110
 * United States government or any agency thereof requires an export license,
111
 * other governmental approval, or letter of assurance, without first obtaining
112
 * such license, approval or letter.
113
 *
114
 *****************************************************************************/
115
 
116
 
117
#include "aslcompiler.h"
118
#include "aslcompiler.y.h"
119
 
120
#include "acparser.h"
121
#include "amlcode.h"
122
#include "acnamesp.h"
123
#include "acdispat.h"
124
 
125
 
126
#define _COMPONENT          ACPI_COMPILER
127
        ACPI_MODULE_NAME    ("asllookup")
128
 
129
/* Local prototypes */
130
 
131
static ACPI_STATUS
132
LsCompareOneNamespaceObject (
133
    ACPI_HANDLE             ObjHandle,
134
    UINT32                  Level,
135
    void                    *Context,
136
    void                    **ReturnValue);
137
 
138
static ACPI_STATUS
139
LsDoOneNamespaceObject (
140
    ACPI_HANDLE             ObjHandle,
141
    UINT32                  Level,
142
    void                    *Context,
143
    void                    **ReturnValue);
144
 
145
static BOOLEAN
146
LkObjectExists (
147
    char                    *Name);
148
 
149
static void
150
LkCheckFieldRange (
151
    ACPI_PARSE_OBJECT       *Op,
152
    UINT32                  RegionBitLength,
153
    UINT32                  FieldBitOffset,
154
    UINT32                  FieldBitLength,
155
    UINT32                  AccessBitWidth);
156
 
157
static ACPI_STATUS
158
LkNamespaceLocateBegin (
159
    ACPI_PARSE_OBJECT       *Op,
160
    UINT32                  Level,
161
    void                    *Context);
162
 
163
static ACPI_STATUS
164
LkNamespaceLocateEnd (
165
    ACPI_PARSE_OBJECT       *Op,
166
    UINT32                  Level,
167
    void                    *Context);
168
 
169
static ACPI_STATUS
170
LkIsObjectUsed (
171
    ACPI_HANDLE             ObjHandle,
172
    UINT32                  Level,
173
    void                    *Context,
174
    void                    **ReturnValue);
175
 
176
static ACPI_STATUS
177
LsDoOnePathname (
178
    ACPI_HANDLE             ObjHandle,
179
    UINT32                  Level,
180
    void                    *Context,
181
    void                    **ReturnValue);
182
 
183
void
184
LsSetupNsList (
185
    void                    *Handle);
186
 
187
ACPI_PARSE_OBJECT *
188
LkGetNameOp (
189
    ACPI_PARSE_OBJECT       *Op);
190
 
191
 
192
/*******************************************************************************
193
 *
194
 * FUNCTION:    LsDoOneNamespaceObject
195
 *
196
 * PARAMETERS:  ACPI_WALK_CALLBACK
197
 *
198
 * RETURN:      Status
199
 *
200
 * DESCRIPTION: Dump a namespace object to the namespace output file.
201
 *              Called during the walk of the namespace to dump all objects.
202
 *
203
 ******************************************************************************/
204
 
205
static ACPI_STATUS
206
LsDoOneNamespaceObject (
207
    ACPI_HANDLE             ObjHandle,
208
    UINT32                  Level,
209
    void                    *Context,
210
    void                    **ReturnValue)
211
{
212
    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
213
    ACPI_OPERAND_OBJECT     *ObjDesc;
214
    ACPI_PARSE_OBJECT       *Op;
215
 
216
 
217
    Gbl_NumNamespaceObjects++;
218
 
219
    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u  [%u]  %*s %4.4s - %s",
220
        Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
221
        &Node->Name,
222
        AcpiUtGetTypeName (Node->Type));
223
 
224
    Op = Node->Op;
225
    ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
226
 
227
    if (!Op)
228
    {
229
        FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
230
        return (AE_OK);
231
    }
232
 
233
 
234
    if ((ObjDesc) &&
235
        (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
236
    {
237
        switch (Node->Type)
238
        {
239
        case ACPI_TYPE_INTEGER:
240
 
241
            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
242
                "       [Initial Value   0x%8.8X%8.8X]",
243
                ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
244
            break;
245
 
246
 
247
        case ACPI_TYPE_STRING:
248
 
249
            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
250
                "        [Initial Value   \"%s\"]",
251
                ObjDesc->String.Pointer);
252
            break;
253
 
254
        default:
255
            /* Nothing to do for other types */
256
            break;
257
        }
258
 
259
    }
260
    else
261
    {
262
        switch (Node->Type)
263
        {
264
        case ACPI_TYPE_INTEGER:
265
 
266
            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
267
            {
268
                Op = Op->Asl.Child;
269
            }
270
            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
271
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
272
            {
273
                Op = Op->Asl.Next;
274
            }
275
            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
276
                "       [Initial Value   0x%8.8X%8.8X]",
277
                ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
278
            break;
279
 
280
 
281
        case ACPI_TYPE_STRING:
282
 
283
            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
284
            {
285
                Op = Op->Asl.Child;
286
            }
287
            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
288
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
289
            {
290
                Op = Op->Asl.Next;
291
            }
292
            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
293
                "        [Initial Value   \"%s\"]",
294
                Op->Asl.Value.String);
295
            break;
296
 
297
 
298
        case ACPI_TYPE_LOCAL_REGION_FIELD:
299
 
300
            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
301
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
302
            {
303
                Op = Op->Asl.Child;
304
            }
305
            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
306
                "   [Offset 0x%04X   Length 0x%04X bits]",
307
                Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
308
            break;
309
 
310
 
311
        case ACPI_TYPE_BUFFER_FIELD:
312
 
313
            switch (Op->Asl.ParseOpcode)
314
            {
315
            case PARSEOP_CREATEBYTEFIELD:
316
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BYTE  ( 8 bit)]");
317
                break;
318
 
319
            case PARSEOP_CREATEDWORDFIELD:
320
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [DWORD (32 bit)]");
321
                break;
322
 
323
            case PARSEOP_CREATEQWORDFIELD:
324
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [QWORD (64 bit)]");
325
                break;
326
 
327
            case PARSEOP_CREATEWORDFIELD:
328
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [WORD  (16 bit)]");
329
                break;
330
 
331
            case PARSEOP_CREATEBITFIELD:
332
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BIT   ( 1 bit)]");
333
                break;
334
 
335
            case PARSEOP_CREATEFIELD:
336
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [Arbitrary Bit Field]");
337
                break;
338
 
339
            default:
340
                break;
341
 
342
            }
343
            break;
344
 
345
 
346
        case ACPI_TYPE_PACKAGE:
347
 
348
            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
349
            {
350
                Op = Op->Asl.Child;
351
            }
352
            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
353
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
354
            {
355
                Op = Op->Asl.Next;
356
            }
357
            Op = Op->Asl.Child;
358
 
359
            if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
360
                (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
361
            {
362
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
363
                    "       [Initial Length  0x%.2X elements]",
364
                    Op->Asl.Value.Integer);
365
            }
366
            break;
367
 
368
 
369
        case ACPI_TYPE_BUFFER:
370
 
371
            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
372
            {
373
                Op = Op->Asl.Child;
374
            }
375
            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
376
                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
377
            {
378
                Op = Op->Asl.Next;
379
            }
380
            Op = Op->Asl.Child;
381
 
382
            if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
383
            {
384
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
385
                    "        [Initial Length  0x%.2X bytes]",
386
                    Op->Asl.Value.Integer);
387
            }
388
            break;
389
 
390
 
391
        case ACPI_TYPE_METHOD:
392
 
393
            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
394
                "        [Code Length     0x%.4X bytes]",
395
                Op->Asl.AmlSubtreeLength);
396
            break;
397
 
398
 
399
        case ACPI_TYPE_LOCAL_RESOURCE:
400
 
401
            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
402
                "  [Desc Offset     0x%.4X Bytes]", Node->Value);
403
            break;
404
 
405
 
406
        case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
407
 
408
            if (Node->Flags & 0x80)
409
            {
410
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
411
                    "   [Field Offset    0x%.4X Bits 0x%.4X Bytes]",
412
                    Node->Value, Node->Value / 8);
413
            }
414
            else
415
            {
416
                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
417
                    "   [Field Offset    0x%.4X Bytes]", Node->Value);
418
            }
419
            break;
420
 
421
 
422
        default:
423
            /* Nothing to do for other types */
424
            break;
425
        }
426
    }
427
 
428
    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
429
    return (AE_OK);
430
}
431
 
432
 
433
/*******************************************************************************
434
 *
435
 * FUNCTION:    LsSetupNsList
436
 *
437
 * PARAMETERS:  Handle          - local file handle
438
 *
439
 * RETURN:      None
440
 *
441
 * DESCRIPTION: Set the namespace output file to the input handle
442
 *
443
 ******************************************************************************/
444
 
445
void
446
LsSetupNsList (
447
    void                    *Handle)
448
{
449
 
450
    Gbl_NsOutputFlag = TRUE;
451
    Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
452
}
453
 
454
 
455
/*******************************************************************************
456
 *
457
 * FUNCTION:    LsDoOnePathname
458
 *
459
 * PARAMETERS:  ACPI_WALK_CALLBACK
460
 *
461
 * RETURN:      Status
462
 *
463
 * DESCRIPTION: Print the full pathname for a namespace node.
464
 *
465
 ******************************************************************************/
466
 
467
static ACPI_STATUS
468
LsDoOnePathname (
469
    ACPI_HANDLE             ObjHandle,
470
    UINT32                  Level,
471
    void                    *Context,
472
    void                    **ReturnValue)
473
{
474
    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
475
    ACPI_STATUS             Status;
476
    ACPI_BUFFER             TargetPath;
477
 
478
 
479
    TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
480
    Status = AcpiNsHandleToPathname (Node, &TargetPath);
481
    if (ACPI_FAILURE (Status))
482
    {
483
        return (Status);
484
    }
485
 
486
    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
487
    ACPI_FREE (TargetPath.Pointer);
488
 
489
    return (AE_OK);
490
}
491
 
492
 
493
/*******************************************************************************
494
 *
495
 * FUNCTION:    LsDisplayNamespace
496
 *
497
 * PARAMETERS:  None
498
 *
499
 * RETURN:      Status
500
 *
501
 * DESCRIPTION: Walk the namespace an display information about each node
502
 *              in the tree.  Information is written to the optional
503
 *              namespace output file.
504
 *
505
 ******************************************************************************/
506
 
507
ACPI_STATUS
508
LsDisplayNamespace (
509
    void)
510
{
511
    ACPI_STATUS             Status;
512
 
513
 
514
    if (!Gbl_NsOutputFlag)
515
    {
516
        return (AE_OK);
517
    }
518
 
519
    Gbl_NumNamespaceObjects = 0;
520
 
521
    /* File header */
522
 
523
    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
524
    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");
525
 
526
    /* Walk entire namespace from the root */
527
 
528
    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
529
                ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL,
530
                NULL, NULL);
531
 
532
    /* Print the full pathname for each namespace node */
533
 
534
    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
535
 
536
    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
537
                ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL,
538
                NULL, NULL);
539
 
540
    return (Status);
541
}
542
 
543
 
544
/*******************************************************************************
545
 *
546
 * FUNCTION:    LsCompareOneNamespaceObject
547
 *
548
 * PARAMETERS:  ACPI_WALK_CALLBACK
549
 *
550
 * RETURN:      Status
551
 *
552
 * DESCRIPTION: Compare name of one object.
553
 *
554
 ******************************************************************************/
555
 
556
static ACPI_STATUS
557
LsCompareOneNamespaceObject (
558
    ACPI_HANDLE             ObjHandle,
559
    UINT32                  Level,
560
    void                    *Context,
561
    void                    **ReturnValue)
562
{
563
    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
564
 
565
 
566
    /* Simply check the name */
567
 
568
    if (*((UINT32 *) (Context)) == Node->Name.Integer)
569
    {
570
        /* Abort walk if we found one instance */
571
 
572
        return (AE_CTRL_TRUE);
573
    }
574
 
575
    return (AE_OK);
576
}
577
 
578
 
579
/*******************************************************************************
580
 *
581
 * FUNCTION:    LkObjectExists
582
 *
583
 * PARAMETERS:  Name            - 4 char ACPI name
584
 *
585
 * RETURN:      TRUE if name exists in namespace
586
 *
587
 * DESCRIPTION: Walk the namespace to find an object
588
 *
589
 ******************************************************************************/
590
 
591
static BOOLEAN
592
LkObjectExists (
593
    char                    *Name)
594
{
595
    ACPI_STATUS             Status;
596
 
597
 
598
    /* Walk entire namespace from the supplied root */
599
 
600
    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
601
                ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL,
602
                Name, NULL);
603
    if (Status == AE_CTRL_TRUE)
604
    {
605
        /* At least one instance of the name was found */
606
 
607
        return (TRUE);
608
    }
609
 
610
    return (FALSE);
611
}
612
 
613
 
614
/*******************************************************************************
615
 *
616
 * FUNCTION:    LkGetNameOp
617
 *
618
 * PARAMETERS:  Op              - Current Op
619
 *
620
 * RETURN:      NameOp associated with the input op
621
 *
622
 * DESCRIPTION: Find the name declaration op associated with the operator
623
 *
624
 ******************************************************************************/
625
 
626
ACPI_PARSE_OBJECT *
627
LkGetNameOp (
628
    ACPI_PARSE_OBJECT       *Op)
629
{
630
    const ACPI_OPCODE_INFO  *OpInfo;
631
    ACPI_PARSE_OBJECT       *NameOp = Op;
632
 
633
 
634
    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
635
 
636
 
637
    /* Get the NamePath from the appropriate place */
638
 
639
    if (OpInfo->Flags & AML_NAMED)
640
    {
641
        /* For nearly all NAMED operators, the name reference is the first child */
642
 
643
        NameOp = Op->Asl.Child;
644
        if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
645
        {
646
            /*
647
             * ALIAS is the only oddball opcode, the name declaration
648
             * (alias name) is the second operand
649
             */
650
            NameOp = Op->Asl.Child->Asl.Next;
651
        }
652
    }
653
    else if (OpInfo->Flags & AML_CREATE)
654
    {
655
        /* Name must appear as the last parameter */
656
 
657
        NameOp = Op->Asl.Child;
658
        while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
659
        {
660
            NameOp = NameOp->Asl.Next;
661
        }
662
    }
663
 
664
    return (NameOp);
665
}
666
 
667
 
668
/*******************************************************************************
669
 *
670
 * FUNCTION:    LkIsObjectUsed
671
 *
672
 * PARAMETERS:  ACPI_WALK_CALLBACK
673
 *
674
 * RETURN:      Status
675
 *
676
 * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
677
 *              We have to be careful, because some types and names are
678
 *              typically or always unreferenced, we don't want to issue
679
 *              excessive warnings.
680
 *
681
 ******************************************************************************/
682
 
683
static ACPI_STATUS
684
LkIsObjectUsed (
685
    ACPI_HANDLE             ObjHandle,
686
    UINT32                  Level,
687
    void                    *Context,
688
    void                    **ReturnValue)
689
{
690
    ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
691
 
692
 
693
    /* Referenced flag is set during the namespace xref */
694
 
695
    if (Node->Flags & ANOBJ_IS_REFERENCED)
696
    {
697
        return (AE_OK);
698
    }
699
 
700
    /*
701
     * Ignore names that start with an underscore,
702
     * these are the reserved ACPI names and are typically not referenced,
703
     * they are called by the host OS.
704
     */
705
    if (Node->Name.Ascii[0] == '_')
706
    {
707
        return (AE_OK);
708
    }
709
 
710
    /* There are some types that are typically not referenced, ignore them */
711
 
712
    switch (Node->Type)
713
    {
714
    case ACPI_TYPE_DEVICE:
715
    case ACPI_TYPE_PROCESSOR:
716
    case ACPI_TYPE_POWER:
717
    case ACPI_TYPE_LOCAL_RESOURCE:
718
        return (AE_OK);
719
 
720
    default:
721
        break;
722
    }
723
 
724
    /* All others are valid unreferenced namespace objects */
725
 
726
    if (Node->Op)
727
    {
728
        AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED, LkGetNameOp (Node->Op), NULL);
729
    }
730
    return (AE_OK);
731
}
732
 
733
 
734
/*******************************************************************************
735
 *
736
 * FUNCTION:    LkFindUnreferencedObjects
737
 *
738
 * PARAMETERS:  None
739
 *
740
 * RETURN:      None
741
 *
742
 * DESCRIPTION: Namespace walk to find objects that are not referenced in any
743
 *              way. Must be called after the namespace has been cross
744
 *              referenced.
745
 *
746
 ******************************************************************************/
747
 
748
void
749
LkFindUnreferencedObjects (
750
    void)
751
{
752
 
753
    /* Walk entire namespace from the supplied root */
754
 
755
    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
756
                ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
757
                NULL, NULL);
758
}
759
 
760
 
761
/*******************************************************************************
762
 *
763
 * FUNCTION:    LkCrossReferenceNamespace
764
 *
765
 * PARAMETERS:  None
766
 *
767
 * RETURN:      Status
768
 *
769
 * DESCRIPTION: Perform a cross reference check of the parse tree against the
770
 *              namespace.  Every named referenced within the parse tree
771
 *              should be get resolved with a namespace lookup.  If not, the
772
 *              original reference in the ASL code is invalid -- i.e., refers
773
 *              to a non-existent object.
774
 *
775
 * NOTE:  The ASL "External" operator causes the name to be inserted into the
776
 *        namespace so that references to the external name will be resolved
777
 *        correctly here.
778
 *
779
 ******************************************************************************/
780
 
781
ACPI_STATUS
782
LkCrossReferenceNamespace (
783
    void)
784
{
785
    ACPI_WALK_STATE         *WalkState;
786
 
787
 
788
    DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
789
 
790
    /*
791
     * Create a new walk state for use when looking up names
792
     * within the namespace (Passed as context to the callbacks)
793
     */
794
    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
795
    if (!WalkState)
796
    {
797
        return AE_NO_MEMORY;
798
    }
799
 
800
    /* Walk the entire parse tree */
801
 
802
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
803
                        LkNamespaceLocateEnd, WalkState);
804
    return AE_OK;
805
}
806
 
807
 
808
/*******************************************************************************
809
 *
810
 * FUNCTION:    LkCheckFieldRange
811
 *
812
 * PARAMETERS:  RegionBitLength     - Length of entire parent region
813
 *              FieldBitOffset      - Start of the field unit (within region)
814
 *              FieldBitLength      - Entire length of field unit
815
 *              AccessBitWidth      - Access width of the field unit
816
 *
817
 * RETURN:      None
818
 *
819
 * DESCRIPTION: Check one field unit to make sure it fits in the parent
820
 *              op region.
821
 *
822
 * Note: AccessBitWidth must be either 8,16,32, or 64
823
 *
824
 ******************************************************************************/
825
 
826
static void
827
LkCheckFieldRange (
828
    ACPI_PARSE_OBJECT       *Op,
829
    UINT32                  RegionBitLength,
830
    UINT32                  FieldBitOffset,
831
    UINT32                  FieldBitLength,
832
    UINT32                  AccessBitWidth)
833
{
834
    UINT32                  FieldEndBitOffset;
835
 
836
 
837
    /*
838
     * Check each field unit against the region size.  The entire
839
     * field unit (start offset plus length) must fit within the
840
     * region.
841
     */
842
    FieldEndBitOffset = FieldBitOffset + FieldBitLength;
843
 
844
    if (FieldEndBitOffset > RegionBitLength)
845
    {
846
        /* Field definition itself is beyond the end-of-region */
847
 
848
        AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
849
        return;
850
    }
851
 
852
    /*
853
     * Now check that the field plus AccessWidth doesn't go beyond
854
     * the end-of-region.  Assumes AccessBitWidth is a power of 2
855
     */
856
    FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
857
 
858
    if (FieldEndBitOffset > RegionBitLength)
859
    {
860
        /* Field definition combined with the access is beyond EOR */
861
 
862
        AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
863
    }
864
}
865
 
866
/*******************************************************************************
867
 *
868
 * FUNCTION:    LkNamespaceLocateBegin
869
 *
870
 * PARAMETERS:  ASL_WALK_CALLBACK
871
 *
872
 * RETURN:      Status
873
 *
874
 * DESCRIPTION: Descending callback used during cross-reference.  For named
875
 *              object references, attempt to locate the name in the
876
 *              namespace.
877
 *
878
 * NOTE: ASL references to named fields within resource descriptors are
879
 *       resolved to integer values here.  Therefore, this step is an
880
 *       important part of the code generation.  We don't know that the
881
 *       name refers to a resource descriptor until now.
882
 *
883
 ******************************************************************************/
884
 
885
static ACPI_STATUS
886
LkNamespaceLocateBegin (
887
    ACPI_PARSE_OBJECT       *Op,
888
    UINT32                  Level,
889
    void                    *Context)
890
{
891
    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
892
    ACPI_NAMESPACE_NODE     *Node;
893
    ACPI_STATUS             Status;
894
    ACPI_OBJECT_TYPE        ObjectType;
895
    char                    *Path;
896
    UINT8                   PassedArgs;
897
    ACPI_PARSE_OBJECT       *NextOp;
898
    ACPI_PARSE_OBJECT       *OwningOp;
899
    ACPI_PARSE_OBJECT       *SpaceIdOp;
900
    UINT32                  MinimumLength;
901
    UINT32                  Temp;
902
    const ACPI_OPCODE_INFO  *OpInfo;
903
    UINT32                  Flags;
904
 
905
 
906
    ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin, Op);
907
 
908
    /*
909
     * If this node is the actual declaration of a name
910
     * [such as the XXXX name in "Method (XXXX)"],
911
     * we are not interested in it here.  We only care about names that are
912
     * references to other objects within the namespace and the parent objects
913
     * of name declarations
914
     */
915
    if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
916
    {
917
        return (AE_OK);
918
    }
919
 
920
    /* We are only interested in opcodes that have an associated name */
921
 
922
    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
923
 
924
    if ((!(OpInfo->Flags & AML_NAMED)) &&
925
        (!(OpInfo->Flags & AML_CREATE)) &&
926
        (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
927
        (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
928
        (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
929
    {
930
        return (AE_OK);
931
    }
932
 
933
    /*
934
     * One special case: CondRefOf operator - we don't care if the name exists
935
     * or not at this point, just ignore it, the point of the operator is to
936
     * determine if the name exists at runtime.
937
     */
938
    if ((Op->Asl.Parent) &&
939
        (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
940
    {
941
        return (AE_OK);
942
    }
943
 
944
    /*
945
     * We must enable the "search-to-root" for single NameSegs, but
946
     * we have to be very careful about opening up scopes
947
     */
948
    Flags = ACPI_NS_SEARCH_PARENT;
949
    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
950
        (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
951
        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
952
    {
953
        /*
954
         * These are name references, do not push the scope stack
955
         * for them.
956
         */
957
        Flags |= ACPI_NS_DONT_OPEN_SCOPE;
958
    }
959
 
960
    /* Get the NamePath from the appropriate place */
961
 
962
    if (OpInfo->Flags & AML_NAMED)
963
    {
964
        /* For nearly all NAMED operators, the name reference is the first child */
965
 
966
        Path = Op->Asl.Child->Asl.Value.String;
967
        if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
968
        {
969
            /*
970
             * ALIAS is the only oddball opcode, the name declaration
971
             * (alias name) is the second operand
972
             */
973
            Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
974
        }
975
    }
976
    else if (OpInfo->Flags & AML_CREATE)
977
    {
978
        /* Name must appear as the last parameter */
979
 
980
        NextOp = Op->Asl.Child;
981
        while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
982
        {
983
            NextOp = NextOp->Asl.Next;
984
        }
985
        Path = NextOp->Asl.Value.String;
986
    }
987
    else
988
    {
989
        Path = Op->Asl.Value.String;
990
    }
991
 
992
    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
993
    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
994
        "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
995
 
996
    /*
997
     * Lookup the name in the namespace.  Name must exist at this point, or it
998
     * is an invalid reference.
999
     *
1000
     * The namespace is also used as a lookup table for references to resource
1001
     * descriptors and the fields within them.
1002
     */
1003
    Gbl_NsLookupCount++;
1004
 
1005
    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
1006
                ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
1007
    if (ACPI_FAILURE (Status))
1008
    {
1009
        if (Status == AE_NOT_FOUND)
1010
        {
1011
            /*
1012
             * We didn't find the name reference by path -- we can qualify this
1013
             * a little better before we print an error message
1014
             */
1015
            if (strlen (Path) == ACPI_NAME_SIZE)
1016
            {
1017
                /* A simple, one-segment ACPI name */
1018
 
1019
                if (LkObjectExists (Path))
1020
                {
1021
                    /*
1022
                     * There exists such a name, but we couldn't get to it
1023
                     * from this scope
1024
                     */
1025
                    AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
1026
                        Op->Asl.ExternalName);
1027
                }
1028
                else
1029
                {
1030
                    /* The name doesn't exist, period */
1031
 
1032
                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
1033
                        Op, Op->Asl.ExternalName);
1034
                }
1035
            }
1036
            else
1037
            {
1038
                /* Check for a fully qualified path */
1039
 
1040
                if (Path[0] == AML_ROOT_PREFIX)
1041
                {
1042
                    /* Gave full path, the object does not exist */
1043
 
1044
                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
1045
                        Op->Asl.ExternalName);
1046
                }
1047
                else
1048
                {
1049
                    /*
1050
                     * We can't tell whether it doesn't exist or just
1051
                     * can't be reached.
1052
                     */
1053
                    AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
1054
                        Op->Asl.ExternalName);
1055
                }
1056
            }
1057
 
1058
            Status = AE_OK;
1059
        }
1060
        return (Status);
1061
    }
1062
 
1063
    /* Check for a reference vs. name declaration */
1064
 
1065
    if (!(OpInfo->Flags & AML_NAMED) &&
1066
        !(OpInfo->Flags & AML_CREATE))
1067
    {
1068
        /* This node has been referenced, mark it for reference check */
1069
 
1070
        Node->Flags |= ANOBJ_IS_REFERENCED;
1071
    }
1072
 
1073
    /* Attempt to optimize the NamePath */
1074
 
1075
    OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
1076
 
1077
    /*
1078
     * 1) Dereference an alias (A name reference that is an alias)
1079
     *    Aliases are not nested, the alias always points to the final object
1080
     */
1081
    if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
1082
        (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
1083
    {
1084
        /* This node points back to the original PARSEOP_ALIAS */
1085
 
1086
        NextOp = Node->Op;
1087
 
1088
        /* The first child is the alias target op */
1089
 
1090
        NextOp = NextOp->Asl.Child;
1091
 
1092
        /* That in turn points back to original target alias node */
1093
 
1094
        if (NextOp->Asl.Node)
1095
        {
1096
            Node = NextOp->Asl.Node;
1097
        }
1098
 
1099
        /* Else - forward reference to alias, will be resolved later */
1100
    }
1101
 
1102
    /* 2) Check for a reference to a resource descriptor */
1103
 
1104
    if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1105
             (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1106
    {
1107
        /*
1108
         * This was a reference to a field within a resource descriptor.  Extract
1109
         * the associated field offset (either a bit or byte offset depending on
1110
         * the field type) and change the named reference into an integer for
1111
         * AML code generation
1112
         */
1113
        Temp = Node->Value;
1114
        if (Node->Flags & ANOBJ_IS_BIT_OFFSET)
1115
        {
1116
            Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;
1117
        }
1118
 
1119
        /* Perform BitOffset <--> ByteOffset conversion if necessary */
1120
 
1121
        switch (Op->Asl.Parent->Asl.AmlOpcode)
1122
        {
1123
        case AML_CREATE_FIELD_OP:
1124
 
1125
            /* We allow a Byte offset to Bit Offset conversion for this op */
1126
 
1127
            if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
1128
            {
1129
                /* Simply multiply byte offset times 8 to get bit offset */
1130
 
1131
                Temp = ACPI_MUL_8 (Temp);
1132
            }
1133
            break;
1134
 
1135
 
1136
        case AML_CREATE_BIT_FIELD_OP:
1137
 
1138
            /* This op requires a Bit Offset */
1139
 
1140
            if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
1141
            {
1142
                AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);
1143
            }
1144
            break;
1145
 
1146
 
1147
        case AML_CREATE_BYTE_FIELD_OP:
1148
        case AML_CREATE_WORD_FIELD_OP:
1149
        case AML_CREATE_DWORD_FIELD_OP:
1150
        case AML_CREATE_QWORD_FIELD_OP:
1151
        case AML_INDEX_OP:
1152
 
1153
            /* These Ops require Byte offsets */
1154
 
1155
            if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
1156
            {
1157
                AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);
1158
            }
1159
            break;
1160
 
1161
 
1162
        default:
1163
            /* Nothing to do for other opcodes */
1164
            break;
1165
        }
1166
 
1167
        /* Now convert this node to an integer whose value is the field offset */
1168
 
1169
        Op->Asl.AmlLength       = 0;
1170
        Op->Asl.ParseOpcode     = PARSEOP_INTEGER;
1171
        Op->Asl.Value.Integer   = (UINT64) Temp;
1172
        Op->Asl.CompileFlags   |= NODE_IS_RESOURCE_FIELD;
1173
 
1174
        OpcGenerateAmlOpcode (Op);
1175
    }
1176
 
1177
    /* 3) Check for a method invocation */
1178
 
1179
    else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
1180
                (Node->Type == ACPI_TYPE_METHOD) &&
1181
                (Op->Asl.Parent) &&
1182
                (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
1183
 
1184
                (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1185
    {
1186
 
1187
        /*
1188
         * A reference to a method within one of these opcodes is not an
1189
         * invocation of the method, it is simply a reference to the method.
1190
         */
1191
        if ((Op->Asl.Parent) &&
1192
           ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)      ||
1193
            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF)    ||
1194
            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
1195
        {
1196
            return (AE_OK);
1197
        }
1198
        /*
1199
         * There are two types of method invocation:
1200
         * 1) Invocation with arguments -- the parser recognizes this
1201
         *    as a METHODCALL.
1202
         * 2) Invocation with no arguments --the parser cannot determine that
1203
         *    this is a method invocation, therefore we have to figure it out
1204
         *    here.
1205
         */
1206
        if (Node->Type != ACPI_TYPE_METHOD)
1207
        {
1208
            sprintf (MsgBuffer, "%s is a %s",
1209
                    Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
1210
 
1211
            AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
1212
            return (AE_OK);
1213
        }
1214
 
1215
        /* Save the method node in the caller's op */
1216
 
1217
        Op->Asl.Node = Node;
1218
        if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
1219
        {
1220
            return (AE_OK);
1221
        }
1222
 
1223
        /*
1224
         * This is a method invocation, with or without arguments.
1225
         * Count the number of arguments, each appears as a child
1226
         * under the parent node
1227
         */
1228
        Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
1229
        UtSetParseOpName (Op);
1230
 
1231
        PassedArgs = 0;
1232
        NextOp     = Op->Asl.Child;
1233
 
1234
        while (NextOp)
1235
        {
1236
            PassedArgs++;
1237
            NextOp = NextOp->Asl.Next;
1238
        }
1239
 
1240
        if (Node->Value != ASL_EXTERNAL_METHOD)
1241
        {
1242
            /*
1243
             * Check the parsed arguments with the number expected by the
1244
             * method declaration itself
1245
             */
1246
            if (PassedArgs != Node->Value)
1247
            {
1248
                sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
1249
                            Node->Value);
1250
 
1251
                if (PassedArgs < Node->Value)
1252
                {
1253
                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
1254
                }
1255
                else
1256
                {
1257
                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
1258
                }
1259
            }
1260
        }
1261
    }
1262
 
1263
    /* 4) Check for an ASL Field definition */
1264
 
1265
    else if ((Op->Asl.Parent) &&
1266
            ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
1267
             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
1268
    {
1269
        /*
1270
         * Offset checking for fields.  If the parent operation region has a
1271
         * constant length (known at compile time), we can check fields
1272
         * defined in that region against the region length.  This will catch
1273
         * fields and field units that cannot possibly fit within the region.
1274
         *
1275
         * Note: Index fields do not directly reference an operation region,
1276
         * thus they are not included in this check.
1277
         */
1278
        if (Op == Op->Asl.Parent->Asl.Child)
1279
        {
1280
            /*
1281
             * This is the first child of the field node, which is
1282
             * the name of the region.  Get the parse node for the
1283
             * region -- which contains the length of the region.
1284
             */
1285
            OwningOp = Node->Op;
1286
            Op->Asl.Parent->Asl.ExtraValue =
1287
                ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
1288
 
1289
            /* Examine the field access width */
1290
 
1291
            switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
1292
            {
1293
            case AML_FIELD_ACCESS_ANY:
1294
            case AML_FIELD_ACCESS_BYTE:
1295
            case AML_FIELD_ACCESS_BUFFER:
1296
            default:
1297
                MinimumLength = 1;
1298
                break;
1299
 
1300
            case AML_FIELD_ACCESS_WORD:
1301
                MinimumLength = 2;
1302
                break;
1303
 
1304
            case AML_FIELD_ACCESS_DWORD:
1305
                MinimumLength = 4;
1306
                break;
1307
 
1308
            case AML_FIELD_ACCESS_QWORD:
1309
                MinimumLength = 8;
1310
                break;
1311
            }
1312
 
1313
            /*
1314
             * Is the region at least as big as the access width?
1315
             * Note: DataTableRegions have 0 length
1316
             */
1317
            if (((UINT32) OwningOp->Asl.Value.Integer) &&
1318
                ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
1319
            {
1320
                AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
1321
            }
1322
 
1323
            /*
1324
             * Check EC/CMOS/SMBUS fields to make sure that the correct
1325
             * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
1326
             */
1327
            SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
1328
            switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
1329
            {
1330
            case REGION_EC:
1331
            case REGION_CMOS:
1332
 
1333
                if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
1334
                {
1335
                    AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
1336
                }
1337
                break;
1338
 
1339
            case REGION_SMBUS:
1340
            case REGION_IPMI:
1341
 
1342
                if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
1343
                {
1344
                    AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
1345
                }
1346
                break;
1347
 
1348
            default:
1349
 
1350
                /* Nothing to do for other address spaces */
1351
                break;
1352
            }
1353
        }
1354
        else
1355
        {
1356
            /*
1357
             * This is one element of the field list.  Check to make sure
1358
             * that it does not go beyond the end of the parent operation region.
1359
             *
1360
             * In the code below:
1361
             *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
1362
             *    Op->Asl.ExtraValue                  - Field start offset (bits)
1363
             *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
1364
             *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
1365
             */
1366
            if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
1367
            {
1368
                LkCheckFieldRange (Op,
1369
                            Op->Asl.Parent->Asl.ExtraValue,
1370
                            Op->Asl.ExtraValue,
1371
                            (UINT32) Op->Asl.Child->Asl.Value.Integer,
1372
                            Op->Asl.Child->Asl.ExtraValue);
1373
            }
1374
        }
1375
    }
1376
 
1377
    Op->Asl.Node = Node;
1378
    return (Status);
1379
}
1380
 
1381
 
1382
/*******************************************************************************
1383
 *
1384
 * FUNCTION:    LkNamespaceLocateEnd
1385
 *
1386
 * PARAMETERS:  ASL_WALK_CALLBACK
1387
 *
1388
 * RETURN:      Status
1389
 *
1390
 * DESCRIPTION: Ascending callback used during cross reference.  We only
1391
 *              need to worry about scope management here.
1392
 *
1393
 ******************************************************************************/
1394
 
1395
static ACPI_STATUS
1396
LkNamespaceLocateEnd (
1397
    ACPI_PARSE_OBJECT       *Op,
1398
    UINT32                  Level,
1399
    void                    *Context)
1400
{
1401
    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1402
    const ACPI_OPCODE_INFO  *OpInfo;
1403
 
1404
 
1405
    ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd);
1406
 
1407
 
1408
    /* We are only interested in opcodes that have an associated name */
1409
 
1410
    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1411
    if (!(OpInfo->Flags & AML_NAMED))
1412
    {
1413
        return (AE_OK);
1414
    }
1415
 
1416
    /* Not interested in name references, we did not open a scope for them */
1417
 
1418
    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
1419
        (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
1420
        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1421
    {
1422
        return (AE_OK);
1423
    }
1424
 
1425
    /* Pop the scope stack if necessary */
1426
 
1427
    if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
1428
    {
1429
 
1430
        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1431
            "%s: Popping scope for Op %p\n",
1432
            AcpiUtGetTypeName (OpInfo->ObjectType), Op));
1433
 
1434
        (void) AcpiDsScopeStackPop (WalkState);
1435
    }
1436
 
1437
    return (AE_OK);
1438
}
1439