1 /****************************************************************************** 2 * 3 * Module Name: aslprepkg - support for ACPI predefined name package objects 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "aslcompiler.h" 45 #include "aslcompiler.y.h" 46 #include "acpredef.h" 47 48 49 #define _COMPONENT ACPI_COMPILER 50 ACPI_MODULE_NAME ("aslprepkg") 51 52 53 /* Local prototypes */ 54 55 static void 56 ApCheckPackageElements ( 57 const char *PredefinedName, 58 ACPI_PARSE_OBJECT *Op, 59 UINT8 Type1, 60 UINT32 Count1, 61 UINT8 Type2, 62 UINT32 Count2); 63 64 static void 65 ApCheckPackageList ( 66 const char *PredefinedName, 67 ACPI_PARSE_OBJECT *ParentOp, 68 const ACPI_PREDEFINED_INFO *Package, 69 UINT32 StartIndex, 70 UINT32 Count); 71 72 static void 73 ApPackageTooSmall ( 74 const char *PredefinedName, 75 ACPI_PARSE_OBJECT *Op, 76 UINT32 Count, 77 UINT32 ExpectedCount); 78 79 static void 80 ApZeroLengthPackage ( 81 const char *PredefinedName, 82 ACPI_PARSE_OBJECT *Op); 83 84 static void 85 ApPackageTooLarge ( 86 const char *PredefinedName, 87 ACPI_PARSE_OBJECT *Op, 88 UINT32 Count, 89 UINT32 ExpectedCount); 90 91 92 /******************************************************************************* 93 * 94 * FUNCTION: ApCheckPackage 95 * 96 * PARAMETERS: ParentOp - Parser op for the package 97 * Predefined - Pointer to package-specific info for 98 * the method 99 * 100 * RETURN: None 101 * 102 * DESCRIPTION: Top-level validation for predefined name return package 103 * objects. 104 * 105 ******************************************************************************/ 106 107 void 108 ApCheckPackage ( 109 ACPI_PARSE_OBJECT *ParentOp, 110 const ACPI_PREDEFINED_INFO *Predefined) 111 { 112 ACPI_PARSE_OBJECT *Op; 113 const ACPI_PREDEFINED_INFO *Package; 114 ACPI_STATUS Status; 115 UINT32 ExpectedCount; 116 UINT32 Count; 117 UINT32 i; 118 119 120 /* The package info for this name is in the next table entry */ 121 122 Package = Predefined + 1; 123 124 /* First child is the package length */ 125 126 Op = ParentOp->Asl.Child; 127 Count = (UINT32) Op->Asl.Value.Integer; 128 129 /* 130 * Many of the variable-length top-level packages are allowed to simply 131 * have zero elements. This allows the BIOS to tell the host that even 132 * though the predefined name/method exists, the feature is not supported. 133 * Other package types require one or more elements. In any case, there 134 * is no need to continue validation. 135 */ 136 if (!Count) 137 { 138 switch (Package->RetInfo.Type) 139 { 140 case ACPI_PTYPE1_FIXED: 141 case ACPI_PTYPE1_OPTION: 142 case ACPI_PTYPE2_PKG_COUNT: 143 case ACPI_PTYPE2_REV_FIXED: 144 145 ApZeroLengthPackage (Predefined->Info.Name, ParentOp); 146 break; 147 148 case ACPI_PTYPE1_VAR: 149 case ACPI_PTYPE2: 150 case ACPI_PTYPE2_COUNT: 151 case ACPI_PTYPE2_FIXED: 152 case ACPI_PTYPE2_MIN: 153 case ACPI_PTYPE2_FIX_VAR: 154 default: 155 156 break; 157 } 158 159 return; 160 } 161 162 /* Get the first element of the package */ 163 164 Op = Op->Asl.Next; 165 166 /* Decode the package type */ 167 168 switch (Package->RetInfo.Type) 169 { 170 case ACPI_PTYPE1_FIXED: 171 /* 172 * The package count is fixed and there are no subpackages 173 * 174 * If package is too small, exit. 175 * If package is larger than expected, issue warning but continue 176 */ 177 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 178 if (Count < ExpectedCount) 179 { 180 goto PackageTooSmall; 181 } 182 else if (Count > ExpectedCount) 183 { 184 ApPackageTooLarge (Predefined->Info.Name, ParentOp, 185 Count, ExpectedCount); 186 } 187 188 /* Validate all elements of the package */ 189 190 ApCheckPackageElements (Predefined->Info.Name, Op, 191 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 192 Package->RetInfo.ObjectType2, Package->RetInfo.Count2); 193 break; 194 195 case ACPI_PTYPE1_VAR: 196 /* 197 * The package count is variable, there are no subpackages, 198 * and all elements must be of the same type 199 */ 200 for (i = 0; i < Count; i++) 201 { 202 ApCheckObjectType (Predefined->Info.Name, Op, 203 Package->RetInfo.ObjectType1, i); 204 Op = Op->Asl.Next; 205 } 206 break; 207 208 case ACPI_PTYPE1_OPTION: 209 /* 210 * The package count is variable, there are no subpackages. 211 * There are a fixed number of required elements, and a variable 212 * number of optional elements. 213 * 214 * Check if package is at least as large as the minimum required 215 */ 216 ExpectedCount = Package->RetInfo3.Count; 217 if (Count < ExpectedCount) 218 { 219 goto PackageTooSmall; 220 } 221 222 /* Variable number of sub-objects */ 223 224 for (i = 0; i < Count; i++) 225 { 226 if (i < Package->RetInfo3.Count) 227 { 228 /* These are the required package elements (0, 1, or 2) */ 229 230 ApCheckObjectType (Predefined->Info.Name, Op, 231 Package->RetInfo3.ObjectType[i], i); 232 } 233 else 234 { 235 /* These are the optional package elements */ 236 237 ApCheckObjectType (Predefined->Info.Name, Op, 238 Package->RetInfo3.TailObjectType, i); 239 } 240 Op = Op->Asl.Next; 241 } 242 break; 243 244 case ACPI_PTYPE2_REV_FIXED: 245 246 /* First element is the (Integer) revision */ 247 248 ApCheckObjectType (Predefined->Info.Name, Op, 249 ACPI_RTYPE_INTEGER, 0); 250 251 Op = Op->Asl.Next; 252 Count--; 253 254 /* Examine the subpackages */ 255 256 ApCheckPackageList (Predefined->Info.Name, Op, 257 Package, 1, Count); 258 break; 259 260 case ACPI_PTYPE2_PKG_COUNT: 261 262 /* First element is the (Integer) count of subpackages to follow */ 263 264 Status = ApCheckObjectType (Predefined->Info.Name, Op, 265 ACPI_RTYPE_INTEGER, 0); 266 267 /* We must have an integer count from above (otherwise, use Count) */ 268 269 if (ACPI_SUCCESS (Status)) 270 { 271 /* 272 * Count cannot be larger than the parent package length, but 273 * allow it to be smaller. The >= accounts for the Integer above. 274 */ 275 ExpectedCount = (UINT32) Op->Asl.Value.Integer; 276 if (ExpectedCount >= Count) 277 { 278 goto PackageTooSmall; 279 } 280 281 Count = ExpectedCount; 282 } 283 284 Op = Op->Asl.Next; 285 286 /* Examine the subpackages */ 287 288 ApCheckPackageList (Predefined->Info.Name, Op, 289 Package, 1, Count); 290 break; 291 292 case ACPI_PTYPE2: 293 case ACPI_PTYPE2_FIXED: 294 case ACPI_PTYPE2_MIN: 295 case ACPI_PTYPE2_COUNT: 296 case ACPI_PTYPE2_FIX_VAR: 297 /* 298 * These types all return a single Package that consists of a 299 * variable number of subpackages. 300 */ 301 302 /* Examine the subpackages */ 303 304 ApCheckPackageList (Predefined->Info.Name, Op, 305 Package, 0, Count); 306 break; 307 308 default: 309 return; 310 } 311 312 return; 313 314 PackageTooSmall: 315 ApPackageTooSmall (Predefined->Info.Name, ParentOp, 316 Count, ExpectedCount); 317 } 318 319 320 /******************************************************************************* 321 * 322 * FUNCTION: ApCheckPackageElements 323 * 324 * PARAMETERS: PredefinedName - Name of the predefined object 325 * Op - Parser op for the package 326 * Type1 - Object type for first group 327 * Count1 - Count for first group 328 * Type2 - Object type for second group 329 * Count2 - Count for second group 330 * 331 * RETURN: None 332 * 333 * DESCRIPTION: Validate all elements of a package. Works with packages that 334 * are defined to contain up to two groups of different object 335 * types. 336 * 337 ******************************************************************************/ 338 339 static void 340 ApCheckPackageElements ( 341 const char *PredefinedName, 342 ACPI_PARSE_OBJECT *Op, 343 UINT8 Type1, 344 UINT32 Count1, 345 UINT8 Type2, 346 UINT32 Count2) 347 { 348 UINT32 i; 349 350 351 /* 352 * Up to two groups of package elements are supported by the data 353 * structure. All elements in each group must be of the same type. 354 * The second group can have a count of zero. 355 * 356 * Aborts check upon a NULL package element, as this means (at compile 357 * time) that the remainder of the package elements are also NULL 358 * (This is the only way to create NULL package elements.) 359 */ 360 for (i = 0; (i < Count1) && Op; i++) 361 { 362 ApCheckObjectType (PredefinedName, Op, Type1, i); 363 Op = Op->Asl.Next; 364 } 365 366 for (i = 0; (i < Count2) && Op; i++) 367 { 368 ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1)); 369 Op = Op->Asl.Next; 370 } 371 } 372 373 374 /******************************************************************************* 375 * 376 * FUNCTION: ApCheckPackageList 377 * 378 * PARAMETERS: PredefinedName - Name of the predefined object 379 * ParentOp - Parser op of the parent package 380 * Package - Package info for this predefined name 381 * StartIndex - Index in parent package where list begins 382 * ParentCount - Element count of parent package 383 * 384 * RETURN: None 385 * 386 * DESCRIPTION: Validate the individual package elements for a predefined name. 387 * Handles the cases where the predefined name is defined as a 388 * Package of Packages (subpackages). These are the types: 389 * 390 * ACPI_PTYPE2 391 * ACPI_PTYPE2_FIXED 392 * ACPI_PTYPE2_MIN 393 * ACPI_PTYPE2_COUNT 394 * ACPI_PTYPE2_FIX_VAR 395 * 396 ******************************************************************************/ 397 398 static void 399 ApCheckPackageList ( 400 const char *PredefinedName, 401 ACPI_PARSE_OBJECT *ParentOp, 402 const ACPI_PREDEFINED_INFO *Package, 403 UINT32 StartIndex, 404 UINT32 ParentCount) 405 { 406 ACPI_PARSE_OBJECT *SubPackageOp = ParentOp; 407 ACPI_PARSE_OBJECT *Op; 408 ACPI_STATUS Status; 409 UINT32 Count; 410 UINT32 ExpectedCount; 411 UINT32 i; 412 UINT32 j; 413 414 415 /* 416 * Validate each subpackage in the parent Package 417 * 418 * Note: We ignore NULL package elements on the assumption that 419 * they will be initialized by the BIOS or other ASL code. 420 */ 421 for (i = 0; (i < ParentCount) && SubPackageOp; i++) 422 { 423 /* Each object in the list must be of type Package */ 424 425 Status = ApCheckObjectType (PredefinedName, SubPackageOp, 426 ACPI_RTYPE_PACKAGE, i + StartIndex); 427 if (ACPI_FAILURE (Status)) 428 { 429 goto NextSubpackage; 430 } 431 432 /* Examine the different types of expected subpackages */ 433 434 Op = SubPackageOp->Asl.Child; 435 436 /* First child is the package length */ 437 438 Count = (UINT32) Op->Asl.Value.Integer; 439 Op = Op->Asl.Next; 440 441 /* The subpackage must have at least one element */ 442 443 if (!Count) 444 { 445 ApZeroLengthPackage (PredefinedName, SubPackageOp); 446 goto NextSubpackage; 447 } 448 449 /* 450 * Decode the package type. 451 * PTYPE2 indicates that a "package of packages" is expected for 452 * this name. The various flavors of PTYPE2 indicate the number 453 * and format of the subpackages. 454 */ 455 switch (Package->RetInfo.Type) 456 { 457 case ACPI_PTYPE2: 458 case ACPI_PTYPE2_PKG_COUNT: 459 case ACPI_PTYPE2_REV_FIXED: 460 461 /* Each subpackage has a fixed number of elements */ 462 463 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 464 if (Count < ExpectedCount) 465 { 466 ApPackageTooSmall (PredefinedName, SubPackageOp, 467 Count, ExpectedCount); 468 break; 469 } 470 if (Count > ExpectedCount) 471 { 472 ApPackageTooLarge (PredefinedName, SubPackageOp, 473 Count, ExpectedCount); 474 break; 475 } 476 477 ApCheckPackageElements (PredefinedName, Op, 478 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 479 Package->RetInfo.ObjectType2, Package->RetInfo.Count2); 480 break; 481 482 case ACPI_PTYPE2_FIX_VAR: 483 /* 484 * Each subpackage has a fixed number of elements and an 485 * optional element 486 */ 487 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 488 if (Count < ExpectedCount) 489 { 490 ApPackageTooSmall (PredefinedName, SubPackageOp, 491 Count, ExpectedCount); 492 break; 493 } 494 495 ApCheckPackageElements (PredefinedName, Op, 496 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 497 Package->RetInfo.ObjectType2, 498 Count - Package->RetInfo.Count1); 499 break; 500 501 case ACPI_PTYPE2_FIXED: 502 503 /* Each subpackage has a fixed length */ 504 505 ExpectedCount = Package->RetInfo2.Count; 506 if (Count < ExpectedCount) 507 { 508 ApPackageTooSmall (PredefinedName, SubPackageOp, 509 Count, ExpectedCount); 510 break; 511 } 512 if (Count > ExpectedCount) 513 { 514 ApPackageTooLarge (PredefinedName, SubPackageOp, 515 Count, ExpectedCount); 516 break; 517 } 518 519 /* Check each object/type combination */ 520 521 for (j = 0; j < ExpectedCount; j++) 522 { 523 ApCheckObjectType (PredefinedName, Op, 524 Package->RetInfo2.ObjectType[j], j); 525 526 Op = Op->Asl.Next; 527 } 528 break; 529 530 case ACPI_PTYPE2_MIN: 531 532 /* Each subpackage has a variable but minimum length */ 533 534 ExpectedCount = Package->RetInfo.Count1; 535 if (Count < ExpectedCount) 536 { 537 ApPackageTooSmall (PredefinedName, SubPackageOp, 538 Count, ExpectedCount); 539 break; 540 } 541 542 /* Check the type of each subpackage element */ 543 544 ApCheckPackageElements (PredefinedName, Op, 545 Package->RetInfo.ObjectType1, Count, 0, 0); 546 break; 547 548 case ACPI_PTYPE2_COUNT: 549 /* 550 * First element is the (Integer) count of elements, including 551 * the count field (the ACPI name is NumElements) 552 */ 553 Status = ApCheckObjectType (PredefinedName, Op, 554 ACPI_RTYPE_INTEGER, 0); 555 556 /* We must have an integer count from above (otherwise, use Count) */ 557 558 if (ACPI_SUCCESS (Status)) 559 { 560 /* 561 * Make sure package is large enough for the Count and is 562 * is as large as the minimum size 563 */ 564 ExpectedCount = (UINT32) Op->Asl.Value.Integer; 565 566 if (Count < ExpectedCount) 567 { 568 ApPackageTooSmall (PredefinedName, SubPackageOp, 569 Count, ExpectedCount); 570 break; 571 } 572 else if (Count > ExpectedCount) 573 { 574 ApPackageTooLarge (PredefinedName, SubPackageOp, 575 Count, ExpectedCount); 576 } 577 578 /* Some names of this type have a minimum length */ 579 580 if (Count < Package->RetInfo.Count1) 581 { 582 ExpectedCount = Package->RetInfo.Count1; 583 ApPackageTooSmall (PredefinedName, SubPackageOp, 584 Count, ExpectedCount); 585 break; 586 } 587 588 Count = ExpectedCount; 589 } 590 591 /* Check the type of each subpackage element */ 592 593 Op = Op->Asl.Next; 594 ApCheckPackageElements (PredefinedName, Op, 595 Package->RetInfo.ObjectType1, (Count - 1), 0, 0); 596 break; 597 598 default: 599 break; 600 } 601 602 NextSubpackage: 603 SubPackageOp = SubPackageOp->Asl.Next; 604 } 605 } 606 607 608 /******************************************************************************* 609 * 610 * FUNCTION: ApPackageTooSmall 611 * 612 * PARAMETERS: PredefinedName - Name of the predefined object 613 * Op - Current parser op 614 * Count - Actual package element count 615 * ExpectedCount - Expected package element count 616 * 617 * RETURN: None 618 * 619 * DESCRIPTION: Issue error message for a package that is smaller than 620 * required. 621 * 622 ******************************************************************************/ 623 624 static void 625 ApPackageTooSmall ( 626 const char *PredefinedName, 627 ACPI_PARSE_OBJECT *Op, 628 UINT32 Count, 629 UINT32 ExpectedCount) 630 { 631 632 sprintf (MsgBuffer, "%s: length %u, required minimum is %u", 633 PredefinedName, Count, ExpectedCount); 634 635 AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer); 636 } 637 638 639 /******************************************************************************* 640 * 641 * FUNCTION: ApZeroLengthPackage 642 * 643 * PARAMETERS: PredefinedName - Name of the predefined object 644 * Op - Current parser op 645 * 646 * RETURN: None 647 * 648 * DESCRIPTION: Issue error message for a zero-length package (a package that 649 * is required to have a non-zero length). Variable length 650 * packages seem to be allowed to have zero length, however. 651 * Even if not allowed, BIOS code does it. 652 * 653 ******************************************************************************/ 654 655 static void 656 ApZeroLengthPackage ( 657 const char *PredefinedName, 658 ACPI_PARSE_OBJECT *Op) 659 { 660 661 sprintf (MsgBuffer, "%s: length is zero", PredefinedName); 662 663 AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer); 664 } 665 666 667 /******************************************************************************* 668 * 669 * FUNCTION: ApPackageTooLarge 670 * 671 * PARAMETERS: PredefinedName - Name of the predefined object 672 * Op - Current parser op 673 * Count - Actual package element count 674 * ExpectedCount - Expected package element count 675 * 676 * RETURN: None 677 * 678 * DESCRIPTION: Issue a remark for a package that is larger than expected. 679 * 680 ******************************************************************************/ 681 682 static void 683 ApPackageTooLarge ( 684 const char *PredefinedName, 685 ACPI_PARSE_OBJECT *Op, 686 UINT32 Count, 687 UINT32 ExpectedCount) 688 { 689 690 sprintf (MsgBuffer, "%s: length is %u, only %u required", 691 PredefinedName, Count, ExpectedCount); 692 693 AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer); 694 } 695