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: nspredef - Validation of ACPI predefined methods and objects
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
#define ACPI_CREATE_PREDEFINED_TABLE
117
 
118
#include "acpi.h"
119
#include "accommon.h"
120
#include "acnamesp.h"
121
#include "acpredef.h"
122
 
123
 
124
#define _COMPONENT          ACPI_NAMESPACE
125
        ACPI_MODULE_NAME    ("nspredef")
126
 
127
 
128
/*******************************************************************************
129
 *
130
 * This module validates predefined ACPI objects that appear in the namespace,
131
 * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
132
 * validation is to detect problems with BIOS-exposed predefined ACPI objects
133
 * before the results are returned to the ACPI-related drivers.
134
 *
135
 * There are several areas that are validated:
136
 *
137
 *  1) The number of input arguments as defined by the method/object in the
138
 *      ASL is validated against the ACPI specification.
139
 *  2) The type of the return object (if any) is validated against the ACPI
140
 *      specification.
141
 *  3) For returned package objects, the count of package elements is
142
 *      validated, as well as the type of each package element. Nested
143
 *      packages are supported.
144
 *
145
 * For any problems found, a warning message is issued.
146
 *
147
 ******************************************************************************/
148
 
149
 
150
/* Local prototypes */
151
 
152
static ACPI_STATUS
153
AcpiNsCheckPackage (
154
    ACPI_PREDEFINED_DATA        *Data,
155
    ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
156
 
157
static ACPI_STATUS
158
AcpiNsCheckPackageList (
159
    ACPI_PREDEFINED_DATA        *Data,
160
    const ACPI_PREDEFINED_INFO  *Package,
161
    ACPI_OPERAND_OBJECT         **Elements,
162
    UINT32                      Count);
163
 
164
static ACPI_STATUS
165
AcpiNsCheckPackageElements (
166
    ACPI_PREDEFINED_DATA        *Data,
167
    ACPI_OPERAND_OBJECT         **Elements,
168
    UINT8                       Type1,
169
    UINT32                      Count1,
170
    UINT8                       Type2,
171
    UINT32                      Count2,
172
    UINT32                      StartIndex);
173
 
174
static ACPI_STATUS
175
AcpiNsCheckObjectType (
176
    ACPI_PREDEFINED_DATA        *Data,
177
    ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
178
    UINT32                      ExpectedBtypes,
179
    UINT32                      PackageIndex);
180
 
181
static ACPI_STATUS
182
AcpiNsCheckReference (
183
    ACPI_PREDEFINED_DATA        *Data,
184
    ACPI_OPERAND_OBJECT         *ReturnObject);
185
 
186
static void
187
AcpiNsGetExpectedTypes (
188
    char                        *Buffer,
189
    UINT32                      ExpectedBtypes);
190
 
191
/*
192
 * Names for the types that can be returned by the predefined objects.
193
 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
194
 */
195
static const char   *AcpiRtypeNames[] =
196
{
197
    "/Integer",
198
    "/String",
199
    "/Buffer",
200
    "/Package",
201
    "/Reference",
202
};
203
 
204
 
205
/*******************************************************************************
206
 *
207
 * FUNCTION:    AcpiNsCheckPredefinedNames
208
 *
209
 * PARAMETERS:  Node            - Namespace node for the method/object
210
 *              UserParamCount  - Number of parameters actually passed
211
 *              ReturnStatus    - Status from the object evaluation
212
 *              ReturnObjectPtr - Pointer to the object returned from the
213
 *                                evaluation of a method or object
214
 *
215
 * RETURN:      Status
216
 *
217
 * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
218
 *
219
 ******************************************************************************/
220
 
221
ACPI_STATUS
222
AcpiNsCheckPredefinedNames (
223
    ACPI_NAMESPACE_NODE         *Node,
224
    UINT32                      UserParamCount,
225
    ACPI_STATUS                 ReturnStatus,
226
    ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
227
{
228
    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
229
    ACPI_STATUS                 Status = AE_OK;
230
    const ACPI_PREDEFINED_INFO  *Predefined;
231
    char                        *Pathname;
232
    ACPI_PREDEFINED_DATA        *Data;
233
 
234
 
235
    /* Match the name for this method/object against the predefined list */
236
 
237
    Predefined = AcpiNsCheckForPredefinedName (Node);
238
 
239
    /* Get the full pathname to the object, for use in warning messages */
240
 
241
    Pathname = AcpiNsGetExternalPathname (Node);
242
    if (!Pathname)
243
    {
244
        return (AE_OK); /* Could not get pathname, ignore */
245
    }
246
 
247
    /*
248
     * Check that the parameter count for this method matches the ASL
249
     * definition. For predefined names, ensure that both the caller and
250
     * the method itself are in accordance with the ACPI specification.
251
     */
252
    AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined);
253
 
254
    /* If not a predefined name, we cannot validate the return object */
255
 
256
    if (!Predefined)
257
    {
258
        goto Cleanup;
259
    }
260
 
261
    /*
262
     * If the method failed or did not actually return an object, we cannot
263
     * validate the return object
264
     */
265
    if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
266
    {
267
        goto Cleanup;
268
    }
269
 
270
    /*
271
     * If there is no return value, check if we require a return value for
272
     * this predefined name. Either one return value is expected, or none,
273
     * for both methods and other objects.
274
     *
275
     * Exit now if there is no return object. Warning if one was expected.
276
     */
277
    if (!ReturnObject)
278
    {
279
        if ((Predefined->Info.ExpectedBtypes) &&
280
            (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
281
        {
282
            ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
283
                "Missing expected return value"));
284
 
285
            Status = AE_AML_NO_RETURN_VALUE;
286
        }
287
        goto Cleanup;
288
    }
289
 
290
    /*
2216 Serge 291
     * Return value validation and possible repair.
1498 serge 292
     *
2216 Serge 293
     * 1) Don't perform return value validation/repair if this feature
294
     * has been disabled via a global option.
295
     *
296
     * 2) We have a return value, but if one wasn't expected, just exit,
297
     * this is not a problem. For example, if the "Implicit Return"
298
     * feature is enabled, methods will always return a value.
299
     *
300
     * 3) If the return value can be of any type, then we cannot perform
301
     * any validation, just exit.
1498 serge 302
     */
2216 Serge 303
    if (AcpiGbl_DisableAutoRepair ||
304
        (!Predefined->Info.ExpectedBtypes) ||
1498 serge 305
        (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL))
306
    {
307
        goto Cleanup;
308
    }
309
 
310
    /* Create the parameter data block for object validation */
311
 
312
    Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA));
