Subversion Repositories Kolibri OS

Rev

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