Subversion Repositories Kolibri OS

Rev

Rev 1498 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1498 Rev 2216
Line 1... Line -...
1
/******************************************************************************
-
 
2
 *
1
/******************************************************************************
3
 * Module Name: aslanalyze.c - check for semantic errors
2
 *
4
 *
3
 * Module Name: aslanalyze.c - Support functions for parse tree walks
5
 *****************************************************************************/
4
 *
6
 
5
 *****************************************************************************/
Line 7... Line 6...
7
/******************************************************************************
6
 
8
 *
7
/******************************************************************************
9
 * 1. Copyright Notice
8
 *
10
 *
9
 * 1. Copyright Notice
11
 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
10
 *
12
 * All rights reserved.
11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
13
 *
12
 * All rights reserved.
14
 * 2. License
13
 *
15
 *
14
 * 2. License
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
15
 *
Line 115... Line 114...
115
 
114
 *****************************************************************************/
Line 116... Line 115...
116
 
115
 
117
#include "aslcompiler.h"
116
 
118
#include "aslcompiler.y.h"
117
#include "aslcompiler.h"
119
#include "acparser.h"
-
 
-
 
118
#include "aslcompiler.y.h"
Line 120... Line 119...
120
#include "amlcode.h"
119
#include 
121
 
120
 
Line 122... Line -...
122
#define _COMPONENT          ACPI_COMPILER
-
 
123
        ACPI_MODULE_NAME    ("aslanalyze")
-
 
124
 
-
 
125
/* Local prototypes */
-
 
126
 
-
 
127
static UINT32
-
 
128
AnMapArgTypeToBtype (
-
 
129
    UINT32                  ArgType);
-
 
130
 
-
 
131
static UINT32
-
 
132
AnMapEtypeToBtype (
-
 
133
    UINT32                  Etype);
-
 
134
 
-
 
135
static void
-
 
136
AnFormatBtype (
-
 
137
    char                    *Buffer,
-
 
138
    UINT32                  Btype);
-
 
139
 
-
 
140
static UINT32
-
 
141
AnGetBtype (
-
 
142
    ACPI_PARSE_OBJECT       *Op);
-
 
143
 
-
 
144
static UINT32
-
 
145
AnMapObjTypeToBtype (
-
 
146
    ACPI_PARSE_OBJECT       *Op);
-
 
147
 
-
 
148
static BOOLEAN
-
 
149
AnLastStatementIsReturn (
-
 
150
    ACPI_PARSE_OBJECT       *Op);
-
 
151
 
-
 
152
static void
-
 
153
AnCheckMethodReturnValue (
-
 
154
    ACPI_PARSE_OBJECT       *Op,
-
 
155
    const ACPI_OPCODE_INFO  *OpInfo,
-
 
156
    ACPI_PARSE_OBJECT       *ArgOp,
-
 
157
    UINT32                  RequiredBtypes,
-
 
158
    UINT32                  ThisNodeBtype);
-
 
159
 
-
 
160
static BOOLEAN
-
 
161
AnIsInternalMethod (
-
 
162
    ACPI_PARSE_OBJECT       *Op);
-
 
163
 
-
 
164
static UINT32
-
 
165
AnGetInternalMethodReturnType (
-
 
166
    ACPI_PARSE_OBJECT       *Op);
-
 
167
 
-
 
168
BOOLEAN
-
 
Line 169... Line 121...
169
AnIsResultUsed (
121
 
170
    ACPI_PARSE_OBJECT       *Op);
122
#define _COMPONENT          ACPI_COMPILER
171
 
123
        ACPI_MODULE_NAME    ("aslanalyze")
172
 
124
 
Line 181... Line 133...
181
 * DESCRIPTION: Check for an internal control method.
133
 *
182
 *
134
 * DESCRIPTION: Check for an internal control method.
183
 ******************************************************************************/
135
 *
184
 
136
 ******************************************************************************/
Line 185... Line 137...
185
static BOOLEAN
137
 
186
AnIsInternalMethod (
138
BOOLEAN
187
    ACPI_PARSE_OBJECT       *Op)