313
    if (!Data)
314
    {
315
        goto Cleanup;
316
    }
317
    Data->Predefined = Predefined;
2216 Serge 318
    Data->Node = Node;
1498 serge 319
    Data->NodeFlags = Node->Flags;
320
    Data->Pathname = Pathname;
321
 
322
    /*
323
     * Check that the type of the main return object is what is expected
324
     * for this predefined name
325
     */
326
    Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr,
327
                Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
328
    if (ACPI_FAILURE (Status))
329
    {
330
        goto Exit;
331
    }
332
 
333
    /*
334
     * For returned Package objects, check the type of all sub-objects.
335
     * Note: Package may have been newly created by call above.
336
     */
337
    if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE)
338
    {
339
        Data->ParentPackage = *ReturnObjectPtr;
340
        Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
341
        if (ACPI_FAILURE (Status))
342
        {
343
            goto Exit;
344
        }
345
    }
346
 
347
    /*
348
     * The return object was OK, or it was successfully repaired above.
349
     * Now make some additional checks such as verifying that package
350
     * objects are sorted correctly (if required) or buffer objects have
351
     * the correct data width (bytes vs. dwords). These repairs are
352
     * performed on a per-name basis, i.e., the code is specific to
353
     * particular predefined names.
354
     */
355
    Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr);
356
 
357
Exit:
358
    /*
359
     * If the object validation failed or if we successfully repaired one
360
     * or more objects, mark the parent node to suppress further warning
361
     * messages during the next evaluation of the same method/object.
362
     */
363
    if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED))
364
    {
365
        Node->Flags |= ANOBJ_EVALUATED;
366
    }
367
    ACPI_FREE (Data);
368
 
369
Cleanup:
370
    ACPI_FREE (Pathname);
371
    return (Status);
372
}
373
 
374
 
375
/*******************************************************************************
376
 *
377
 * FUNCTION:    AcpiNsCheckParameterCount
378
 *
379
 * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
380
 *              Node            - Namespace node for the method/object
381
 *              UserParamCount  - Number of args passed in by the caller
382
 *              Predefined      - Pointer to entry in predefined name table
383
 *
384
 * RETURN:      None
385
 *
386
 * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
387
 *              predefined name is what is expected (i.e., what is defined in
388
 *              the ACPI specification for this predefined name.)
389
 *
390
 ******************************************************************************/
391
 
392
void
393
AcpiNsCheckParameterCount (
394
    char                        *Pathname,
395
    ACPI_NAMESPACE_NODE         *Node,
396
    UINT32                      UserParamCount,
397
    const ACPI_PREDEFINED_INFO  *Predefined)
