Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/compiler/aslprepkg.c
48371 views
1
/******************************************************************************
2
*
3
* Module Name: aslprepkg - support for ACPI predefined name package objects
4
*
5
*****************************************************************************/
6
7
/******************************************************************************
8
*
9
* 1. Copyright Notice
10
*
11
* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12
* All rights reserved.
13
*
14
* 2. License
15
*
16
* 2.1. This is your license from Intel Corp. under its intellectual property
17
* rights. You may have additional license terms from the party that provided
18
* you this software, covering your right to use that party's intellectual
19
* property rights.
20
*
21
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
* copy of the source code appearing in this file ("Covered Code") an
23
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
* base code distributed originally by Intel ("Original Intel Code") to copy,
25
* make derivatives, distribute, use and display any portion of the Covered
26
* Code in any form, with the right to sublicense such rights; and
27
*
28
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
* license (with the right to sublicense), under only those claims of Intel
30
* patents that are infringed by the Original Intel Code, to make, use, sell,
31
* offer to sell, and import the Covered Code and derivative works thereof
32
* solely to the minimum extent necessary to exercise the above copyright
33
* license, and in no event shall the patent license extend to any additions
34
* to or modifications of the Original Intel Code. No other license or right
35
* is granted directly or by implication, estoppel or otherwise;
36
*
37
* The above copyright and patent license is granted only if the following
38
* conditions are met:
39
*
40
* 3. Conditions
41
*
42
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
* Redistribution of source code of any substantial portion of the Covered
44
* Code or modification with rights to further distribute source must include
45
* the above Copyright Notice, the above License, this list of Conditions,
46
* and the following Disclaimer and Export Compliance provision. In addition,
47
* Licensee must cause all Covered Code to which Licensee contributes to
48
* contain a file documenting the changes Licensee made to create that Covered
49
* Code and the date of any change. Licensee must include in that file the
50
* documentation of any changes made by any predecessor Licensee. Licensee
51
* must include a prominent statement that the modification is derived,
52
* directly or indirectly, from Original Intel Code.
53
*
54
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
* Redistribution of source code of any substantial portion of the Covered
56
* Code or modification without rights to further distribute source must
57
* include the following Disclaimer and Export Compliance provision in the
58
* documentation and/or other materials provided with distribution. In
59
* addition, Licensee may not authorize further sublicense of source of any
60
* portion of the Covered Code, and must include terms to the effect that the
61
* license from Licensee to its licensee is limited to the intellectual
62
* property embodied in the software Licensee provides to its licensee, and
63
* not to intellectual property embodied in modifications its licensee may
64
* make.
65
*
66
* 3.3. Redistribution of Executable. Redistribution in executable form of any
67
* substantial portion of the Covered Code or modification must reproduce the
68
* above Copyright Notice, and the following Disclaimer and Export Compliance
69
* provision in the documentation and/or other materials provided with the
70
* distribution.
71
*
72
* 3.4. Intel retains all right, title, and interest in and to the Original
73
* Intel Code.
74
*
75
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
* Intel shall be used in advertising or otherwise to promote the sale, use or
77
* other dealings in products derived from or relating to the Covered Code
78
* without prior written authorization from Intel.
79
*
80
* 4. Disclaimer and Export Compliance
81
*
82
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
* PARTICULAR PURPOSE.
89
*
90
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
* LIMITED REMEDY.
98
*
99
* 4.3. Licensee shall not export, either directly or indirectly, any of this
100
* software or system incorporating such software without first obtaining any
101
* required license or other approval from the U. S. Department of Commerce or
102
* any other agency or department of the United States Government. In the
103
* event Licensee exports any such software from the United States or
104
* re-exports any such software from a foreign destination, Licensee shall
105
* ensure that the distribution and export/re-export of the software is in
106
* compliance with all laws, regulations, orders, or other restrictions of the
107
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
* any of its subsidiaries will export/re-export any technical data, process,
109
* software, or service, directly or indirectly, to any country for which the
110
* United States government or any agency thereof requires an export license,
111
* other governmental approval, or letter of assurance, without first obtaining
112
* such license, approval or letter.
113
*
114
*****************************************************************************
115
*
116
* Alternatively, you may choose to be licensed under the terms of the
117
* following license:
118
*
119
* Redistribution and use in source and binary forms, with or without
120
* modification, are permitted provided that the following conditions
121
* are met:
122
* 1. Redistributions of source code must retain the above copyright
123
* notice, this list of conditions, and the following disclaimer,
124
* without modification.
125
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
126
* substantially similar to the "NO WARRANTY" disclaimer below
127
* ("Disclaimer") and any redistribution must be conditioned upon
128
* including a substantially similar Disclaimer requirement for further
129
* binary redistribution.
130
* 3. Neither the names of the above-listed copyright holders nor the names
131
* of any contributors may be used to endorse or promote products derived
132
* from this software without specific prior written permission.
133
*
134
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
*
146
* Alternatively, you may choose to be licensed under the terms of the
147
* GNU General Public License ("GPL") version 2 as published by the Free
148
* Software Foundation.
149
*
150
*****************************************************************************/
151
152
#include <contrib/dev/acpica/compiler/aslcompiler.h>
153
#include "aslcompiler.y.h"
154
#include <contrib/dev/acpica/include/acpredef.h>
155
156
157
#define _COMPONENT ACPI_COMPILER
158
ACPI_MODULE_NAME ("aslprepkg")
159
160
161
/* Local prototypes */
162
163
static ACPI_PARSE_OBJECT *
164
ApCheckPackageElements (
165
const char *PredefinedName,
166
ACPI_PARSE_OBJECT *Op,
167
UINT8 Type1,
168
UINT32 Count1,
169
UINT8 Type2,
170
UINT32 Count2);
171
172
static void
173
ApCheckPackageList (
174
const char *PredefinedName,
175
ACPI_PARSE_OBJECT *ParentOp,
176
const ACPI_PREDEFINED_INFO *Package,
177
UINT32 StartIndex,
178
UINT32 Count);
179
180
static void
181
ApPackageTooSmall (
182
const char *PredefinedName,
183
ACPI_PARSE_OBJECT *Op,
184
UINT32 Count,
185
UINT32 ExpectedCount);
186
187
static void
188
ApZeroLengthPackage (
189
const char *PredefinedName,
190
ACPI_PARSE_OBJECT *Op);
191
192
static void
193
ApPackageTooLarge (
194
const char *PredefinedName,
195
ACPI_PARSE_OBJECT *Op,
196
UINT32 Count,
197
UINT32 ExpectedCount);
198
199
static void
200
ApCustomPackage (
201
ACPI_PARSE_OBJECT *ParentOp,
202
const ACPI_PREDEFINED_INFO *Predefined);
203
204
205
/*******************************************************************************
206
*
207
* FUNCTION: ApCheckPackage
208
*
209
* PARAMETERS: ParentOp - Parser op for the package
210
* Predefined - Pointer to package-specific info for
211
* the method
212
*
213
* RETURN: None
214
*
215
* DESCRIPTION: Top-level validation for predefined name return package
216
* objects.
217
*
218
******************************************************************************/
219
220
void
221
ApCheckPackage (
222
ACPI_PARSE_OBJECT *ParentOp,
223
const ACPI_PREDEFINED_INFO *Predefined)
224
{
225
ACPI_PARSE_OBJECT *Op;
226
const ACPI_PREDEFINED_INFO *Package;
227
ACPI_STATUS Status;
228
UINT32 ExpectedCount;
229
UINT32 Count;
230
UINT32 i;
231
232
233
/* The package info for this name is in the next table entry */
234
235
Package = Predefined + 1;
236
237
/* First child is the package length */
238
239
Op = ParentOp->Asl.Child;
240
Count = (UINT32) Op->Asl.Value.Integer;
241
242
/*
243
* Many of the variable-length top-level packages are allowed to simply
244
* have zero elements. This allows the BIOS to tell the host that even
245
* though the predefined name/method exists, the feature is not supported.
246
* Other package types require one or more elements. In any case, there
247
* is no need to continue validation.
248
*/
249
if (!Count)
250
{
251
switch (Package->RetInfo.Type)
252
{
253
case ACPI_PTYPE1_FIXED:
254
case ACPI_PTYPE1_OPTION:
255
case ACPI_PTYPE2_PKG_COUNT:
256
case ACPI_PTYPE2_REV_FIXED:
257
258
ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
259
break;
260
261
case ACPI_PTYPE1_VAR:
262
case ACPI_PTYPE2:
263
case ACPI_PTYPE2_COUNT:
264
case ACPI_PTYPE2_FIXED:
265
case ACPI_PTYPE2_MIN:
266
case ACPI_PTYPE2_FIX_VAR:
267
case ACPI_PTYPE2_VAR_VAR:
268
default:
269
270
break;
271
}
272
273
return;
274
}
275
276
/* Get the first element of the package */
277
278
Op = Op->Asl.Next;
279
280
/* Decode the package type */
281
282
switch (Package->RetInfo.Type)
283
{
284
case ACPI_PTYPE_CUSTOM:
285
286
ApCustomPackage (ParentOp, Predefined);
287
break;
288
289
case ACPI_PTYPE1_FIXED:
290
/*
291
* The package count is fixed and there are no subpackages
292
*
293
* If package is too small, exit.
294
* If package is larger than expected, issue warning but continue
295
*/
296
ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
297
if (Count < ExpectedCount)
298
{
299
goto PackageTooSmall;
300
}
301
else if (Count > ExpectedCount)
302
{
303
ApPackageTooLarge (Predefined->Info.Name, ParentOp,
304
Count, ExpectedCount);
305
}
306
307
/* Validate all elements of the package */
308
309
ApCheckPackageElements (Predefined->Info.Name, Op,
310
Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
311
Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
312
break;
313
314
case ACPI_PTYPE1_VAR:
315
/*
316
* The package count is variable, there are no subpackages,
317
* and all elements must be of the same type
318
*/
319
for (i = 0; i < Count; i++)
320
{
321
if (!Op)
322
{
323
/*
324
* If we get to this point, it means that the package length
325
* is larger than the initializer list. Stop processing the
326
* package and return because we have run out of package
327
* elements to analyze.
328
*/
329
return;
330
}
331
332
ApCheckObjectType (Predefined->Info.Name, Op,
333
Package->RetInfo.ObjectType1, i);
334
Op = Op->Asl.Next;
335
}
336
break;
337
338
case ACPI_PTYPE1_OPTION:
339
/*
340
* The package count is variable, there are no subpackages.
341
* There are a fixed number of required elements, and a variable
342
* number of optional elements.
343
*
344
* Check if package is at least as large as the minimum required
345
*/
346
ExpectedCount = Package->RetInfo3.Count;
347
if (Count < ExpectedCount)
348
{
349
goto PackageTooSmall;
350
}
351
352
/* Variable number of sub-objects */
353
354
for (i = 0; i < Count; i++)
355
{
356
if (i < Package->RetInfo3.Count)
357
{
358
/* These are the required package elements (0, 1, or 2) */
359
360
ApCheckObjectType (Predefined->Info.Name, Op,
361
Package->RetInfo3.ObjectType[i], i);
362
}
363
else
364
{
365
/* These are the optional package elements */
366
367
ApCheckObjectType (Predefined->Info.Name, Op,
368
Package->RetInfo3.TailObjectType, i);
369
}
370
371
Op = Op->Asl.Next;
372
}
373
break;
374
375
case ACPI_PTYPE2_REV_FIXED:
376
377
/* First element is the (Integer) revision */
378
379
ApCheckObjectType (Predefined->Info.Name, Op,
380
ACPI_RTYPE_INTEGER, 0);
381
382
Op = Op->Asl.Next;
383
Count--;
384
385
/* Examine the subpackages */
386
387
ApCheckPackageList (Predefined->Info.Name, Op,
388
Package, 1, Count);
389
break;
390
391
case ACPI_PTYPE2_PKG_COUNT:
392
393
/* First element is the (Integer) count of subpackages to follow */
394
395
Status = ApCheckObjectType (Predefined->Info.Name, Op,
396
ACPI_RTYPE_INTEGER, 0);
397
398
/* We must have an integer count from above (otherwise, use Count) */
399
400
if (ACPI_SUCCESS (Status))
401
{
402
/*
403
* Count cannot be larger than the parent package length, but
404
* allow it to be smaller. The >= accounts for the Integer above.
405
*/
406
ExpectedCount = (UINT32) Op->Asl.Value.Integer;
407
if (ExpectedCount >= Count)
408
{
409
goto PackageTooSmall;
410
}
411
412
Count = ExpectedCount;
413
}
414
415
Op = Op->Asl.Next;
416
417
/* Examine the subpackages */
418
419
ApCheckPackageList (Predefined->Info.Name, Op,
420
Package, 1, Count);
421
break;
422
423
case ACPI_PTYPE2_UUID_PAIR:
424
425
/* The package contains a variable list of UUID Buffer/Package pairs */
426
427
/* The length of the package must be even */
428
429
if (Count & 1)
430
{
431
sprintf (AslGbl_MsgBuffer, "%4.4s: Package length, %d, must be even.",
432
Predefined->Info.Name, Count);
433
434
AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH,
435
ParentOp->Asl.Child, AslGbl_MsgBuffer);
436
}
437
438
/* Validate the alternating types */
439
440
for (i = 0; i < Count; ++i)
441
{
442
if (i & 1)
443
{
444
ApCheckObjectType (Predefined->Info.Name, Op,
445
Package->RetInfo.ObjectType2, i);
446
}
447
else
448
{
449
ApCheckObjectType (Predefined->Info.Name, Op,
450
Package->RetInfo.ObjectType1, i);
451
}
452
453
Op = Op->Asl.Next;
454
}
455
456
break;
457
458
case ACPI_PTYPE2_VAR_VAR:
459
460
/* Check for minimum size (ints at beginning + 1 subpackage) */
461
462
ExpectedCount = Package->RetInfo4.Count1 + 1;
463
if (Count < ExpectedCount)
464
{
465
goto PackageTooSmall;
466
}
467
468
/* Check the non-package elements at beginning of main package */
469
470
for (i = 0; i < Package->RetInfo4.Count1; ++i)
471
{
472
ApCheckObjectType (Predefined->Info.Name, Op,
473
Package->RetInfo4.ObjectType1, i);
474
Op = Op->Asl.Next;
475
}
476
477
/* Examine the variable-length list of subpackages */
478
479
ApCheckPackageList (Predefined->Info.Name, Op,
480
Package, Package->RetInfo4.Count1, Count);
481
482
break;
483
484
case ACPI_PTYPE2:
485
case ACPI_PTYPE2_FIXED:
486
case ACPI_PTYPE2_MIN:
487
case ACPI_PTYPE2_COUNT:
488
case ACPI_PTYPE2_FIX_VAR:
489
/*
490
* These types all return a single Package that consists of a
491
* variable number of subpackages.
492
*/
493
494
/* Examine the subpackages */
495
496
ApCheckPackageList (Predefined->Info.Name, Op,
497
Package, 0, Count);
498
break;
499
500
default:
501
return;
502
}
503
504
return;
505
506
PackageTooSmall:
507
ApPackageTooSmall (Predefined->Info.Name, ParentOp,
508
Count, ExpectedCount);
509
}
510
511
512
/*******************************************************************************
513
*
514
* FUNCTION: ApCustomPackage
515
*
516
* PARAMETERS: ParentOp - Parse op for the package
517
* Predefined - Pointer to package-specific info for
518
* the method
519
*
520
* RETURN: None
521
*
522
* DESCRIPTION: Validate packages that don't fit into the standard model and
523
* require custom code.
524
*
525
* NOTE: Currently used for the _BIX method only. When needed for two or more
526
* methods, probably a detect/dispatch mechanism will be required.
527
*
528
******************************************************************************/
529
530
static void
531
ApCustomPackage (
532
ACPI_PARSE_OBJECT *ParentOp,
533
const ACPI_PREDEFINED_INFO *Predefined)
534
{
535
ACPI_PARSE_OBJECT *Op;
536
UINT32 Count;
537
UINT32 ExpectedCount;
538
UINT32 Version;
539
540
541
/* First child is the package length */
542
543
Op = ParentOp->Asl.Child;
544
Count = (UINT32) Op->Asl.Value.Integer;
545
546
/* Get the version number, must be Integer */
547
548
Op = Op->Asl.Next;
549
Version = (UINT32) Op->Asl.Value.Integer;
550
if (Op->Asl.ParseOpcode != PARSEOP_INTEGER)
551
{
552
AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, AslGbl_MsgBuffer);
553
return;
554
}
555
556
/* Validate count (# of elements) */
557
558
ExpectedCount = 21; /* Version 1 */
559
if (Version == 0)
560
{
561
ExpectedCount = 20; /* Version 0 */
562
}
563
564
if (Count < ExpectedCount)
565
{
566
ApPackageTooSmall (Predefined->Info.Name, ParentOp,
567
Count, ExpectedCount);
568
return;
569
}
570
else if (Count > ExpectedCount)
571
{
572
ApPackageTooLarge (Predefined->Info.Name, ParentOp,
573
Count, ExpectedCount);
574
}
575
576
/* Validate all elements of the package */
577
578
Op = ApCheckPackageElements (Predefined->Info.Name, Op,
579
ACPI_RTYPE_INTEGER, 16,
580
ACPI_RTYPE_STRING, 4);
581
582
/* Version 1 has a single trailing integer */
583
584
if (Version > 0)
585
{
586
ApCheckPackageElements (Predefined->Info.Name, Op,
587
ACPI_RTYPE_INTEGER, 1, 0, 0);
588
}
589
}
590
591
592
/*******************************************************************************
593
*
594
* FUNCTION: ApCheckPackageElements
595
*
596
* PARAMETERS: PredefinedName - Name of the predefined object
597
* Op - Parser op for the package
598
* Type1 - Object type for first group
599
* Count1 - Count for first group
600
* Type2 - Object type for second group
601
* Count2 - Count for second group
602
*
603
* RETURN: Next Op peer in the parse tree, after all specified elements
604
* have been validated. Used for multiple validations (calls
605
* to this function).
606
*
607
* DESCRIPTION: Validate all elements of a package. Works with packages that
608
* are defined to contain up to two groups of different object
609
* types.
610
*
611
******************************************************************************/
612
613
static ACPI_PARSE_OBJECT *
614
ApCheckPackageElements (
615
const char *PredefinedName,
616
ACPI_PARSE_OBJECT *Op,
617
UINT8 Type1,
618
UINT32 Count1,
619
UINT8 Type2,
620
UINT32 Count2)
621
{
622
UINT32 i;
623
624
625
/*
626
* Up to two groups of package elements are supported by the data
627
* structure. All elements in each group must be of the same type.
628
* The second group can have a count of zero.
629
*
630
* Aborts check upon a NULL package element, as this means (at compile
631
* time) that the remainder of the package elements are also NULL
632
* (This is the only way to create NULL package elements.)
633
*/
634
for (i = 0; (i < Count1) && Op; i++)
635
{
636
ApCheckObjectType (PredefinedName, Op, Type1, i);
637
Op = Op->Asl.Next;
638
}
639
640
for (i = 0; (i < Count2) && Op; i++)
641
{
642
ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
643
Op = Op->Asl.Next;
644
}
645
646
return (Op);
647
}
648
649
650
/*******************************************************************************
651
*
652
* FUNCTION: ApCheckPackageList
653
*
654
* PARAMETERS: PredefinedName - Name of the predefined object
655
* ParentOp - Parser op of the parent package
656
* Package - Package info for this predefined name
657
* StartIndex - Index in parent package where list begins
658
* ParentCount - Element count of parent package
659
*
660
* RETURN: None
661
*
662
* DESCRIPTION: Validate the individual package elements for a predefined name.
663
* Handles the cases where the predefined name is defined as a
664
* Package of Packages (subpackages). These are the types:
665
*
666
* ACPI_PTYPE2
667
* ACPI_PTYPE2_FIXED
668
* ACPI_PTYPE2_MIN
669
* ACPI_PTYPE2_COUNT
670
* ACPI_PTYPE2_FIX_VAR
671
* ACPI_PTYPE2_VAR_VAR
672
*
673
******************************************************************************/
674
675
static void
676
ApCheckPackageList (
677
const char *PredefinedName,
678
ACPI_PARSE_OBJECT *ParentOp,
679
const ACPI_PREDEFINED_INFO *Package,
680
UINT32 StartIndex,
681
UINT32 ParentCount)
682
{
683
ACPI_PARSE_OBJECT *SubPackageOp = ParentOp;
684
ACPI_PARSE_OBJECT *Op;
685
ACPI_STATUS Status;
686
UINT32 Count;
687
UINT32 ExpectedCount;
688
UINT32 i;
689
UINT32 j;
690
691
692
/*
693
* Validate each subpackage in the parent Package
694
*
695
* Note: We ignore NULL package elements on the assumption that
696
* they will be initialized by the BIOS or other ASL code.
697
*/
698
for (i = 0; (i < ParentCount) && SubPackageOp; i++)
699
{
700
/* Each object in the list must be of type Package */
701
702
Status = ApCheckObjectType (PredefinedName, SubPackageOp,
703
ACPI_RTYPE_PACKAGE, i + StartIndex);
704
if (ACPI_FAILURE (Status))
705
{
706
goto NextSubpackage;
707
}
708
709
/* Examine the different types of expected subpackages */
710
711
Op = SubPackageOp->Asl.Child;
712
713
/* First child is the package length */
714
715
Count = (UINT32) Op->Asl.Value.Integer;
716
Op = Op->Asl.Next;
717
718
/*
719
* Most subpackage must have at least one element, with
720
* only rare exceptions. (_RDI)
721
*/
722
if (!Count &&
723
(Package->RetInfo.Type != ACPI_PTYPE2_VAR_VAR))
724
{
725
ApZeroLengthPackage (PredefinedName, SubPackageOp);
726
goto NextSubpackage;
727
}
728
729
/*
730
* Decode the package type.
731
* PTYPE2 indicates that a "package of packages" is expected for
732
* this name. The various flavors of PTYPE2 indicate the number
733
* and format of the subpackages.
734
*/
735
switch (Package->RetInfo.Type)
736
{
737
case ACPI_PTYPE2:
738
case ACPI_PTYPE2_PKG_COUNT:
739
case ACPI_PTYPE2_REV_FIXED:
740
741
/* Each subpackage has a fixed number of elements */
742
743
ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
744
if (Count < ExpectedCount)
745
{
746
ApPackageTooSmall (PredefinedName, SubPackageOp,
747
Count, ExpectedCount);
748
break;
749
}
750
if (Count > ExpectedCount)
751
{
752
ApPackageTooLarge (PredefinedName, SubPackageOp,
753
Count, ExpectedCount);
754
break;
755
}
756
757
ApCheckPackageElements (PredefinedName, Op,
758
Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
759
Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
760
break;
761
762
case ACPI_PTYPE2_FIX_VAR:
763
/*
764
* Each subpackage has a fixed number of elements and an
765
* optional element
766
*/
767
ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
768
if (Count < ExpectedCount)
769
{
770
ApPackageTooSmall (PredefinedName, SubPackageOp,
771
Count, ExpectedCount);
772
break;
773
}
774
775
ApCheckPackageElements (PredefinedName, Op,
776
Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
777
Package->RetInfo.ObjectType2,
778
Count - Package->RetInfo.Count1);
779
break;
780
781
case ACPI_PTYPE2_VAR_VAR:
782
/*
783
* Must have at least the minimum number elements.
784
* A zero PkgCount means the number of elements is variable.
785
*/
786
ExpectedCount = Package->RetInfo4.PkgCount;
787
if (ExpectedCount && (Count < ExpectedCount))
788
{
789
ApPackageTooSmall (PredefinedName, SubPackageOp,
790
Count, 1);
791
break;
792
}
793
794
ApCheckPackageElements (PredefinedName, Op,
795
Package->RetInfo4.SubObjectTypes,
796
Package->RetInfo4.PkgCount,
797
0, 0);
798
break;
799
800
case ACPI_PTYPE2_FIXED:
801
802
/* Each subpackage has a fixed length */
803
804
ExpectedCount = Package->RetInfo2.Count;
805
if (Count < ExpectedCount)
806
{
807
ApPackageTooSmall (PredefinedName, SubPackageOp,
808
Count, ExpectedCount);
809
break;
810
}
811
if (Count > ExpectedCount)
812
{
813
ApPackageTooLarge (PredefinedName, SubPackageOp,
814
Count, ExpectedCount);
815
break;
816
}
817
818
/* Check each object/type combination */
819
820
for (j = 0; j < ExpectedCount; j++)
821
{
822
ApCheckObjectType (PredefinedName, Op,
823
Package->RetInfo2.ObjectType[j], j);
824
825
Op = Op->Asl.Next;
826
}
827
break;
828
829
case ACPI_PTYPE2_MIN:
830
831
/* Each subpackage has a variable but minimum length */
832
833
ExpectedCount = Package->RetInfo.Count1;
834
if (Count < ExpectedCount)
835
{
836
ApPackageTooSmall (PredefinedName, SubPackageOp,
837
Count, ExpectedCount);
838
break;
839
}
840
841
/* Check the type of each subpackage element */
842
843
ApCheckPackageElements (PredefinedName, Op,
844
Package->RetInfo.ObjectType1, Count, 0, 0);
845
break;
846
847
case ACPI_PTYPE2_COUNT:
848
/*
849
* First element is the (Integer) count of elements, including
850
* the count field (the ACPI name is NumElements)
851
*/
852
Status = ApCheckObjectType (PredefinedName, Op,
853
ACPI_RTYPE_INTEGER, 0);
854
855
/* We must have an integer count from above (otherwise, use Count) */
856
857
if (ACPI_SUCCESS (Status))
858
{
859
/*
860
* Make sure package is large enough for the Count and is
861
* is as large as the minimum size
862
*/
863
ExpectedCount = (UINT32) Op->Asl.Value.Integer;
864
865
if (Count < ExpectedCount)
866
{
867
ApPackageTooSmall (PredefinedName, SubPackageOp,
868
Count, ExpectedCount);
869
break;
870
}
871
else if (Count > ExpectedCount)
872
{
873
ApPackageTooLarge (PredefinedName, SubPackageOp,
874
Count, ExpectedCount);
875
}
876
877
/* Some names of this type have a minimum length */
878
879
if (Count < Package->RetInfo.Count1)
880
{
881
ExpectedCount = Package->RetInfo.Count1;
882
ApPackageTooSmall (PredefinedName, SubPackageOp,
883
Count, ExpectedCount);
884
break;
885
}
886
887
Count = ExpectedCount;
888
}
889
890
/* Check the type of each subpackage element */
891
892
Op = Op->Asl.Next;
893
ApCheckPackageElements (PredefinedName, Op,
894
Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
895
break;
896
897
default:
898
break;
899
}
900
901
NextSubpackage:
902
SubPackageOp = SubPackageOp->Asl.Next;
903
}
904
}
905
906
907
/*******************************************************************************
908
*
909
* FUNCTION: ApPackageTooSmall
910
*
911
* PARAMETERS: PredefinedName - Name of the predefined object
912
* Op - Current parser op
913
* Count - Actual package element count
914
* ExpectedCount - Expected package element count
915
*
916
* RETURN: None
917
*
918
* DESCRIPTION: Issue error message for a package that is smaller than
919
* required.
920
*
921
******************************************************************************/
922
923
static void
924
ApPackageTooSmall (
925
const char *PredefinedName,
926
ACPI_PARSE_OBJECT *Op,
927
UINT32 Count,
928
UINT32 ExpectedCount)
929
{
930
931
sprintf (AslGbl_MsgBuffer, "%4.4s: length %u, required minimum is %u",
932
PredefinedName, Count, ExpectedCount);
933
934
AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
935
}
936
937
938
/*******************************************************************************
939
*
940
* FUNCTION: ApZeroLengthPackage
941
*
942
* PARAMETERS: PredefinedName - Name of the predefined object
943
* Op - Current parser op
944
*
945
* RETURN: None
946
*
947
* DESCRIPTION: Issue error message for a zero-length package (a package that
948
* is required to have a non-zero length). Variable length
949
* packages seem to be allowed to have zero length, however.
950
* Even if not allowed, BIOS code does it.
951
*
952
******************************************************************************/
953
954
static void
955
ApZeroLengthPackage (
956
const char *PredefinedName,
957
ACPI_PARSE_OBJECT *Op)
958
{
959
960
sprintf (AslGbl_MsgBuffer, "%4.4s: length is zero", PredefinedName);
961
962
AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
963
}
964
965
966
/*******************************************************************************
967
*
968
* FUNCTION: ApPackageTooLarge
969
*
970
* PARAMETERS: PredefinedName - Name of the predefined object
971
* Op - Current parser op
972
* Count - Actual package element count
973
* ExpectedCount - Expected package element count
974
*
975
* RETURN: None
976
*
977
* DESCRIPTION: Issue a remark for a package that is larger than expected.
978
*
979
******************************************************************************/
980
981
static void
982
ApPackageTooLarge (
983
const char *PredefinedName,
984
ACPI_PARSE_OBJECT *Op,
985
UINT32 Count,
986
UINT32 ExpectedCount)
987
{
988
989
sprintf (AslGbl_MsgBuffer, "%4.4s: length is %u, only %u required",
990
PredefinedName, Count, ExpectedCount);
991
992
AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
993
}
994
995