139
AnIsInternalMethod (
188
{
140
    ACPI_PARSE_OBJECT       *Op)
Line 189... Line 141...
189
 
141
{
Line 208... Line 160...
208
 * DESCRIPTION: Get the return type of an internal method
160
 *
209
 *
161
 * DESCRIPTION: Get the return type of an internal method
210
 ******************************************************************************/
162
 *
211
 
163
 ******************************************************************************/
Line 212... Line 164...
212
static UINT32
164
 
213
AnGetInternalMethodReturnType (
165
UINT32
214
    ACPI_PARSE_OBJECT       *Op)
166
AnGetInternalMethodReturnType (
215
{
167
    ACPI_PARSE_OBJECT       *Op)
Line 216... Line 168...
216
 
168
{
Line 225... Line 177...
225
 
177
}
Line 226... Line 178...
226
 
178
 
227
/*******************************************************************************
179
 
228
 *
-
 
229
 * FUNCTION:    AnMapArgTypeToBtype
-
 
230
 *
-
 
231
 * PARAMETERS:  ArgType      - The ARGI required type(s) for this argument,
-
 
232
 *                             from the opcode info table
-
 
233
 *
-
 
234
 * RETURN:      The corresponding Bit-encoded types
-
 
235
 *
-
 
236
 * DESCRIPTION: Convert an encoded ARGI required argument type code into a
-
 
237
 *              bitfield type code. Implements the implicit source conversion
-
 
238
 *              rules.
-
 
239
 *
-
 
240
 ******************************************************************************/
-
 
241
 
-
 
242
static UINT32
-
 
243
AnMapArgTypeToBtype (
-
 
244
    UINT32                  ArgType)
-
 
245
{
-
 
246
 
-
 
247
    switch (ArgType)
-
 
248
    {
-
 
249
 
-
 
250
    /* Simple types */
-
 
251
 
-
 
252
    case ARGI_ANYTYPE:
-
 
253
        return (ACPI_BTYPE_OBJECTS_AND_REFS);
-
 
254
 
-
 
255
    case ARGI_PACKAGE:
-
 
256
        return (ACPI_BTYPE_PACKAGE);
-
 
257
 
-
 
258
    case ARGI_EVENT:
-
 
259
        return (ACPI_BTYPE_EVENT);
-
 
260
 
-
 
261
    case ARGI_MUTEX:
-
 
262
        return (ACPI_BTYPE_MUTEX);
-
 
263
 
-
 
264
    case ARGI_DDBHANDLE:
-
 
265
        /*
-
 
266
         * DDBHandleObject := SuperName
-
 
267
         * ACPI_BTYPE_REFERENCE: Index reference as parameter of Load/Unload
-
 
268
         */
-
 
269
        return (ACPI_BTYPE_DDB_HANDLE | ACPI_BTYPE_REFERENCE);
-
 
270
 
-
 
271
    /* Interchangeable types */
-
 
272
    /*
-
 
273
     * Source conversion rules:
-
 
274
     * Integer, String, and Buffer are all interchangeable
-
 
275
     */
-
 
276
    case ARGI_INTEGER:
-
 
277
    case ARGI_STRING:
-
 
278
    case ARGI_BUFFER:
-
 
279
    case ARGI_BUFFER_OR_STRING:
-
 
280
    case ARGI_COMPUTEDATA:
-
 
281
        return (ACPI_BTYPE_COMPUTE_DATA);
-
 
282
 
-
 
283
    /* References */
-
 
284
 
-
 
285
    case ARGI_INTEGER_REF:
-
 
286
        return (ACPI_BTYPE_INTEGER);
-
 
287
 
-
 
288
    case ARGI_OBJECT_REF:
-
 
289
        return (ACPI_BTYPE_ALL_OBJECTS);
-
 
290
 
-
 
291
    case ARGI_DEVICE_REF:
-
 
292
        return (ACPI_BTYPE_DEVICE_OBJECTS);
-
 
293
 
-
 
294
    case ARGI_REFERENCE:
-
 
295
        return (ACPI_BTYPE_REFERENCE);
-
 
296
 
-
 
297
    case ARGI_TARGETREF:
-
 
298
    case ARGI_FIXED_TARGET:
-
 
299
    case ARGI_SIMPLE_TARGET:
-
 
300
        return (ACPI_BTYPE_OBJECTS_AND_REFS);
-
 
301
 
-
 
302
    /* Complex types */
-
 
303
 
-
 
304
    case ARGI_DATAOBJECT:
-
 
305
 
-
 
306
        /*
-
 
307
         * Buffer, string, package or reference to a Op -
-
 
308
         * Used only by SizeOf operator
-
 
309
         */
-
 
310
        return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
-
 
311
            ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
-
 
312
 
-
 
313
    case ARGI_COMPLEXOBJ:
-
 
314
 
-
 
315
        /* Buffer, String, or package */
-
 
316
 
-
 
317
        return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE);
-
 
318
 
-
 
319
    case ARGI_REF_OR_STRING:
-
 
320
        return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
-
 
321
 
-
 
322
    case ARGI_REGION_OR_BUFFER:
-
 
323
 
-
 
324
        /* Used by Load() only. Allow buffers in addition to regions/fields */
-
 
325
 
-
 
326
        return (ACPI_BTYPE_REGION | ACPI_BTYPE_BUFFER | ACPI_BTYPE_FIELD_UNIT);
-
 
327
 
-
 
328
    case ARGI_DATAREFOBJ:
-
 
329
        return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
-
 
330
            ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
-
 
331
 
-
 
332
    default:
-
 
333
        break;
-
 
334
    }
-
 
335
 
-
 
336
    return (ACPI_BTYPE_OBJECTS_AND_REFS);
-
 
337
}
-
 
338
 
-
 
339
 
-
 
340
/*******************************************************************************
-
 
341
 *
-
 
342
 * FUNCTION:    AnMapEtypeToBtype
-
 
343
 *
-
 
344
 * PARAMETERS:  Etype           - Encoded ACPI Type
-
 
345
 *
-
 
346
 * RETURN:      Btype corresponding to the Etype
-
 
347
 *
-
 
348
 * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
-
 
349
 *              operand conversion rules. In other words, returns the type(s)
-
 
350
 *              this Etype is implicitly converted to during interpretation.
-
 
351
 *
-
 
352
 ******************************************************************************/
-
 
353
 
-
 
354
static UINT32
-
 
355
AnMapEtypeToBtype (
-
 
356
    UINT32                  Etype)
-
 
357
{
-
 
358
 
-
 
359
 
-
 
360
    if (Etype == ACPI_TYPE_ANY)
-
 
361
    {
-
 
362
        return ACPI_BTYPE_OBJECTS_AND_REFS;
-
 
363
    }
-
 
364
 
-
 
365
    /* Try the standard ACPI data types */
-
 
366
 
-
 
367
    if (Etype <= ACPI_TYPE_EXTERNAL_MAX)
-
 
368
    {
-
 
369
        /*
-
 
370
         * This switch statement implements the allowed operand conversion
-
 
371
         * rules as per the "ASL Data Types" section of the ACPI
-
 
372
         * specification.
-
 
373
         */
-
 
374
        switch (Etype)
-
 
375
        {
-
 
376
        case ACPI_TYPE_INTEGER:
-
 
377
            return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
-
 
378
 
-
 
379
        case ACPI_TYPE_STRING:
-
 
380
        case ACPI_TYPE_BUFFER:
-
 
381
            return (ACPI_BTYPE_COMPUTE_DATA);
-
 
382
 
-
 
383
        case ACPI_TYPE_PACKAGE:
-
 
384
            return (ACPI_BTYPE_PACKAGE);
-
 
385
 
-
 
386
        case ACPI_TYPE_FIELD_UNIT:
-
 
387
            return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
-
 
388
 
-
 
389
        case ACPI_TYPE_BUFFER_FIELD:
-
 
390
            return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
-
 
391
 
-
 
392
        case ACPI_TYPE_DDB_HANDLE:
-
 
393
            return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
-
 
394
 
-
 
395
        case ACPI_BTYPE_DEBUG_OBJECT:
-
 
396
 
-
 
397
            /* Cannot be used as a source operand */
-
 
398
 
-
 
399
            return (0);
-
 
400
 
-
 
401
        default:
-
 
402
            return (1 << (Etype - 1));
-
 
403
        }
-
 
404
    }
-
 
405
 
-
 
406
    /* Try the internal data types */
-
 
407
 
-
 
408
    switch (Etype)
-
 
409
    {
-
 
410
    case ACPI_TYPE_LOCAL_REGION_FIELD:
-
 
411
    case ACPI_TYPE_LOCAL_BANK_FIELD:
-
 
412
    case ACPI_TYPE_LOCAL_INDEX_FIELD:
-
 
413
 
-
 
414
        /* Named fields can be either Integer/Buffer/String */
-
 
415
 
-
 
416
        return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
-
 
417
 
-
 
418
    case ACPI_TYPE_LOCAL_ALIAS:
-
 
419
 
-
 
420
        return (ACPI_BTYPE_INTEGER);
-
 
421
 
-
 
422
 
-
 
423
    case ACPI_TYPE_LOCAL_RESOURCE:
-
 
424
    case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
-
 
425
 
-
 
426
        return (ACPI_BTYPE_REFERENCE);
-
 
427
 
-
 
428
    default:
-
 
429
        printf ("Unhandled encoded type: %X\n", Etype);
-
 
430
        return (0);
-
 
431
    }
-
 
432
}
-
 
433
 
-
 
434
 
-
 
435
/*******************************************************************************
-
 
436
 *
-
 
437
 * FUNCTION:    AnFormatBtype
-
 
438
 *
-
 
439
 * PARAMETERS:  Btype               - Bitfield of ACPI types
-
 
440
 *              Buffer              - Where to put the ascii string
-
 
441
 *
-
 
442
 * RETURN:      None.
-
 
443
 *
-
 
444
 * DESCRIPTION: Convert a Btype to a string of ACPI types
-
 
445
 *
-
 
446
 ******************************************************************************/
-
 
447
 
-
 
448
static void
-
 
449
AnFormatBtype (
-
 
450
    char                    *Buffer,
-
 
451
    UINT32                  Btype)
-
 
452
{
-
 
453
    UINT32                  Type;
-
 
454
    BOOLEAN                 First = TRUE;
-
 
455
 
-
 
456
 
-
 
457
    *Buffer = 0;
-
 
458
 
-
 
459
    if (Btype == 0)
-
 
460
    {
-
 
461
        strcat (Buffer, "NoReturnValue");
-
 
462
        return;
-
 
463
    }
-
 
464
 
-
 
465
    for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++)
-
 
466
    {
-
 
467
        if (Btype & 0x00000001)
-
 
468
        {
-
 
469
            if (!First)
-
 
470
            {
-
 
471
                strcat (Buffer, "|");
-
 
472
            }
-
 
473
            First = FALSE;
-
 
474
            strcat (Buffer, AcpiUtGetTypeName (Type));
-
 
475
        }
-
 
476
        Btype >>= 1;
-
 
477
    }
-
 
478
 
-
 
479
    if (Btype & 0x00000001)
-
 
480
    {
-
 
481
        if (!First)
-
 
482
        {
-
 
483
            strcat (Buffer, "|");
-
 
484
        }
-
 
485
        First = FALSE;
-
 
486
        strcat (Buffer, "Reference");
-
 
487
    }
-
 
488
 
-
 
489
    Btype >>= 1;
-
 
490
    if (Btype & 0x00000001)
-
 
491
    {
-
 
492
        if (!First)
-
 
493
        {
-
 
494
            strcat (Buffer, "|");
-
 
495
        }
-
 
496
        First = FALSE;
-
 
497
        strcat (Buffer, "Resource");
-
 
498
    }
-
 
499
}
-
 
500
 
-
 
501
 
-
 
502
/*******************************************************************************
-
 
503
 *
180
/*******************************************************************************
504
 * FUNCTION:    AnGetBtype
-
 
505
 *
-
 
506
 * PARAMETERS:  Op          - Parse node whose type will be returned.
-
 
507
 *
-
 
508
 * RETURN:      The Btype associated with the Op.
-
 
509
 *
-
 
510
 * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
-
 
511
 *              Handles the case where the node is a name or method call and
-
 
512
 *              the actual type must be obtained from the namespace node.
-
 
513
 *
-
 
514
 ******************************************************************************/
-
 
515
 
-
 
516
static UINT32
-
 
517
AnGetBtype (
-
 
518
    ACPI_PARSE_OBJECT       *Op)
-
 
519
{
-
 
520
    ACPI_NAMESPACE_NODE     *Node;
-
 
521
    ACPI_PARSE_OBJECT       *ReferencedNode;
-
 
522
    UINT32                  ThisNodeBtype = 0;
-
 
523
 
-
 
524
 
-
 
525
    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)     ||
-
 
526
        (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)  ||
-
 
527
        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
-
 
528
    {
-
 
529
        Node = Op->Asl.Node;
-
 
530
        if (!Node)
-
 
531
        {
-
 
532
            DbgPrint (ASL_DEBUG_OUTPUT,
-
 
533
                "No attached Nsnode: [%s] at line %u name [%s], ignoring typecheck\n",
-
 
534
                Op->Asl.ParseOpName, Op->Asl.LineNumber,
-
 
535
                Op->Asl.ExternalName);
-
 
536
            return ACPI_UINT32_MAX;
-
 
537
        }
-
 
538
 
-
 
539
        ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
-
 
540
        if (!ThisNodeBtype)
-
 
541
        {
-
 
542
            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
-
 
543
                "could not map type");
-
 
544
        }
-
 
545
 
-
 
546
        /*
-
 
547
         * Since it was a named reference, enable the
-
 
548
         * reference bit also
-
 
549
         */
-
 
550
        ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
-
 
551
 
-
 
552
        if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
-
 
553
        {
-
 
554
            ReferencedNode = Node->Op;
-
 
555
            if (!ReferencedNode)
-
 
556
            {
-
 
557
                /* Check for an internal method */
-
 
558
 
-
 
559
                if (AnIsInternalMethod (Op))
-
 
560
                {
-
 
561
                    return (AnGetInternalMethodReturnType (Op));
-
 
562
                }
-
 
563
 
-
 
564
                AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
-
 
565
                    "null Op pointer");
-
 
566
                return ACPI_UINT32_MAX;
-
 
567
            }
-
 
568
 
-
 
569
            if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
-
 
570
            {
-
 
571
                ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
-
 
572
            }
-
 
573
            else
-
 
574
            {
-
 
575
                return (ACPI_UINT32_MAX -1);
-
 
576
            }
-
 
577
        }
-
 
578
    }
-
 
579
    else
-
 
580
    {
-
 
581
        ThisNodeBtype = Op->Asl.AcpiBtype;
-
 
582
    }
-
 
583
 
-
 
584
    return (ThisNodeBtype);
-
 
585
}
-
 
586
 
-
 
587
 
-
 
588
/*******************************************************************************
-
 
589
 *
-
 
590
 * FUNCTION:    AnMapObjTypeToBtype
-
 
591
 *
-
 
592
 * PARAMETERS:  Op              - A parse node
-
 
593
 *
-
 
594
 * RETURN:      A Btype
-
 
595
 *
-
 
596
 * DESCRIPTION: Map object to the associated "Btype"
-
 
597
 *
-
 
598
 ******************************************************************************/
-
 
599
 
-
 
600
static UINT32
-
 
601
AnMapObjTypeToBtype (
-
 
602
    ACPI_PARSE_OBJECT       *Op)