398
{
399
    UINT32                      ParamCount;
400
    UINT32                      RequiredParamsCurrent;
401
    UINT32                      RequiredParamsOld;
402
 
403
 
404
    /* Methods have 0-7 parameters. All other types have zero. */
405
 
406
    ParamCount = 0;
407
    if (Node->Type == ACPI_TYPE_METHOD)
408
    {
409
        ParamCount = Node->Object->Method.ParamCount;
410
    }
411
 
412
    if (!Predefined)
413
    {
414
        /*
415
         * Check the parameter count for non-predefined methods/objects.
416
         *
417
         * Warning if too few or too many arguments have been passed by the
418
         * caller. An incorrect number of arguments may not cause the method
419
         * to fail. However, the method will fail if there are too few
420
         * arguments and the method attempts to use one of the missing ones.
421
         */
422
        if (UserParamCount < ParamCount)
423
        {
424
            ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
425
                "Insufficient arguments - needs %u, found %u",
426
                ParamCount, UserParamCount));
427
        }
428
        else if (UserParamCount > ParamCount)
429
        {
430
            ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
431
                "Excess arguments - needs %u, found %u",
432
                ParamCount, UserParamCount));
433
        }
434
        return;
435
    }
436
 
437
    /*
438
     * Validate the user-supplied parameter count.
439
     * Allow two different legal argument counts (_SCP, etc.)
440
     */
441
    RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
442
    RequiredParamsOld = Predefined->Info.ParamCount >> 4;
443
 
444
    if (UserParamCount != ACPI_UINT32_MAX)
445
    {
446
        if ((UserParamCount != RequiredParamsCurrent) &&
447
            (UserParamCount != RequiredParamsOld))
448
        {
449
            ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
450
                "Parameter count mismatch - "
451
                "caller passed %u, ACPI requires %u",
452
                UserParamCount, RequiredParamsCurrent));
453
        }
454
    }
455
 
456
    /*
457
     * Check that the ASL-defined parameter count is what is expected for
458
     * this predefined name (parameter count as defined by the ACPI
459
     * specification)
460
     */
461
    if ((ParamCount != RequiredParamsCurrent) &&
462
        (ParamCount != RequiredParamsOld))
463
    {
464
        ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags,
465
            "Parameter count mismatch - ASL declared %u, ACPI requires %u",
466
            ParamCount, RequiredParamsCurrent));
467
    }
468
}
469
 
470
 
471
/*******************************************************************************
472
 *
473
 * FUNCTION:    AcpiNsCheckForPredefinedName
474
 *
475
 * PARAMETERS:  Node            - Namespace node for the method/object
476
 *
477
 * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
478
 *
479
 * DESCRIPTION: Check an object name against the predefined object list.
480
 *
481
 ******************************************************************************/
482
 
483
const ACPI_PREDEFINED_INFO *
484
AcpiNsCheckForPredefinedName (
485
    ACPI_NAMESPACE_NODE         *Node)
486
{
487
    const ACPI_PREDEFINED_INFO  *ThisName;
488
 
489
 
490
    /* Quick check for a predefined name, first character must be underscore */
491
 
492
    if (Node->Name.Ascii[0] != '_')
493
    {
494
        return (NULL);
495
    }
496
 
497
    /* Search info table for a predefined method/object name */
498
 
499
    ThisName = PredefinedNames;
500
    while (ThisName->Info.Name[0])
501
    {
502
        if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
503
        {
504
            return (ThisName);
505
        }
506
 
507
        /*
508
         * Skip next entry in the table if this name returns a Package
509
         * (next entry contains the package info)
510
         */
511
        if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
512
        {
513
            ThisName++;
514
        }
515
 
516
        ThisName++;
517
    }
518
 
519
    return (NULL); /* Not found */
520
}
521
 
522
 
523
/*******************************************************************************
524
 *
525
 * FUNCTION:    AcpiNsCheckPackage
526
 *
527
 * PARAMETERS:  Data            - Pointer to validation data structure
528
 *              ReturnObjectPtr - Pointer to the object returned from the
529
 *                                evaluation of a method or object
530
 *
531
 * RETURN:      Status
532
 *
533
 * DESCRIPTION: Check a returned package object for the correct count and
534
 *              correct type of all sub-objects.
535
 *
536
 ******************************************************************************/
537
 
538
static ACPI_STATUS
539
AcpiNsCheckPackage (
540
    ACPI_PREDEFINED_DATA        *Data,
541
    ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
542
{
543
    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
544
    const ACPI_PREDEFINED_INFO  *Package;
545
    ACPI_OPERAND_OBJECT         **Elements;
546
    ACPI_STATUS                 Status = AE_OK;
547
    UINT32                      ExpectedCount;
548
    UINT32                      Count;
549
    UINT32                      i;
550
 
551
 
552
    ACPI_FUNCTION_NAME (NsCheckPackage);
553
 
554
 
555
    /* The package info for this name is in the next table entry */
556
 
557
    Package = Data->Predefined + 1;
558
 
559
    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
560
        "%s Validating return Package of Type %X, Count %X\n",
561
        Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
562
 
563
    /*
564
     * For variable-length Packages, we can safely remove all embedded
565
     * and trailing NULL package elements
566
     */
567
    AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject);
568
 
569
    /* Extract package count and elements array */
570
 
571
    Elements = ReturnObject->Package.Elements;
572
    Count = ReturnObject->Package.Count;
573
 
574
    /* The package must have at least one element, else invalid */
575
 
576
    if (!Count)
577
    {
578
        ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
579
            "Return Package has no elements (empty)"));
580
 
581
        return (AE_AML_OPERAND_VALUE);
582
    }
583
 
584
    /*
585
     * Decode the type of the expected package contents
586
     *
587
     * PTYPE1 packages contain no subpackages
588
     * PTYPE2 packages contain sub-packages
589
     */
590
    switch (Package->RetInfo.Type)
591
    {
592
    case ACPI_PTYPE1_FIXED:
593
 
594
        /*
595
         * The package count is fixed and there are no sub-packages
596
         *
597
         * If package is too small, exit.
598
         * If package is larger than expected, issue warning but continue
599
         */
600
        ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
601
        if (Count < ExpectedCount)
602
        {
603
            goto PackageTooSmall;
604
        }
605
        else if (Count > ExpectedCount)
606
        {
607
            ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
608
                "%s: Return Package is larger than needed - "
609
                "found %u, expected %u\n",
610
                Data->Pathname, Count, ExpectedCount));
611
        }
612
 
613
        /* Validate all elements of the returned package */
614
 
615
        Status = AcpiNsCheckPackageElements (Data, Elements,
616
                    Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
617
                    Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
618
        break;
619
 
620
 
621
    case ACPI_PTYPE1_VAR:
622
 
623
        /*
624
         * The package count is variable, there are no sub-packages, and all
625
         * elements must be of the same type
626
         */
627
        for (i = 0; i < Count; i++)
628
        {
629
            Status = AcpiNsCheckObjectType (Data, Elements,
630
                        Package->RetInfo.ObjectType1, i);
631
            if (ACPI_FAILURE (Status))
632
            {
633
                return (Status);
634
            }
635
            Elements++;
636
        }
637
        break;
638
 
639
 
640
    case ACPI_PTYPE1_OPTION:
641
 
642
        /*
643
         * The package count is variable, there are no sub-packages. There are
644
         * a fixed number of required elements, and a variable number of
645
         * optional elements.
646
         *
647
         * Check if package is at least as large as the minimum required
648
         */
649
        ExpectedCount = Package->RetInfo3.Count;
650
        if (Count < ExpectedCount)
651
        {
652
            goto PackageTooSmall;
653
        }
654
 
655
        /* Variable number of sub-objects */
656
 
657
        for (i = 0; i < Count; i++)
658
        {
659
            if (i < Package->RetInfo3.Count)
660
            {
661
                /* These are the required package elements (0, 1, or 2) */
662
 
663
                Status = AcpiNsCheckObjectType (Data, Elements,
664
                            Package->RetInfo3.ObjectType[i], i);
665
                if (ACPI_FAILURE (Status))
666
                {
667
                    return (Status);
668
                }
669
            }
670
            else
671
            {
672
                /* These are the optional package elements */
673
 
674
                Status = AcpiNsCheckObjectType (Data, Elements,
675
                            Package->RetInfo3.TailObjectType, i);
676
                if (ACPI_FAILURE (Status))
677
                {
678
                    return (Status);
679
                }
680
            }
681
            Elements++;
682
        }
683
        break;
684
 
685
 
686
    case ACPI_PTYPE2_REV_FIXED:
687
 
688
        /* First element is the (Integer) revision */
689
 
690
        Status = AcpiNsCheckObjectType (Data, Elements,
691
                    ACPI_RTYPE_INTEGER, 0);
692
        if (ACPI_FAILURE (Status))
693
        {
694
            return (Status);
695
        }
696
 
697
        Elements++;
698
        Count--;
699
 
700
        /* Examine the sub-packages */
701
 
702
        Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
703
        break;
704
 
705
 
706
    case ACPI_PTYPE2_PKG_COUNT:
707
 
708
        /* First element is the (Integer) count of sub-packages to follow */
709
 
710
        Status = AcpiNsCheckObjectType (Data, Elements,
711
                    ACPI_RTYPE_INTEGER, 0);
712
        if (ACPI_FAILURE (Status))
713
        {
714
            return (Status);
715
        }
716
 
717
        /*
718
         * Count cannot be larger than the parent package length, but allow it
719
         * to be smaller. The >= accounts for the Integer above.
720
         */
721
        ExpectedCount = (UINT32) (*Elements)->Integer.Value;
722
        if (ExpectedCount >= Count)
723
        {
724
            goto PackageTooSmall;
725
        }
726
 
727
        Count = ExpectedCount;
728
        Elements++;
729
 
730
        /* Examine the sub-packages */
731
 
732
        Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
733
        break;
734
 
735
 
736
    case ACPI_PTYPE2:
737
    case ACPI_PTYPE2_FIXED:
738
    case ACPI_PTYPE2_MIN:
739
    case ACPI_PTYPE2_COUNT:
740
 
741
        /*
742
         * These types all return a single Package that consists of a
743
         * variable number of sub-Packages.
744
         *
745
         * First, ensure that the first element is a sub-Package. If not,
746
         * the BIOS may have incorrectly returned the object as a single
747
         * package instead of a Package of Packages (a common error if
748
         * there is only one entry). We may be able to repair this by
749
         * wrapping the returned Package with a new outer Package.
750
         */
751
        if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
752
        {
753
            /* Create the new outer package and populate it */
754
 
755
            Status = AcpiNsRepairPackageList (Data, ReturnObjectPtr);
756
            if (ACPI_FAILURE (Status))
757
            {
758
                return (Status);
759
            }
760
 
761
            /* Update locals to point to the new package (of 1 element) */
762
 
763
            ReturnObject = *ReturnObjectPtr;
764
            Elements = ReturnObject->Package.Elements;
765
            Count = 1;
766
        }
767
 
768
        /* Examine the sub-packages */
769
 
770
        Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
771
        break;
772
 
773
 
774
    default:
775
 
776
        /* Should not get here if predefined info table is correct */
777
 
778
        ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
779
            "Invalid internal return type in table entry: %X",
780
            Package->RetInfo.Type));