-
 
603
{
-
 
604
 
-
 
605
    switch (Op->Asl.ParseOpcode)
-
 
606
    {
-
 
607
    case PARSEOP_OBJECTTYPE_BFF:        /* "BuffFieldObj" */
-
 
608
        return (ACPI_BTYPE_BUFFER_FIELD);
-
 
609
 
-
 
610
    case PARSEOP_OBJECTTYPE_BUF:        /* "BuffObj" */
-
 
611
        return (ACPI_BTYPE_BUFFER);
-
 
612
 
-
 
613
    case PARSEOP_OBJECTTYPE_DDB:        /* "DDBHandleObj" */
-
 
614
        return (ACPI_BTYPE_DDB_HANDLE);
-
 
615
 
-
 
616
    case PARSEOP_OBJECTTYPE_DEV:        /* "DeviceObj" */
-
 
617
        return (ACPI_BTYPE_DEVICE);
-
 
618
 
-
 
619
    case PARSEOP_OBJECTTYPE_EVT:        /* "EventObj" */
-
 
620
        return (ACPI_BTYPE_EVENT);
-
 
621
 
-
 
622
    case PARSEOP_OBJECTTYPE_FLD:        /* "FieldUnitObj" */
-
 
623
        return (ACPI_BTYPE_FIELD_UNIT);
-
 
624
 
-
 
625
    case PARSEOP_OBJECTTYPE_INT:        /* "IntObj" */
-
 
626
        return (ACPI_BTYPE_INTEGER);
-
 
627
 
-
 
628
    case PARSEOP_OBJECTTYPE_MTH:        /* "MethodObj" */
-
 
629
        return (ACPI_BTYPE_METHOD);
-
 
630
 
-
 
631
    case PARSEOP_OBJECTTYPE_MTX:        /* "MutexObj" */
-
 
632
        return (ACPI_BTYPE_MUTEX);
-
 
633
 
-
 
634
    case PARSEOP_OBJECTTYPE_OPR:        /* "OpRegionObj" */
-
 
635
        return (ACPI_BTYPE_REGION);
-
 
636
 
-
 
637
    case PARSEOP_OBJECTTYPE_PKG:        /* "PkgObj" */
-
 
638
        return (ACPI_BTYPE_PACKAGE);
-
 
639
 
-
 
640
    case PARSEOP_OBJECTTYPE_POW:        /* "PowerResObj" */
-
 
641
        return (ACPI_BTYPE_POWER);
-
 
642
 
-
 
643
    case PARSEOP_OBJECTTYPE_STR:        /* "StrObj" */
-
 
644
        return (ACPI_BTYPE_STRING);
-
 
645
 
-
 
646
    case PARSEOP_OBJECTTYPE_THZ:        /* "ThermalZoneObj" */
-
 
647
        return (ACPI_BTYPE_THERMAL);
-
 
648
 
-
 
649
    case PARSEOP_OBJECTTYPE_UNK:        /* "UnknownObj" */
-
 
650
        return (ACPI_BTYPE_OBJECTS_AND_REFS);
-
 
651
 
-
 
652
    default:
-
 
653
        return (0);
-
 
654
    }
-
 
655
}
-
 
656
 
-
 
657
 
-
 
658
/*******************************************************************************
-
 
659
 *
-
 
660
 * FUNCTION:    AnMethodAnalysisWalkBegin
181
 *
661
 *
182
 * FUNCTION:    AnCheckId
-
 
183
 *
662
 * PARAMETERS:  ASL_WALK_CALLBACK
184
 * PARAMETERS:  Op                  - Current parse op
663
 *
185
 *              Type                - HID or CID
664
 * RETURN:      Status
186
 *
665
 *
187
 * RETURN:      None
666
 * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
188
 *
667
 *              1) Initialized local variables
-
 
668
 *              2) Valid arguments
-
 
669
 *              3) Return types
189
 * DESCRIPTION: Perform various checks on _HID and _CID strings. Only limited
670
 *
190
 *              checks can be performed on _CID strings.
Line 671... Line 191...
671
 ******************************************************************************/
191
 *
672
 
192
 ******************************************************************************/
673
ACPI_STATUS
193
 