781
 
782
        return (AE_AML_INTERNAL);
783
    }
784
 
785
    return (Status);
786
 
787
 
788
PackageTooSmall:
789
 
790
    /* Error exit for the case with an incorrect package count */
791
 
792
    ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
793
        "Return Package is too small - found %u elements, expected %u",
794
        Count, ExpectedCount));
795
 
796
    return (AE_AML_OPERAND_VALUE);
797
}
798
 
799
 
800
/*******************************************************************************
801
 *
802
 * FUNCTION:    AcpiNsCheckPackageList
803
 *
804
 * PARAMETERS:  Data            - Pointer to validation data structure
805
 *              Package         - Pointer to package-specific info for method
806
 *              Elements        - Element list of parent package. All elements
807
 *                                of this list should be of type Package.
808
 *              Count           - Count of subpackages
809
 *
810
 * RETURN:      Status
811
 *
812
 * DESCRIPTION: Examine a list of subpackages
813
 *
814
 ******************************************************************************/
815
 
816
static ACPI_STATUS
817
AcpiNsCheckPackageList (
818
    ACPI_PREDEFINED_DATA        *Data,
819
    const ACPI_PREDEFINED_INFO  *Package,
820
    ACPI_OPERAND_OBJECT         **Elements,
821
    UINT32                      Count)
822
{
823
    ACPI_OPERAND_OBJECT         *SubPackage;
824
    ACPI_OPERAND_OBJECT         **SubElements;
825
    ACPI_STATUS                 Status;
826
    UINT32                      ExpectedCount;
827
    UINT32                      i;
828
    UINT32                      j;
829
 
830
 
831
    /*
832
     * Validate each sub-Package in the parent Package
833
     *
834
     * NOTE: assumes list of sub-packages contains no NULL elements.
835
     * Any NULL elements should have been removed by earlier call
836
     * to AcpiNsRemoveNullElements.
837
     */
838
    for (i = 0; i < Count; i++)
839
    {
840
        SubPackage = *Elements;
841
        SubElements = SubPackage->Package.Elements;
842
        Data->ParentPackage = SubPackage;
843
 
844
        /* Each sub-object must be of type Package */
845
 
846
        Status = AcpiNsCheckObjectType (Data, &SubPackage,
847
                    ACPI_RTYPE_PACKAGE, i);
848
        if (ACPI_FAILURE (Status))
849
        {
850
            return (Status);
851
        }
852
 
853
        /* Examine the different types of expected sub-packages */
854
 
855
        Data->ParentPackage = SubPackage;
856
        switch (Package->RetInfo.Type)
857
        {
858
        case ACPI_PTYPE2:
859
        case ACPI_PTYPE2_PKG_COUNT:
860
        case ACPI_PTYPE2_REV_FIXED:
861
 
862
            /* Each subpackage has a fixed number of elements */
863
 
864
            ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
865
            if (SubPackage->Package.Count < ExpectedCount)
866
            {
867
                goto PackageTooSmall;
868
            }
869
 
870
            Status = AcpiNsCheckPackageElements (Data, SubElements,
871
                        Package->RetInfo.ObjectType1,
872
                        Package->RetInfo.Count1,
873
                        Package->RetInfo.ObjectType2,
874
                        Package->RetInfo.Count2, 0);
875
            if (ACPI_FAILURE (Status))
876
            {
877
                return (Status);
878
            }
879
            break;
880
 
881
 
882
        case ACPI_PTYPE2_FIXED:
883
 
884
            /* Each sub-package has a fixed length */
885
 
886
            ExpectedCount = Package->RetInfo2.Count;
887
            if (SubPackage->Package.Count < ExpectedCount)
888
            {
889
                goto PackageTooSmall;
890
            }
891
 
892
            /* Check the type of each sub-package element */
893
 
894
            for (j = 0; j < ExpectedCount; j++)
895
            {
896
                Status = AcpiNsCheckObjectType (Data, &SubElements[j],
897
                            Package->RetInfo2.ObjectType[j], j);
898
                if (ACPI_FAILURE (Status))
899
                {
900
                    return (Status);
901
                }
902
            }
903
            break;
904
 
905
 
906
        case ACPI_PTYPE2_MIN:
907
 
908
            /* Each sub-package has a variable but minimum length */
909
 
910
            ExpectedCount = Package->RetInfo.Count1;
911
            if (SubPackage->Package.Count < ExpectedCount)
912
            {
913
                goto PackageTooSmall;
914
            }
915
 
916
            /* Check the type of each sub-package element */
917
 
918
            Status = AcpiNsCheckPackageElements (Data, SubElements,
919
                        Package->RetInfo.ObjectType1,
920
                        SubPackage->Package.Count, 0, 0, 0);
921
            if (ACPI_FAILURE (Status))
922
            {
923
                return (Status);
924
            }
925
            break;
926
 
927
 
928
        case ACPI_PTYPE2_COUNT:
929
 
930
            /*
931
             * First element is the (Integer) count of elements, including
932
             * the count field (the ACPI name is NumElements)
933
             */
934
            Status = AcpiNsCheckObjectType (Data, SubElements,
935
                        ACPI_RTYPE_INTEGER, 0);
936
            if (ACPI_FAILURE (Status))
937
            {
938
                return (Status);
939
            }
940
 
941
            /*
942
             * Make sure package is large enough for the Count and is
943
             * is as large as the minimum size
944
             */
945
            ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
946
            if (SubPackage->Package.Count < ExpectedCount)
947
            {
948
                goto PackageTooSmall;
949
            }
950
            if (SubPackage->Package.Count < Package->RetInfo.Count1)
951
            {
952
                ExpectedCount = Package->RetInfo.Count1;
953
                goto PackageTooSmall;
954
            }
955
            if (ExpectedCount == 0)
956
            {
957
                /*
958
                 * Either the NumEntries element was originally zero or it was
959
                 * a NULL element and repaired to an Integer of value zero.
960
                 * In either case, repair it by setting NumEntries to be the
961
                 * actual size of the subpackage.
962
                 */
963
                ExpectedCount = SubPackage->Package.Count;
964
                (*SubElements)->Integer.Value = ExpectedCount;
965
            }
966
 
967
            /* Check the type of each sub-package element */
968
 
969
            Status = AcpiNsCheckPackageElements (Data, (SubElements + 1),
970
                        Package->RetInfo.ObjectType1,
971
                        (ExpectedCount - 1), 0, 0, 1);
972
            if (ACPI_FAILURE (Status))
973
            {
974
                return (Status);
975
            }
976
            break;
977
 
978
 
979
        default: /* Should not get here, type was validated by caller */
980
 
981
            return (AE_AML_INTERNAL);
982
        }
983
 
984
        Elements++;
985
    }
986
 
987
    return (AE_OK);
988
 
989
 
990
PackageTooSmall:
991
 
992
    /* The sub-package count was smaller than required */
993
 
994
    ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
995
        "Return Sub-Package[%u] is too small - found %u elements, expected %u",
996
        i, SubPackage->Package.Count, ExpectedCount));
997
 
998
    return (AE_AML_OPERAND_VALUE);
999
}
1000
 
1001
 
1002
/*******************************************************************************
1003
 *
1004
 * FUNCTION:    AcpiNsCheckPackageElements
1005
 *
1006
 * PARAMETERS:  Data            - Pointer to validation data structure
1007
 *              Elements        - Pointer to the package elements array
1008
 *              Type1           - Object type for first group
1009
 *              Count1          - Count for first group
1010
 *              Type2           - Object type for second group
1011
 *              Count2          - Count for second group
1012
 *              StartIndex      - Start of the first group of elements
1013
 *
1014
 * RETURN:      Status
1015
 *
1016
 * DESCRIPTION: Check that all elements of a package are of the correct object
1017
 *              type. Supports up to two groups of different object types.
1018
 *
1019
 ******************************************************************************/
1020
 