674
AnMethodAnalysisWalkBegin (
194
void
675
    ACPI_PARSE_OBJECT       *Op,
-
 
676
    UINT32                  Level,
195
AnCheckId (
677
    void                    *Context)
-
 
678
{
-
 
679
    ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
-
 
680
    ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
-
 
681
    ACPI_PARSE_OBJECT       *Next;
196
    ACPI_PARSE_OBJECT       *Op,
682
    UINT32                  RegisterNumber;
-
 
683
    UINT32                  i;
-
 
684
    char                    LocalName[] = "Local0";
-
 
685
    char                    ArgName[] = "Arg0";
197
    ACPI_NAME               Type)
686
    ACPI_PARSE_OBJECT       *ArgNode;
-
 
687
    ACPI_PARSE_OBJECT       *NextType;
198
{
688
    ACPI_PARSE_OBJECT       *NextParamType;
-
 
689
    UINT8                   ActualArgs = 0;
-
 
690
 
-
 
691
 
-
 
692
    switch (Op->Asl.ParseOpcode)
-
 
693
    {
-
 
694
    case PARSEOP_METHOD:
-
 
695
 
-
 
696
        TotalMethods++;
-
 
697
 
-
 
698
        /* Create and init method info */
-
 
699
 
-
 
700
        MethodInfo       = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
-
 
Line 701... Line -...
701
        MethodInfo->Next = WalkInfo->MethodStack;
-
 
Line 702... Line 199...
702
        MethodInfo->Op = Op;
199
    UINT32                  i;
Line 703... Line -...
703
 
-
 
704
        WalkInfo->MethodStack = MethodInfo;
-
 
705
 
-
 
706
        /* Get the name node, ignored here */
-
 
707
 
-
 
708
        Next = Op->Asl.Child;
-
 
709
 
-
 
710
        /* Get the NumArguments node */
-
 
711
 
-
 
712
        Next = Next->Asl.Next;
-
 
713
        MethodInfo->NumArguments = (UINT8)
-
 
714
            (((UINT8) Next->Asl.Value.Integer) & 0x07);
-
 
715
 
-
 
716
        /* Get the SerializeRule and SyncLevel nodes, ignored here */
-
 
717
 
-
 
718
        Next = Next->Asl.Next;
-
 
719
        Next = Next->Asl.Next;
-
 
720
        ArgNode = Next;
-
 
721
 
-
 
722
        /* Get the ReturnType node */
-
 
723
 
-
 
724
        Next = Next->Asl.Next;
-
 
725
 
-
 
726
        NextType = Next->Asl.Child;
-
 
727
        while (NextType)
-
 
728
        {
-
 
729
            /* Get and map each of the ReturnTypes */
-
 
730
 
-
 
731
            MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
-
 
732
            NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
-
 
733
            NextType = NextType->Asl.Next;
-
 
734
        }
-
 
735
 
-
 
736
        /* Get the ParameterType node */
-
 
737
 
-
 
738
        Next = Next->Asl.Next;
200
    ACPI_SIZE               Length;
739
 
-
 
740
        NextType = Next->Asl.Child;
-
 
741
        while (NextType)
-
 
742
        {
-
 
743
            if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
-
 
744
            {
-
 
745
                NextParamType = NextType->Asl.Child;
-
 
746
                while (NextParamType)
-
 
747
                {
-
 
748
                    MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
-
 
749
                    NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
-
 
750
                    NextParamType = NextParamType->Asl.Next;
-
 
751
                }
-
 
752
            }
-
 
753
            else
-
 
754
            {
-
 
755
                MethodInfo->ValidArgTypes[ActualArgs] =
-
 
756
                    AnMapObjTypeToBtype (NextType);
-
 
757
                NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
-
 
758
                ActualArgs++;
-
 
759
            }
-
 
760
 
-
 
761
            NextType = NextType->Asl.Next;
-
 
762
        }
-
 
763
 
-
 
764
        if ((MethodInfo->NumArguments) &&
-
 
765
            (MethodInfo->NumArguments != ActualArgs))
-
 
766
        {
-
 
767
            /* error: Param list did not match number of args */
-
 
768
        }
-
 
769
 
-
 
770
        /* Allow numarguments == 0 for Function() */
-
 
771
 
-
 
772
        if ((!MethodInfo->NumArguments) && (ActualArgs))
-
 
773
        {
-
 
774
            MethodInfo->NumArguments = ActualArgs;
-
 
775
            ArgNode->Asl.Value.Integer |= ActualArgs;
-
 
776
        }
-
 
777
 
-
 
778
        /*
-
 
779
         * Actual arguments are initialized at method entry.
-
 
780
         * All other ArgX "registers" can be used as locals, so we
-
 
781
         * track their initialization.
-
 
782
         */
-
 
783
        for (i = 0; i < MethodInfo->NumArguments; i++)
-
 
784
        {
-
 
785
            MethodInfo->ArgInitialized[i] = TRUE;
-
 
786
        }
-
 
787
        break;
-
 
788
 
-
 
789
 
201
    UINT32                  AlphaPrefixLength;
790
    case PARSEOP_METHODCALL:
-
 
791
 
-
 
792
        if (MethodInfo &&
-
 
793
           (Op->Asl.Node == MethodInfo->Op->Asl.Node))
-
 
794
        {
-
 
795
            AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
-
 
796
        }
-
 
797
        break;
-
 
798
 
-
 
799
 
-
 
800
    case PARSEOP_LOCAL0:
-
 
801
    case PARSEOP_LOCAL1:
-
 
802
    case PARSEOP_LOCAL2:
-
 
803
    case PARSEOP_LOCAL3:
-
 
804
    case PARSEOP_LOCAL4:
-
 
805
    case PARSEOP_LOCAL5:
-
 
806
    case PARSEOP_LOCAL6:
-
 
807
    case PARSEOP_LOCAL7:
-
 
808
 
-
 
809
        if (!MethodInfo)
-
 
810
        {
-
 
811
            /*
-
 
812
             * Local was used outside a control method, or there was an error
-
 
813
             * in the method declaration.
-
 
814
             */
-
 
815
            AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
-
 
816
            return (AE_ERROR);
-
 
817
        }
-
 
818
 
-
 
819
        RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
-
 
820
 
-
 
821
        /*
-
 
822
         * If the local is being used as a target, mark the local
-
 
823
         * initialized
-
 
824
         */
-
 
825
        if (Op->Asl.CompileFlags & NODE_IS_TARGET)
-
 
826
        {
-
 
827
            MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
-
 
828
        }
-
 
829
 
-
 
830
        /*
-
 
831
         * Otherwise, this is a reference, check if the local
-
 
832
         * has been previously initialized.
-
 
833
         *
-
 
834
         * The only operator that accepts an uninitialized value is ObjectType()
-
 
835
         */
-
 
836
        else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
-
 
837
                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
202
 
838
        {
-
 
839
            LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
-
 
840
            AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
-
 
841
        }
-
 
842
        break;
-
 
843
 
-
 
844
 
-
 
845
    case PARSEOP_ARG0:
-
 
846
    case PARSEOP_ARG1:
-
 
847
    case PARSEOP_ARG2:
-
 
848
    case PARSEOP_ARG3:
-
 
849
    case PARSEOP_ARG4:
-
 
850
    case PARSEOP_ARG5:
-
 
851
    case PARSEOP_ARG6:
-
 
852
 
-
 
853
        if (!MethodInfo)
-
 
854
        {
-
 
855
            /*
-
 
856
             * Arg was used outside a control method, or there was an error
203
 
Line 857... Line -...
857
             * in the method declaration.
-
 
858
             */
204
    /* Only care about string versions of _HID/_CID (integers are legal) */
Line 859... Line -...
859
            AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
-
 
860
            return (AE_ERROR);
205
 
861
        }
-
 
862
 
206
    if (Op->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)
863
        RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
-
 
864
        ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
207
    {
865
 
208
        return;
-
 
209
    }
-
 
210
 
866
        /*
211
    /* For both _HID and _CID, the string must be non-null */
Line 867... Line 212...
867
         * If the Arg is being used as a target, mark the local
212
 
868
         * initialized
213
    Length = strlen (Op->Asl.Value.String);
869
         */
214
    if (!Length)
870
        if (Op->Asl.CompileFlags & NODE_IS_TARGET)
215
    {
871
        {
216
        AslError (ASL_ERROR, ASL_MSG_NULL_STRING,
872
            MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
217
            Op, NULL);
873
        }
-
 
874
 
-
 
875
        /*
-
 
876
         * Otherwise, this is a reference, check if the Arg
-
 
877
         * has been previously initialized.
-
 
878
         *
-
 
879
         * The only operator that accepts an uninitialized value is ObjectType()
-
 
880
         */
-
 
881
        else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
-
 
882
                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
-
 
883
        {
-
 
884
            AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
-
 
885
        }
-
 
886
 
-
 
887
        /* Flag this arg if it is not a "real" argument to the method */
-
 
888
 
-
 
889
        if (RegisterNumber >= MethodInfo->NumArguments)
-
 
890
        {
218
        return;
891
            AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
219
    }
892
        }
-
 
893
        break;
220
 
894
 
221
    /*
895
 
222
     * One of the things we want to catch here is the use of a leading
896
    case PARSEOP_RETURN:
-
 
897
 
-
 
898
        if (!MethodInfo)
223
     * asterisk in the string -- an odd construct that certain platform
Line 899... Line 224...
899
        {
224
     * manufacturers are fond of. Technically, a leading asterisk is OK
Line 900... Line 225...
900
            /*
225
     * for _CID, but a valid use of this has not been seen.
901
             * Probably was an error in the method declaration,
-
 
902
             * no additional error here
-
 
903
             */
-
 
904
            ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
-
 
905
            return (AE_ERROR);
-
 
906
        }
226
     */
907
 
227
    if (*Op->Asl.Value.String == '*')
908
        /* Child indicates a return value */
228
    {
909
 
-
 
Line -... Line 229...
-
 
229
        AslError (ASL_ERROR, ASL_MSG_LEADING_ASTERISK,
Line 910... Line -...
910
        if ((Op->Asl.Child) &&
-
 
911
            (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
-
 
912
        {
-
 
913
            MethodInfo->NumReturnWithValue++;
230
            Op, Op->Asl.Value.String);
914
        }
-
 
915
        else
231
        return;
916
        {
232
    }
917
            MethodInfo->NumReturnNoValue++;
233
 
-
 
234
    /* _CID strings are bus-specific, no more checks can be performed */
-
 
235
 
918
        }
236
    if (Type == ASL_TYPE_CID)
919
        break;
237
    {
920
 
-
 
921
 
238
        return;
Line 922... Line -...
922
    case PARSEOP_BREAK:
-
 
923
    case PARSEOP_CONTINUE:
-
 
924
 
-
 
925
        Next = Op->Asl.Parent;
-
 
926
        while (Next)
-
 
927
        {
-
 
928
            if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
-
 
929
            {
-
 
930
                break;
-
 
931
            }
239
    }
Line 932... Line -...
932
            Next = Next->Asl.Parent;
-
 
933
        }
240
 
934
 
241
    /* For _HID, all characters must be alphanumeric */
935
        if (!Next)
242
 
-
 
243
    for (i = 0; Op->Asl.Value.String[i]; i++)
-
 
244
    {
936
        {
245
        if (!isalnum ((int) Op->Asl.Value.String[i]))
937
            AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
-
 
938
        }
-
 
Line 939... Line -...
939
        break;
-
 
940
 
-
 
941
 
-
 
942
    case PARSEOP_STALL:
246
        {
943
 
-
 
944
        /* We can range check if the argument is an integer */
-
 
945
 
-
 
Line 946... Line -...
946
        if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
-
 
947
            (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
-
 
948
        {
247
            AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
949
            AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
248
                Op, Op->Asl.Value.String);
950
        }
-
 
951
        break;
-
 
952
 
249
            break;
953
 
250
        }
954
    case PARSEOP_DEVICE:
251
    }
955
    case PARSEOP_EVENT:
-
 
Line -... Line 252...
-
 
252
 
Line 956... Line -...
956
    case PARSEOP_MUTEX:
-
 
957
    case PARSEOP_OPERATIONREGION:
-
 
958
    case PARSEOP_POWERRESOURCE:
-
 
959
    case PARSEOP_PROCESSOR:
-
 
960
    case PARSEOP_THERMALZONE:
-
 
961
 
-
 
962
        /*
-
 
963
         * The first operand is a name to be created in the namespace.
-
 
964
         * Check against the reserved list.
-
 
965
         */
-
 
966
        i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
-
 
967
        if (i < ACPI_VALID_RESERVED_NAME_MAX)
-
 
968
        {
-
 
969
            AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
-
 
970
        }
-
 
971
        break;
-
 
972
 
-
 
973
 
-
 
974
    case PARSEOP_NAME:
253
    /* _HID String must be of the form "XXX####" or "ACPI####" */
975
 
254
 
976
        /* Typecheck any predefined names statically defined with Name() */
255
    if ((Length < 7) || (Length > 8))
977
 
256
    {
978
        ApCheckForPredefinedObject (Op, Op->Asl.NameSeg);
257
        AslError (ASL_ERROR, ASL_MSG_HID_LENGTH,
979
 
258
            Op, Op->Asl.Value.String);
980
        /* Special typechecking for _HID */
259
        return;
981
 
260
    }
982
        if (!ACPI_STRCMP (METHOD_NAME__HID, Op->Asl.NameSeg))
261
 
983
        {
262
    /* _HID Length is valid, now check for uppercase (first 3 or 4 chars) */
984
            Next = Op->Asl.Child->Asl.Next;
-
 
985
            if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
-
 
986
            {
-
 
987
                /*
-
 
988
                 * _HID is a string, all characters must be alphanumeric.
-
 
989
                 * One of the things we want to catch here is the use of
-
 
990
                 * a leading asterisk in the string.
-
 
991
                 */
-
 
992
                for (i = 0; Next->Asl.Value.String[i]; i++)
-
 
993
                {
-
 
Line 994... Line 263...
994
                    if (!isalnum ((int) Next->Asl.Value.String[i]))
263
 
995
                    {
264
    AlphaPrefixLength = 3;
996
                        AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
265
    if (Length >= 8)
Line 1024... Line 293...
1024
 *              fact a RETURN statement.
293
 *              to find the last one. Check if that last statement is in
1025
 *
294
 *              fact a RETURN statement.
1026
 ******************************************************************************/
295
 *
1027
 
296
 ******************************************************************************/
Line 1028... Line 297...
1028
static BOOLEAN
297
 
1029
AnLastStatementIsReturn (
298
BOOLEAN
1030
    ACPI_PARSE_OBJECT       *Op)
299
AnLastStatementIsReturn (
1031
{
300
    ACPI_PARSE_OBJECT       *Op)
1032
    ACPI_PARSE_OBJECT       *Next;
301
{
Line 1033... Line -...
1033
 
-
 
1034
 
302
    ACPI_PARSE_OBJECT       *Next;
1035
    /*
303
 
1036
     * Check if last statement is a return
304
 
1037
     */
305
    /* Check if last statement is a return */
1038
    Next = ASL_GET_CHILD_NODE (Op);
306
 
1039
    while (Next)
307
    Next = ASL_GET_CHILD_NODE (Op);
1040
    {
308
    while (Next)
1041
        if ((!Next->Asl.Next) &&
309
    {
1042
            (Next->Asl.ParseOpcode == PARSEOP_RETURN))
310
        if ((!Next->Asl.Next) &&
1043
        {
311
            (Next->Asl.ParseOpcode == PARSEOP_RETURN))
Line 1044... Line 312...
1044
            return TRUE;
312
        {
1045
        }
313
            return (TRUE);
Line 1046... Line 314...
1046
 
314
        }
1047
        Next = ASL_GET_PEER_NODE (Next);
-
 
1048
    }
-
 
1049
 
-
 
1050
    return FALSE;
-
 
1051
}
-
 
1052
 
-
 
1053
 
-
 
1054
/*******************************************************************************
-
 
1055
 *
-
 
1056
 * FUNCTION:    AnMethodAnalysisWalkEnd
-
 
1057
 *
-
 
1058
 * PARAMETERS:  ASL_WALK_CALLBACK
-
 
1059
 *
-
 
1060
 * RETURN:      Status
-
 
1061
 *
-
 
1062
 * DESCRIPTION: Ascending callback for analysis walk. Complete method
-
 
1063
 *              return analysis.
-
 
1064
 *
-
 
1065
 ******************************************************************************/
-
 
1066
 
-
 
1067
ACPI_STATUS
-
 
1068
AnMethodAnalysisWalkEnd (
-
 
1069
    ACPI_PARSE_OBJECT       *Op,
-
 
1070
    UINT32                  Level,
-
 
1071
    void                    *Context)
-
 
1072
{
-
 
1073
    ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
-
 
1074
    ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
-
 
1075
 
-
 
1076
 
-
 
1077
    switch (Op->Asl.ParseOpcode)
-
 
1078
    {
-
 
1079
    case PARSEOP_METHOD:
-
 
1080
    case PARSEOP_RETURN:
-
 
1081
        if (!MethodInfo)
-
 
1082
        {
-
 
1083
            printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
-
 
1084
            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
-
 
1085
                "No method info for this method");
-
 
1086
            CmCleanupAndExit ();
-
 
1087
            return (AE_AML_INTERNAL);
-
 
1088
        }
-
 
1089
        break;
-
 
1090
 
-
 
1091
    default:
-
 
1092
        break;
-
 
1093
    }
-
 
1094
 
-
 
1095
    switch (Op->Asl.ParseOpcode)
-
 
1096
    {
-
 
1097
    case PARSEOP_METHOD:
-
 
1098
 
-
 
1099
        WalkInfo->MethodStack = MethodInfo->Next;
-
 
1100
 
-
 
1101
        /*
-
 
1102
         * Check if there is no return statement at the end of the
-
 
1103
         * method AND we can actually get there -- i.e., the execution
-
 
1104
         * of the method can possibly terminate without a return statement.
-
 
1105
         */
-
 
1106
        if ((!AnLastStatementIsReturn (Op)) &&
-
 
1107
            (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
-
 
1108
        {
-
 
1109
            /*
-
 
1110
             * No return statement, and execution can possibly exit
-
 
1111
             * via this path. This is equivalent to Return ()
-
 
1112
             */
-
 
1113
            MethodInfo->NumReturnNoValue++;
-
 
1114
        }
-
 
1115
 
-
 
1116
        /*
-
 
1117
         * Check for case where some return statements have a return value
-
 
1118
         * and some do not. Exit without a return statement is a return with
-
 
1119
         * no value
-
 
1120
         */
-
 
1121
        if (MethodInfo->NumReturnNoValue &&
-
 
1122
            MethodInfo->NumReturnWithValue)
-
 
1123
        {
-
 
1124
            AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
-
 
1125
                Op->Asl.ExternalName);
-
 
1126
        }
-
 
1127
 
-
 
1128
        /*
-
 
1129
         * If there are any RETURN() statements with no value, or there is a
-
 
1130
         * control path that allows the method to exit without a return value,
-
 
1131
         * we mark the method as a method that does not return a value. This
-
 
1132
         * knowledge can be used to check method invocations that expect a
-
 
1133
         * returned value.
-
 
1134
         */
-
 
1135
        if (MethodInfo->NumReturnNoValue)
-
 
1136
        {
-
 
1137
            if (MethodInfo->NumReturnWithValue)
-
 
1138
            {
-
 
1139
                Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
-
 
1140
            }
-
 
1141
            else
-
 
1142
            {
-
 
1143
                Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
-
 
1144
            }
-
 
1145
        }
-
 
1146
 
-
 
1147
        /*
-
 
1148
         * Check predefined method names for correct return behavior
-
 
1149
         * and correct number of arguments
-
 
1150
         */
-
 
1151
        ApCheckForPredefinedMethod (Op, MethodInfo);
-
 
1152
        ACPI_FREE (MethodInfo);
-
 
1153
        break;
-
 
1154
 
-
 
1155
 
-
 
1156
    case PARSEOP_RETURN:
-
 
1157
 
-
 
1158
        /*
-
 
1159
         * If the parent is a predefined method name, attempt to typecheck
-
 
1160
         * the return value. Only static types can be validated.
-
 
1161
         */
-
 
1162
        ApCheckPredefinedReturnValue (Op, MethodInfo);
-
 
1163
 
-
 
1164
        /*
-
 
1165
         * The parent block does not "exit" and continue execution -- the
-
 
1166
         * method is terminated here with the Return() statement.
-
 
1167
         */
-
 
1168
        Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
-
 
1169
 
-
 
1170
        /* Used in the "typing" pass later */
-
 
1171
 
-
 
1172
        Op->Asl.ParentMethod = MethodInfo->Op;
-
 
1173
 
-
 
1174
        /*
-
 
1175
         * If there is a peer node after the return statement, then this
-
 
1176
         * node is unreachable code -- i.e., it won't be executed because of
-
 
1177
         * the preceeding Return() statement.
-
 
1178
         */
-
 
1179
        if (Op->Asl.Next)
-
 
1180
        {
-
 
1181
            AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
-
 
1182
        }
-
 
1183
        break;
-
 
1184
 
-
 
1185
 
-
 
1186
    case PARSEOP_IF:
-
 
1187
 
-
 
1188
        if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
-
 
1189
            (Op->Asl.Next) &&
-
 
1190
            (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
-
 
1191
        {
-
 
1192
            /*
-
 
1193
             * This IF has a corresponding ELSE. The IF block has no exit,
-
 
1194
             * (it contains an unconditional Return)
-
 
1195
             * mark the ELSE block to remember this fact.
-
 
1196
             */
-
 
1197
            Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
-
 
1198
        }
-
 
1199
        break;
-
 
1200
 
-
 
1201
 
-
 
1202
    case PARSEOP_ELSE:
-
 
1203
 
-
 
1204
        if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
-
 
1205
            (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
-
 
1206
        {
-
 
1207
            /*
-
 
1208
             * This ELSE block has no exit and the corresponding IF block
-
 
1209
             * has no exit either. Therefore, the parent node has no exit.
-
 
1210
             */
-
 
1211
            Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
-
 
1212
        }
-
 
1213
        break;
-
 
1214
 
-
 
1215
 
-
 
1216
    default:
-
 
1217
 
-
 
1218
        if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
-
 
1219
            (Op->Asl.Parent))
-
 
1220
        {
-
 
1221
            /* If this node has no exit, then the parent has no exit either */
-
 
1222
 
-
 
1223
            Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
-
 
1224
        }
-
 
1225
        break;
-
 
1226
    }
-
 
1227
 
-
 
1228
    return AE_OK;
-
 
1229
}
-
 
1230
 
-
 
1231
 
-
 
1232
/*******************************************************************************
-
 
1233
 *
-
 
1234
 * FUNCTION:    AnMethodTypingWalkBegin
-
 
1235
 *
-
 
1236
 * PARAMETERS:  ASL_WALK_CALLBACK
-
 
1237
 *
-
 
1238
 * RETURN:      Status
-
 
1239
 *
-
 
1240
 * DESCRIPTION: Descending callback for the typing walk.
-
 
1241
 *
-
 
1242
 ******************************************************************************/
-
 
1243
 
-
 
1244
ACPI_STATUS
-
 
1245
AnMethodTypingWalkBegin (
-
 
1246
    ACPI_PARSE_OBJECT       *Op,
-
 
1247
    UINT32                  Level,
-
 
1248
    void                    *Context)
-
 
1249
{
-
 
1250
 
-
 
1251
    return AE_OK;
-
 
1252
}
-
 
1253
 
-
 
1254
 
-
 
1255
/*******************************************************************************
-
 
1256
 *
-
 
1257
 * FUNCTION:    AnMethodTypingWalkEnd
-
 
1258
 *
-
 
1259
 * PARAMETERS:  ASL_WALK_CALLBACK
-
 
1260
 *
-
 
1261
 * RETURN:      Status
-
 
1262
 *
-
 
1263
 * DESCRIPTION: Ascending callback for typing walk. Complete the method
-
 
1264
 *              return analysis. Check methods for:
-
 
1265
 *              1) Initialized local variables
-
 
1266
 *              2) Valid arguments
-
 
1267
 *              3) Return types
-
 
1268
 *
-
 
1269
 ******************************************************************************/
-
 
1270
 
-
 
1271
ACPI_STATUS
-
 
1272
AnMethodTypingWalkEnd (
-
 
1273
    ACPI_PARSE_OBJECT       *Op,
-
 
1274
    UINT32                  Level,
-
 
1275
    void                    *Context)
-
 
1276
{
-
 
1277
    UINT32                  ThisNodeBtype;
-
 
1278
 
-
 
1279
 
-
 
1280
    switch (Op->Asl.ParseOpcode)
-
 
1281
    {
-
 
1282
    case PARSEOP_METHOD:
-
 
1283
 
-
 
1284
        Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
-
 
1285
        break;
-
 
1286
 
-
 
1287
    case PARSEOP_RETURN:
-
 
1288
 
-
 
1289
        if ((Op->Asl.Child) &&
-
 
1290
            (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
-
 
1291
        {
-
 
1292
            ThisNodeBtype = AnGetBtype (Op->Asl.Child);
-
 
1293
 
-
 
1294
            if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
-
 
1295
                (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
-
 
1296
            {
-
 
1297
                /*
-
 
1298
                 * The called method is untyped at this time (typically a
-
 
1299
                 * forward reference).
-
 
1300
                 *
-
 
1301
                 * Check for a recursive method call first.
-
 
1302
                 */
-
 
1303
                if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
-
 
1304
                {
-
 
1305
                    /* We must type the method here */
-
 
1306
 
-
 
1307
                    TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
-
 
1308
                        ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
-
 
1309
                        AnMethodTypingWalkEnd, NULL);
-
 
1310
 
-
 
1311
                    ThisNodeBtype = AnGetBtype (Op->Asl.Child);
-
 
1312
                }
-
 
1313
            }
-
 
1314
 
-
 
1315
            /* Returns a value, save the value type */
-
 
1316
 
-
 
1317
            if (Op->Asl.ParentMethod)
-
 
1318
            {
-
 
1319
                Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
-
 
1320
            }
-
 
1321
        }
-
 
1322
        break;
-
 
1323
 
-
 
1324
    default:
-
 
1325
        break;
315
 
Line 1326... Line 316...
1326
    }
316
        Next = ASL_GET_PEER_NODE (Next);
1327
 
317
    }
Line 1345... Line 335...
1345
 *              in fact return a value, 2) check the type of the return value.
335
 * DESCRIPTION: Check a method invocation for 1) A return value and if it does
1346
 *
336
 *              in fact return a value, 2) check the type of the return value.
1347
 ******************************************************************************/
337
 *
1348
 
338
 ******************************************************************************/
Line 1349... Line 339...
1349
static void
339
 
1350
AnCheckMethodReturnValue (
340
void
1351
    ACPI_PARSE_OBJECT       *Op,
341
AnCheckMethodReturnValue (
1352
    const ACPI_OPCODE_INFO  *OpInfo,
342
    ACPI_PARSE_OBJECT       *Op,
1353
    ACPI_PARSE_OBJECT       *ArgOp,
343
    const ACPI_OPCODE_INFO  *OpInfo,
1354
    UINT32                  RequiredBtypes,
344
    ACPI_PARSE_OBJECT       *ArgOp,
Line 1382... Line 372...
1382
 
372
        /* Method returns a value, but the type is wrong */
Line 1383... Line 373...
1383
        AnFormatBtype (StringBuffer, ThisNodeBtype);
373
 
1384
        AnFormatBtype (StringBuffer2, RequiredBtypes);
374
        AnFormatBtype (StringBuffer, ThisNodeBtype);
Line 1385... Line -...
1385
 
-
 
1386
 
375
        AnFormatBtype (StringBuffer2, RequiredBtypes);
1387
        /*
376
 
1388
         * The case where the method does not return any value at all
377
        /*
1389
         * was already handled in the namespace cross reference
378
         * The case where the method does not return any value at all
1390
         * -- Only issue an error if the method in fact returns a value,
379
         * was already handled in the namespace cross reference
Line 1403... Line 392...
1403
 
392
}
Line 1404... Line 393...
1404
 
393
 
1405
/*******************************************************************************
394
 
1406
 *
-
 
1407
 * FUNCTION:    AnOperandTypecheckWalkBegin
-
 
1408
 *
-
 
1409
 * PARAMETERS:  ASL_WALK_CALLBACK
-
 
1410
 *
-
 
1411
 * RETURN:      Status
-
 
1412
 *
-
 
1413
 * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
-
 
1414
 *              1) Initialized local variables
-
 
1415
 *              2) Valid arguments
-
 
1416
 *              3) Return types
-
 
1417
 *
-
 
1418
 ******************************************************************************/
-
 
1419
 
-
 
1420
ACPI_STATUS
-
 
1421
AnOperandTypecheckWalkBegin (
-
 
1422
    ACPI_PARSE_OBJECT       *Op,
-
 
1423
    UINT32                  Level,
-
 
1424
    void                    *Context)
-
 
1425
{
-
 
1426
 
-
 
1427
    return AE_OK;
-
 
1428
}
-
 
1429
 
-
 
1430
 
-
 
1431
/*******************************************************************************
-
 
1432
 *
-
 
1433
 * FUNCTION:    AnOperandTypecheckWalkEnd
-
 
1434
 *
-
 
1435
 * PARAMETERS:  ASL_WALK_CALLBACK
-
 
1436
 *
-
 
1437
 * RETURN:      Status
-
 
1438
 *
-
 
1439
 * DESCRIPTION: Ascending callback for analysis walk. Complete method
-
 
1440
 *              return analysis.
-
 
1441
 *
-
 
1442
 ******************************************************************************/
-
 
1443
 
-
 
1444
ACPI_STATUS
-
 
1445
AnOperandTypecheckWalkEnd (
-
 
1446
    ACPI_PARSE_OBJECT       *Op,
-
 
1447
    UINT32                  Level,
-
 
1448
    void                    *Context)
-
 
1449
{
-
 
1450
    const ACPI_OPCODE_INFO  *OpInfo;
-
 
1451
    UINT32                  RuntimeArgTypes;
-
 
1452
    UINT32                  RuntimeArgTypes2;
-
 
1453
    UINT32                  RequiredBtypes;
-
 
1454
    UINT32                  ThisNodeBtype;
-
 
1455
    UINT32                  CommonBtypes;
-
 
1456
    UINT32                  OpcodeClass;
-
 
1457
    ACPI_PARSE_OBJECT       *ArgOp;
-
 
1458
    UINT32                  ArgType;
-
 
1459
 
-
 
1460
 
-
 
1461
    switch (Op->Asl.AmlOpcode)
-
 
1462
    {
-
 
1463
    case AML_RAW_DATA_BYTE:
-
 
1464
    case AML_RAW_DATA_WORD:
-
 
1465
    case AML_RAW_DATA_DWORD:
-
 
1466
    case AML_RAW_DATA_QWORD:
-
 
1467
    case AML_RAW_DATA_BUFFER:
-
 
1468
    case AML_RAW_DATA_CHAIN:
-
 
1469
    case AML_PACKAGE_LENGTH:
-
 
1470
    case AML_UNASSIGNED_OPCODE:
-
 
1471
    case AML_DEFAULT_ARG_OP:
-
 
1472
 
-
 
1473
        /* Ignore the internal (compiler-only) AML opcodes */
-
 
1474
 
-
 
1475
        return (AE_OK);
-
 
1476
 
-
 
1477
    default:
-
 
1478
        break;
-
 
1479
    }
-
 
1480
 
-
 
1481
    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
-
 
1482
    if (!OpInfo)
-
 
1483
    {
-
 
1484
        return (AE_OK);
-
 
1485
    }
-
 
1486
 
-
 
1487
    ArgOp           = Op->Asl.Child;
-
 
1488
    RuntimeArgTypes = OpInfo->RuntimeArgs;
-
 
1489
    OpcodeClass     = OpInfo->Class;
-
 
1490
 
-
 
1491
#ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
-
 
1492
    /*
-
 
1493
     * Update 11/2008: In practice, we can't perform this check. A simple
-
 
1494
     * analysis is not sufficient. Also, it can cause errors when compiling
-
 
1495
     * disassembled code because of the way Switch operators are implemented
-
 
1496
     * (a While(One) loop with a named temp variable created within.)
-
 
1497
     */
-
 
1498
 
-
 
1499
    /*
-
 
1500
     * If we are creating a named object, check if we are within a while loop
-
 
1501
     * by checking if the parent is a WHILE op. This is a simple analysis, but
-
 
1502
     * probably sufficient for many cases.
-
 
1503
     *
-
 
1504
     * Allow Scope(), Buffer(), and Package().
-
 
1505
     */
-
 
1506
    if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
-
 
1507
        ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
-
 
1508
    {
-
 
1509
        if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
-
 
1510
        {
-
 
1511
            AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
-
 
1512
        }
-
 
1513
    }
-
 
1514
#endif
-
 
1515
 
-
 
1516
    /*
-
 
1517
     * Special case for control opcodes IF/RETURN/WHILE since they
-
 
1518
     * have no runtime arg list (at this time)
-
 
1519
     */
-
 
1520
    switch (Op->Asl.AmlOpcode)
-
 
1521
    {
-
 
1522
    case AML_IF_OP:
-
 
1523
    case AML_WHILE_OP:
-
 
1524
    case AML_RETURN_OP:
-
 
1525
 
-
 
1526
        if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
-
 
1527
        {
-
 
1528
            /* Check for an internal method */
-
 
1529
 
-
 
1530
            if (AnIsInternalMethod (ArgOp))
-
 
1531
            {
-
 
1532
                return (AE_OK);
-
 
1533
            }
-
 
1534
 
-
 
1535
            /* The lone arg is a method call, check it */
-
 
1536
 
-
 
1537
            RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
-
 
1538
            if (Op->Asl.AmlOpcode == AML_RETURN_OP)
-
 
1539
            {
-
 
1540
                RequiredBtypes = 0xFFFFFFFF;
-
 
1541
            }
-
 
1542
 
-
 
1543
            ThisNodeBtype = AnGetBtype (ArgOp);
-
 
1544
            if (ThisNodeBtype == ACPI_UINT32_MAX)
-
 
1545
            {
-
 
1546
                return (AE_OK);
-
 
1547
            }
-
 
1548
            AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
-
 
1549
                RequiredBtypes, ThisNodeBtype);
-
 
1550
        }
-
 
1551
        return (AE_OK);
-
 
1552
 
-
 
1553
    default:
-
 
1554
        break;
-
 
1555
    }
-
 
1556
 
-
 
1557
    /* Ignore the non-executable opcodes */
-
 
1558
 
-
 
1559
    if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
-
 
1560
    {
-
 
1561
        return (AE_OK);
-
 
1562
    }
-
 
1563
 
-
 
1564
    switch (OpcodeClass)
-
 
1565
    {
-
 
1566
    case AML_CLASS_EXECUTE:
-
 
1567
    case AML_CLASS_CREATE:
-
 
1568
    case AML_CLASS_CONTROL:
-
 
1569
    case AML_CLASS_RETURN_VALUE:
-
 
1570
 
-
 
1571
        /* TBD: Change class or fix typechecking for these */
-
 
1572
 
-
 
1573
        if ((Op->Asl.AmlOpcode == AML_BUFFER_OP)        ||
-
 
1574
            (Op->Asl.AmlOpcode == AML_PACKAGE_OP)       ||
-
 
1575
            (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
-
 
1576
        {
-
 
1577
            break;
-
 
1578
        }
-
 
1579
 
-
 
1580
        /* Reverse the runtime argument list */
-
 
1581
 
-
 
1582
        RuntimeArgTypes2 = 0;
-
 
1583
        while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
-
 
1584
        {
-
 
1585
            RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
-
 
1586
            RuntimeArgTypes2 |= ArgType;
-
 
1587
            INCREMENT_ARG_LIST (RuntimeArgTypes);
-
 
1588
        }
-
 
1589
 
-
 
1590
        while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
-
 
1591
        {
-
 
1592
            RequiredBtypes = AnMapArgTypeToBtype (ArgType);
-
 
1593
 
-
 
1594
            ThisNodeBtype = AnGetBtype (ArgOp);
-
 
1595
            if (ThisNodeBtype == ACPI_UINT32_MAX)
-
 
1596
            {
-
 
1597
                goto NextArgument;
-
 
1598
            }
-
 
1599
 
-
 
1600
            /* Examine the arg based on the required type of the arg */
-
 
1601
 
-
 
1602
            switch (ArgType)
-
 
1603
            {
-
 
1604
            case ARGI_TARGETREF:
-
 
1605
 
-
 
1606
                if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
-
 
1607
                {
-
 
1608
                    /* ZERO is the placeholder for "don't store result" */
-
 
1609
 
-
 
1610
                    ThisNodeBtype = RequiredBtypes;
-
 
1611
                    break;
-
 
1612
                }
-
 
1613
 
-
 
1614
                if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
-
 
1615
                {
-
 
1616
                    /*
-
 
1617
                     * This is the case where an original reference to a resource
-
 
1618
                     * descriptor field has been replaced by an (Integer) offset.
-
 
1619
                     * These named fields are supported at compile-time only;
-
 
1620
                     * the names are not passed to the interpreter (via the AML).
-
 
1621
                     */
-
 
1622
                    if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
-
 
1623
                        (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
-
 
1624
                    {
-
 
1625
                        AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
-
 
1626
                    }
-
 
1627
                    else
-
 
1628
                    {
-
 
1629
                        AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
-
 
1630
                    }
-
 
1631
                    break;
-
 
1632
                }
-
 
1633
 
-
 
1634
                if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
-
 
1635
                    (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
-
 
1636
                {
-
 
1637
                    break;
-
 
1638
                }
-
 
1639
 
-
 
1640
                ThisNodeBtype = RequiredBtypes;
-
 
1641
                break;
-
 
1642
 
-
 
1643
 
-
 
1644
            case ARGI_REFERENCE:            /* References */
-
 
1645
            case ARGI_INTEGER_REF:
-
 
1646
            case ARGI_OBJECT_REF:
-
 
1647
            case ARGI_DEVICE_REF:
-
 
1648
 
-
 
1649
                switch (ArgOp->Asl.ParseOpcode)
-
 
1650
                {
-
 
1651
                case PARSEOP_LOCAL0:
-
 
1652
                case PARSEOP_LOCAL1:
-
 
1653
                case PARSEOP_LOCAL2:
-
 
1654
                case PARSEOP_LOCAL3:
-
 
1655
                case PARSEOP_LOCAL4:
-
 
1656
                case PARSEOP_LOCAL5:
-
 
1657
                case PARSEOP_LOCAL6:
-
 
1658
                case PARSEOP_LOCAL7:
-
 
1659
 
-
 
1660
                    /* TBD: implement analysis of current value (type) of the local */
-
 
1661
                    /* For now, just treat any local as a typematch */
-
 
1662
 
-
 
1663
                    /*ThisNodeBtype = RequiredBtypes;*/
-
 
1664
                    break;
-
 
1665
 
-
 
1666
                case PARSEOP_ARG0:
-
 
1667
                case PARSEOP_ARG1:
-
 
1668
                case PARSEOP_ARG2:
-
 
1669
                case PARSEOP_ARG3:
-
 
1670
                case PARSEOP_ARG4:
-
 
1671
                case PARSEOP_ARG5:
-
 
1672
                case PARSEOP_ARG6:
-
 
1673
 
-
 
1674
                    /* Hard to analyze argument types, sow we won't */
-
 
1675
                    /* For now, just treat any arg as a typematch */
-
 
1676
 
-
 
1677
                    /* ThisNodeBtype = RequiredBtypes; */
-
 
1678
                    break;
-
 
1679
 
-
 
1680
                case PARSEOP_DEBUG:
-
 
1681
                    break;
-
 
1682
 
-
 
1683
                case PARSEOP_REFOF:
-
 
1684
                case PARSEOP_INDEX:
-
 
1685
                default:
-
 
1686
                    break;
-
 
1687
 
-
 
1688
                }
-
 
1689
                break;
-
 
1690
 
-
 
1691
            case ARGI_INTEGER:
-
 
1692
            default:
-
 
1693
                break;
-
 
1694
            }
-
 
1695
 
-
 
1696
 
-
 
1697
            CommonBtypes = ThisNodeBtype & RequiredBtypes;
-
 
1698
 
-
 
1699
            if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
-
 
1700
            {
-
 
1701
                if (AnIsInternalMethod (ArgOp))
-
 
1702
                {
-
 
1703
                    return (AE_OK);
-
 
1704
                }
-
 
1705
 
-
 
1706
                /* Check a method call for a valid return value */
-
 
1707
 
-
 
1708
                AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
-
 
1709
                    RequiredBtypes, ThisNodeBtype);
-
 
1710
            }
-
 
1711
 
-
 
1712
            /*
-
 
1713
             * Now check if the actual type(s) match at least one
-
 
1714
             * bit to the required type
-
 
1715
             */
-
 
1716
            else if (!CommonBtypes)
-
 
1717
            {
-
 
1718
                /* No match -- this is a type mismatch error */
-
 
1719
 
-
 
1720
                AnFormatBtype (StringBuffer, ThisNodeBtype);
-
 
1721
                AnFormatBtype (StringBuffer2, RequiredBtypes);
-
 
1722
 
-
 
1723
                sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
-
 
1724
                            StringBuffer, OpInfo->Name, StringBuffer2);
-
 
1725
 
-
 
1726
                AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
-
 
1727
            }
-
 
1728
 
-
 
1729
        NextArgument:
-
 
1730
            ArgOp = ArgOp->Asl.Next;
-
 
1731
            INCREMENT_ARG_LIST (RuntimeArgTypes2);
-
 
1732
        }
-
 
1733
        break;
-
 
1734
 
-
 
1735
    default:
-
 
1736
        break;
-
 
1737
    }
-
 
1738
 
-
 
1739
    return (AE_OK);
-
 
1740
}
-
 
1741
 
-
 
1742
 
-
 
1743
/*******************************************************************************
-
 
1744
 *
395
/*******************************************************************************
1745
 * FUNCTION:    AnIsResultUsed
396
 *
1746
 *
397
 * FUNCTION:    AnIsResultUsed
1747
 * PARAMETERS:  Op              - Parent op for the operator
398
 *
1748
 *
399
 * PARAMETERS:  Op                  - Parent op for the operator
Line 1808... Line 459...
1808
 
459
}
Line 1809... Line 460...
1809
 
460
 
1810
/*******************************************************************************
461
 
1811
 *
462
/*******************************************************************************
1812
 * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
463
 *
1813
 *
464
 * FUNCTION:    ApCheckForGpeNameConflict
1814
 * PARAMETERS:  ASL_WALK_CALLBACK
465
 *
1815
 *
466
 * PARAMETERS:  Op                  - Current parse op
1816
 * RETURN:      Status
467
 *
1817
 *
468
 * RETURN:      None
-
 
469
 *
1818
 * DESCRIPTION: Descending callback for the analysis walk. Checks for
470
 * DESCRIPTION: Check for a conflict between GPE names within this scope.
1819
 *              miscellaneous issues in the code.
471
 *              Conflict means two GPE names with the same GPE number, but
1820
 *
472
 *              different types -- such as _L1C and _E1C.
Line 1821... Line 473...
1821
 ******************************************************************************/
473
 *
1822
 
474
 ******************************************************************************/
1823
ACPI_STATUS
475
 
1824
AnOtherSemanticAnalysisWalkBegin (
-
 
1825
    ACPI_PARSE_OBJECT       *Op,
-
 
1826
    UINT32                  Level,
476
void
1827
    void                    *Context)
477
ApCheckForGpeNameConflict (
-
 
478
    ACPI_PARSE_OBJECT       *Op)
1828
{
479
{
1829
    ACPI_PARSE_OBJECT       *ArgNode;
480
    ACPI_PARSE_OBJECT       *NextOp;
Line -... Line 481...
-
 
481
    UINT32                  GpeNumber;
-
 
482
    char                    Name[ACPI_NAME_SIZE + 1];
1830
    ACPI_PARSE_OBJECT       *PrevArgNode = NULL;
483
    char                    Target[ACPI_NAME_SIZE];
-
 
484
 
Line 1831... Line 485...
1831
    const ACPI_OPCODE_INFO  *OpInfo;
485
 
1832
 
-
 
1833
 
-
 
1834
    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
-
 
1835
 
-
 
1836
    /*
-
 
1837
     * Determine if an execution class operator actually does something by
-
 
1838
     * checking if it has a target and/or the function return value is used.
486
    /* Need a null-terminated string version of NameSeg */
1839
     * (Target is optional, so a standalone statement can actually do nothing.)
-
 
1840
     */
487
 
1841
    if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
-
 
1842
        (OpInfo->Flags & AML_HAS_RETVAL) &&
488
    ACPI_MOVE_32_TO_32 (Name, &Op->Asl.NameSeg);
1843
        (!AnIsResultUsed (Op)))
-
 
1844
    {
-
 
1845
        if (OpInfo->Flags & AML_HAS_TARGET)
489
    Name[ACPI_NAME_SIZE] = 0;
1846
        {
490
 
1847
            /*
491
    /*
1848
             * Find the target node, it is always the last child. If the traget
492
     * For a GPE method:
1849
             * is not specified in the ASL, a default node of type Zero was
493
     * 1st char must be underscore
1850
             * created by the parser.
494
     * 2nd char must be L or E
1851
             */
-
 
1852
            ArgNode = Op->Asl.Child;
495
     * 3rd/4th chars must be a hex number
Line 1853... Line 496...
1853
            while (ArgNode->Asl.Next)
496
     */
Line 1854... Line 497...
1854
            {
497
    if ((Name[0] != '_') ||
1855
                PrevArgNode = ArgNode;
-
 
1856
                ArgNode = ArgNode->Asl.Next;
-
 
1857
            }
-
 
1858
 
-
 
1859
            /* Divide() is the only weird case, it has two targets */
-
 
1860
 
-
 
1861
            if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
-
 
1862
            {
-
 
1863
                if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) &&
-
 
1864
                    (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO))
-
 
1865
                {
-
 
1866
                    AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
-
 
1867
                }
-
 
1868
            }
-
 
1869
            else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO)
-
 
1870
            {
-
 
1871
                AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
-
 
1872
            }
-
 
1873
        }
498
       ((Name[1] != 'L') && (Name[1] != 'E')))
1874
        else
499
    {
1875
        {
-
 
1876
            /*
-
 
1877
             * Has no target and the result is not used. Only a couple opcodes
-
 
1878
             * can have this combination.
-
 
1879
             */
-
 
1880
            switch (Op->Asl.ParseOpcode)
-
 
1881
            {
-
 
1882
            case PARSEOP_ACQUIRE:
-
 
1883
            case PARSEOP_WAIT:
500
        return;
1884
            case PARSEOP_LOADTABLE:
-
 
1885
                break;
501
    }
Line 1886... Line -...
1886
 
-
 
1887
            default:
-
 
1888
                AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
-
 
1889
                break;
-
 
1890
            }
-
 
1891
        }
-
 
1892
    }
-
 
1893
 
-
 
1894
 
502
 
1895
    /*
-
 
1896
     * Semantic checks for individual ASL operators
503
    /* Verify 3rd/4th chars are a valid hex value */
1897
     */
504
 
1898
    switch (Op->Asl.ParseOpcode)
-
 
1899
    {
505
    GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
-
 
506
    if (GpeNumber == ACPI_UINT32_MAX)
Line 1900... Line 507...
1900
    case PARSEOP_ACQUIRE:
507
    {
Line 1901... Line -...
1901
    case PARSEOP_WAIT:
-
 
1902
        /*
-
 
1903
         * Emit a warning if the timeout parameter for these operators is not
-
 
1904
         * ACPI_WAIT_FOREVER, and the result value from the operator is not
-
 
1905
         * checked, meaning that a timeout could happen, but the code
-
 
1906
         * would not know about it.
508
        return;
1907
         */
-
 
1908
 
-
 
1909
        /* First child is the namepath, 2nd child is timeout */
-
 
1910
 
-
 
1911
        ArgNode = Op->Asl.Child;
509
    }
1912
        ArgNode = ArgNode->Asl.Next;
510
 
1913
 
511
    /*
1914
        /*
-
 
1915
         * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
-
 
1916
         * 0xFFFF or greater
-
 
1917
         */
-
 
1918
        if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
-
 
1919
             (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
512
     * We are now sure we have an _Lxx or _Exx.
1920
             (ArgNode->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
513
     * Create the target name that would cause collision (Flip E/L)
1921
        {
514
     */
1922
            break;
515
    ACPI_MOVE_32_TO_32 (Target, Name);
1923
        }
-
 
Line -... Line 516...
-
 
516
 
-
 
517
    /* Inject opposite letter ("L" versus "E") */
1924
 
518
 
-
 
519
    if (Name[1] == 'L')
-
 
520
    {
1925
        /*
521
        Target[1] = 'E';
1926
         * The operation could timeout. If the return value is not used
522
    }
-
 
523
    else /* Name[1] == 'E' */
-
 
524
    {
1927
         * (indicates timeout occurred), issue a warning
525
        Target[1] = 'L';
1928
         */
-
 
1929
        if (!AnIsResultUsed (Op))
-
 
1930
        {
-
 
1931
            AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode, Op->Asl.ExternalName);
-
 
1932
        }
526
    }
1933
        break;
527
 
-
 
528
    /* Search all peers (objects within this scope) for target match */
1934
 
529
 
1935
    case PARSEOP_CREATEFIELD:
530
    NextOp = Op->Asl.Next;
-
 
531
    while (NextOp)
-
 
532
    {
1936
        /*
533
        /*
-
 
534
         * We mostly care about methods, but check Name() constructs also,
-
 
535
         * even though they will get another error for not being a method.
-
 
536
         * All GPE names must be defined as control methods.
1937
         * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
537
         */
1938
         */
-
 
Line 1939... Line -...
1939
        ArgNode = Op->Asl.Child;
-
 
1940
        ArgNode = ArgNode->Asl.Next;
538
        if ((NextOp->Asl.ParseOpcode == PARSEOP_METHOD) ||
1941
        ArgNode = ArgNode->Asl.Next;
539
            (NextOp->Asl.ParseOpcode == PARSEOP_NAME))
Line -... Line 540...
-
 
540
        {
-
 
541
            if (ACPI_COMPARE_NAME (Target, NextOp->Asl.NameSeg))
1942
 
542
            {
1943
        if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) ||
543
                /* Found both _Exy and _Lxy in the same scope, error */
Line 1944... Line 544...
1944
           ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) &&
544
 
1945
            (ArgNode->Asl.Value.Integer == 0)))
545
                AslError (ASL_ERROR, ASL_MSG_GPE_NAME_CONFLICT, NextOp,
1946
        {
546
                    Name);
1947
            AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL);
547
                return;
1948
        }
548
            }
1949
        break;
549
        }
1950
 
550
 
1951
    default:
551
        NextOp = NextOp->Asl.Next;
1952
        break;
552
    }
-
 
553
 
-
 
554
    /* OK, no conflict found */
1953
    }
555
 
1954
 
556
    return;
1955
    return AE_OK;
557
}
Line 1956... Line 558...
1956
}
558
 
1957
 
559
 
1958
 
560
/*******************************************************************************
1959
/*******************************************************************************
-
 
1960
 *
-
 
1961
 * FUNCTION:    AnOtherSemanticAnalysisWalkEnd
561
 *
-
 
562
 * FUNCTION:    ApCheckRegMethod
-
 
563
 *
Line 1962... Line -...
1962
 *
-
 
Line 1963... Line -...
1963
 * PARAMETERS:  ASL_WALK_CALLBACK
-
 
-
 
564
 * PARAMETERS:  Op                  - Current parse op
Line -... Line 565...
-
 
565
 *
-
 
566
 * RETURN:      None
-
 
567
 *
-
 
568
 * DESCRIPTION: Ensure that a _REG method has a corresponding Operation
Line 1964... Line -...
1964
 *
-
 
1965
 * RETURN:      Status
-
 
1966
 *
-
 
1967
 * DESCRIPTION: Ascending callback for analysis walk. Complete method
-
 
1968
 *              return analysis.
-
 
1969
 *
-
 
1970
 ******************************************************************************/
-
 
1971
 
569
 *              Region declaration within the same scope. Note: _REG is defined
1972
ACPI_STATUS
-
 
1973
AnOtherSemanticAnalysisWalkEnd (
-
 
1974
    ACPI_PARSE_OBJECT       *Op,
-
 
1975
    UINT32                  Level,
-
 
Line 1976... Line -...
1976
    void                    *Context)
-
 
1977
{
-
 
1978
 
-
 
1979
    return AE_OK;
-
 
1980
 
570
 *              to have two arguments and must therefore be defined as a
1981
}
571
 *              control method.
Line -... Line 572...
-
 
572
 *
Line 1982... Line 573...
1982
 
573
 ******************************************************************************/
1983
 
574
 
1984
#ifdef ACPI_OBSOLETE_FUNCTIONS
-
 
1985
/*******************************************************************************
-
 
1986
 *
-
 
1987
 * FUNCTION:    AnMapBtypeToEtype
-
 
1988
 *
575
void
1989
 * PARAMETERS:  Btype               - Bitfield of ACPI types
576
ApCheckRegMethod (
1990
 *
577
    ACPI_PARSE_OBJECT       *Op)
1991
 * RETURN:      The Etype corresponding the the Btype
578
{
Line 1992... Line 579...
1992
 *
579
    ACPI_PARSE_OBJECT       *Next;
1993
 * DESCRIPTION: Convert a bitfield type to an encoded type
580
    ACPI_PARSE_OBJECT       *Parent;
1994
 *
-
 
Line -... Line 581...
-
 
581
 
-
 
582
 
-
 
583
    /* We are only interested in _REG methods */
-
 
584