1021
static ACPI_STATUS
1022
AcpiNsCheckPackageElements (
1023
    ACPI_PREDEFINED_DATA        *Data,
1024
    ACPI_OPERAND_OBJECT         **Elements,
1025
    UINT8                       Type1,
1026
    UINT32                      Count1,
1027
    UINT8                       Type2,
1028
    UINT32                      Count2,
1029
    UINT32                      StartIndex)
1030
{
1031
    ACPI_OPERAND_OBJECT         **ThisElement = Elements;
1032
    ACPI_STATUS                 Status;
1033
    UINT32                      i;
1034
 
1035
 
1036
    /*
1037
     * Up to two groups of package elements are supported by the data
1038
     * structure. All elements in each group must be of the same type.
1039
     * The second group can have a count of zero.
1040
     */
1041
    for (i = 0; i < Count1; i++)
1042
    {
1043
        Status = AcpiNsCheckObjectType (Data, ThisElement,
1044
                    Type1, i + StartIndex);
1045
        if (ACPI_FAILURE (Status))
1046
        {
1047
            return (Status);
1048
        }
1049
        ThisElement++;
1050
    }
1051
 
1052
    for (i = 0; i < Count2; i++)
1053
    {
1054
        Status = AcpiNsCheckObjectType (Data, ThisElement,
1055
                    Type2, (i + Count1 + StartIndex));
1056
        if (ACPI_FAILURE (Status))
1057
        {
1058
            return (Status);
1059
        }
1060
        ThisElement++;
1061
    }
1062
 
1063
    return (AE_OK);
1064
}
1065
 
1066
 
1067
/*******************************************************************************
1068
 *
1069
 * FUNCTION:    AcpiNsCheckObjectType
1070
 *
1071
 * PARAMETERS:  Data            - Pointer to validation data structure
1072
 *              ReturnObjectPtr - Pointer to the object returned from the
1073
 *                                evaluation of a method or object
1074
 *              ExpectedBtypes  - Bitmap of expected return type(s)
1075
 *              PackageIndex    - Index of object within parent package (if
1076
 *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
1077
 *                                otherwise)
1078
 *
1079
 * RETURN:      Status
1080
 *
1081
 * DESCRIPTION: Check the type of the return object against the expected object
1082
 *              type(s). Use of Btype allows multiple expected object types.
1083
 *
1084
 ******************************************************************************/
1085
 
1086
static ACPI_STATUS
1087
AcpiNsCheckObjectType (
1088
    ACPI_PREDEFINED_DATA        *Data,
1089
    ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
1090
    UINT32                      ExpectedBtypes,
1091
    UINT32                      PackageIndex)
1092
{
1093
    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
1094
    ACPI_STATUS                 Status = AE_OK;
1095
    UINT32                      ReturnBtype;
1096
    char                        TypeBuffer[48]; /* Room for 5 types */
1097
 
1098
 
1099
    /*
1100
     * If we get a NULL ReturnObject here, it is a NULL package element.
1101
     * Since all extraneous NULL package elements were removed earlier by a
1102
     * call to AcpiNsRemoveNullElements, this is an unexpected NULL element.
1103
     * We will attempt to repair it.
1104
     */
1105
    if (!ReturnObject)
1106
    {
1107
        Status = AcpiNsRepairNullElement (Data, ExpectedBtypes,
1108
                    PackageIndex, ReturnObjectPtr);
1109
        if (ACPI_SUCCESS (Status))
1110
        {
1111
            return (AE_OK); /* Repair was successful */
1112
        }
1113
        goto TypeErrorExit;
1114
    }
1115
 
1116
    /* A Namespace node should not get here, but make sure */
1117
 
1118
    if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
1119
    {
1120
        ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1121
            "Invalid return type - Found a Namespace node [%4.4s] type %s",
1122
            ReturnObject->Node.Name.Ascii,
1123
            AcpiUtGetTypeName (ReturnObject->Node.Type)));
1124
        return (AE_AML_OPERAND_TYPE);
1125
    }
1126
 
1127
    /*
1128
     * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
1129
     * The bitmapped type allows multiple possible return types.
1130
     *
1131
     * Note, the cases below must handle all of the possible types returned
1132
     * from all of the predefined names (including elements of returned
1133
     * packages)
1134
     */
1135
    switch (ReturnObject->Common.Type)
1136
    {
1137
    case ACPI_TYPE_INTEGER:
1138
        ReturnBtype = ACPI_RTYPE_INTEGER;
1139
        break;
1140
 
1141
    case ACPI_TYPE_BUFFER:
1142
        ReturnBtype = ACPI_RTYPE_BUFFER;
1143
        break;
1144
 
1145
    case ACPI_TYPE_STRING:
1146
        ReturnBtype = ACPI_RTYPE_STRING;
1147
        break;
1148
 
1149
    case ACPI_TYPE_PACKAGE:
1150
        ReturnBtype = ACPI_RTYPE_PACKAGE;
1151
        break;
1152
 
1153
    case ACPI_TYPE_LOCAL_REFERENCE:
1154
        ReturnBtype = ACPI_RTYPE_REFERENCE;
1155
        break;
1156
 
1157
    default:
1158
        /* Not one of the supported objects, must be incorrect */
1159
 
1160
        goto TypeErrorExit;
1161
    }
1162
 
1163
    /* Is the object one of the expected types? */
1164
 
1165
    if (ReturnBtype & ExpectedBtypes)
1166
    {
1167
        /* For reference objects, check that the reference type is correct */
1168
 
1169
        if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
1170
        {
1171
            Status = AcpiNsCheckReference (Data, ReturnObject);
1172
        }
1173
 
1174
        return (Status);
1175
    }
1176
 
1177
    /* Type mismatch -- attempt repair of the returned object */
1178
 
1179
    Status = AcpiNsRepairObject (Data, ExpectedBtypes,
1180
                PackageIndex, ReturnObjectPtr);
1181
    if (ACPI_SUCCESS (Status))
1182
    {
1183
        return (AE_OK); /* Repair was successful */
1184
    }
1185
 
1186
 
1187
TypeErrorExit:
1188
 
1189
    /* Create a string with all expected types for this predefined object */
1190
 
1191
    AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes);
1192
 
1193
    if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
1194
    {
1195
        ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1196
            "Return type mismatch - found %s, expected %s",
1197
            AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1198
    }
1199
    else
1200
    {
1201
        ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1202
            "Return Package type mismatch at index %u - "
1203
            "found %s, expected %s", PackageIndex,
1204
            AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1205
    }
1206
 
1207
    return (AE_AML_OPERAND_TYPE);
1208
}
1209
 
1210
 
1211
/*******************************************************************************
1212
 *
1213
 * FUNCTION:    AcpiNsCheckReference
1214
 *
1215
 * PARAMETERS:  Data            - Pointer to validation data structure
1216
 *              ReturnObject    - Object returned from the evaluation of a
1217
 *                                method or object
1218
 *
1219
 * RETURN:      Status
1220
 *
1221
 * DESCRIPTION: Check a returned reference object for the correct reference
1222
 *              type. The only reference type that can be returned from a
1223
 *              predefined method is a named reference. All others are invalid.
1224
 *
1225
 ******************************************************************************/
1226
 
1227
static ACPI_STATUS
1228
AcpiNsCheckReference (
1229
    ACPI_PREDEFINED_DATA        *Data,
1230
    ACPI_OPERAND_OBJECT         *ReturnObject)
1231
{
1232
 
1233
    /*
1234
     * Check the reference object for the correct reference type (opcode).
1235
     * The only type of reference that can be converted to an ACPI_OBJECT is
1236
     * a reference to a named object (reference class: NAME)
1237
     */
1238
    if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
1239
    {
1240
        return (AE_OK);
1241
    }
1242
 
1243
    ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1244
        "Return type mismatch - unexpected reference object type [%s] %2.2X",
1245
        AcpiUtGetReferenceName (ReturnObject),
1246
        ReturnObject->Reference.Class));
1247
 
1248
    return (AE_AML_OPERAND_TYPE);
1249
}
1250
 
1251
 
1252
/*******************************************************************************
1253
 *
1254
 * FUNCTION:    AcpiNsGetExpectedTypes
1255
 *
1256
 * PARAMETERS:  Buffer          - Pointer to where the string is returned
1257
 *              ExpectedBtypes  - Bitmap of expected return type(s)
1258
 *
1259
 * RETURN:      Buffer is populated with type names.
1260
 *
1261
 * DESCRIPTION: Translate the expected types bitmap into a string of ascii
1262
 *              names of expected types, for use in warning messages.
1263
 *
1264
 ******************************************************************************/
1265
 
1266
static void
1267
AcpiNsGetExpectedTypes (
1268
    char                        *Buffer,
1269
    UINT32                      ExpectedBtypes)
1270
{
1271
    UINT32                      ThisRtype;
1272
    UINT32                      i;
1273
    UINT32                      j;
1274
 
1275
 
1276
    j = 1;
1277
    Buffer[0] = 0;
1278
    ThisRtype = ACPI_RTYPE_INTEGER;
1279
 
1280
    for (i = 0; i < ACPI_NUM_RTYPES; i++)
1281
    {
1282
        /* If one of the expected types, concatenate the name of this type */
1283
 
1284
        if (ExpectedBtypes & ThisRtype)
1285
        {
1286
            ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
1287
            j = 0;              /* Use name separator from now on */
1288
        }
1289
        ThisRtype <<= 1;    /* Next Rtype */
1290
    }
1291
}