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 sub-packages 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 sub-packages, 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 sub-packages. 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 sub-packages */ 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 sub-packages 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 sub-packages */ 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 sub-Packages. 300 */ 301 302 /* Examine the sub-packages */ 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 471 ApCheckPackageElements (PredefinedName, Op, 472 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 473 Package->RetInfo.ObjectType2, Package->RetInfo.Count2); 474 break; 475 476 case ACPI_PTYPE2_FIX_VAR: 477 /* 478 * Each subpackage has a fixed number of elements and an 479 * optional element 480 */ 481 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 482 if (Count < ExpectedCount) 483 { 484 ApPackageTooSmall (PredefinedName, SubPackageOp, 485 Count, ExpectedCount); 486 break; 487 } 488 489 ApCheckPackageElements (PredefinedName, Op, 490 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 491 Package->RetInfo.ObjectType2, 492 Count - Package->RetInfo.Count1); 493 break; 494 495 case ACPI_PTYPE2_FIXED: 496 497 /* Each sub-package has a fixed length */ 498 499 ExpectedCount = Package->RetInfo2.Count; 500 if (Count < ExpectedCount) 501 { 502 ApPackageTooSmall (PredefinedName, SubPackageOp, 503 Count, ExpectedCount); 504 break; 505 } 506 507 /* Check each object/type combination */ 508 509 for (j = 0; j < ExpectedCount; j++) 510 { 511 ApCheckObjectType (PredefinedName, Op, 512 Package->RetInfo2.ObjectType[j], j); 513 514 Op = Op->Asl.Next; 515 } 516 break; 517 518 case ACPI_PTYPE2_MIN: 519 520 /* Each sub-package has a variable but minimum length */ 521 522 ExpectedCount = Package->RetInfo.Count1; 523 if (Count < ExpectedCount) 524 { 525 ApPackageTooSmall (PredefinedName, SubPackageOp, 526 Count, ExpectedCount); 527 break; 528 } 529 530 /* Check the type of each sub-package element */ 531 532 ApCheckPackageElements (PredefinedName, Op, 533 Package->RetInfo.ObjectType1, Count, 0, 0); 534 break; 535 536 case ACPI_PTYPE2_COUNT: 537 /* 538 * First element is the (Integer) count of elements, including 539 * the count field (the ACPI name is NumElements) 540 */ 541 Status = ApCheckObjectType (PredefinedName, Op, 542 ACPI_RTYPE_INTEGER, 0); 543 544 /* We must have an integer count from above (otherwise, use Count) */ 545 546 if (ACPI_SUCCESS (Status)) 547 { 548 /* 549 * Make sure package is large enough for the Count and is 550 * is as large as the minimum size 551 */ 552 ExpectedCount = (UINT32) Op->Asl.Value.Integer; 553 554 if (Count < ExpectedCount) 555 { 556 ApPackageTooSmall (PredefinedName, SubPackageOp, 557 Count, ExpectedCount); 558 break; 559 } 560 else if (Count > ExpectedCount) 561 { 562 ApPackageTooLarge (PredefinedName, SubPackageOp, 563 Count, ExpectedCount); 564 } 565 566 /* Some names of this type have a minimum length */ 567 568 if (Count < Package->RetInfo.Count1) 569 { 570 ExpectedCount = Package->RetInfo.Count1; 571 ApPackageTooSmall (PredefinedName, SubPackageOp, 572 Count, ExpectedCount); 573 break; 574 } 575 576 Count = ExpectedCount; 577 } 578 579 /* Check the type of each sub-package element */ 580 581 Op = Op->Asl.Next; 582 ApCheckPackageElements (PredefinedName, Op, 583 Package->RetInfo.ObjectType1, (Count - 1), 0, 0); 584 break; 585 586 default: 587 break; 588 } 589 590 NextSubpackage: 591 SubPackageOp = SubPackageOp->Asl.Next; 592 } 593 } 594 595 596 /******************************************************************************* 597 * 598 * FUNCTION: ApPackageTooSmall 599 * 600 * PARAMETERS: PredefinedName - Name of the predefined object 601 * Op - Current parser op 602 * Count - Actual package element count 603 * ExpectedCount - Expected package element count 604 * 605 * RETURN: None 606 * 607 * DESCRIPTION: Issue error message for a package that is smaller than 608 * required. 609 * 610 ******************************************************************************/ 611 612 static void 613 ApPackageTooSmall ( 614 const char *PredefinedName, 615 ACPI_PARSE_OBJECT *Op, 616 UINT32 Count, 617 UINT32 ExpectedCount) 618 { 619 620 sprintf (MsgBuffer, "%s: length %u, required minimum is %u", 621 PredefinedName, Count, ExpectedCount); 622 623 AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer); 624 } 625 626 627 /******************************************************************************* 628 * 629 * FUNCTION: ApZeroLengthPackage 630 * 631 * PARAMETERS: PredefinedName - Name of the predefined object 632 * Op - Current parser op 633 * 634 * RETURN: None 635 * 636 * DESCRIPTION: Issue error message for a zero-length package (a package that 637 * is required to have a non-zero length). Variable length 638 * packages seem to be allowed to have zero length, however. 639 * Even if not allowed, BIOS code does it. 640 * 641 ******************************************************************************/ 642 643 static void 644 ApZeroLengthPackage ( 645 const char *PredefinedName, 646 ACPI_PARSE_OBJECT *Op) 647 { 648 649 sprintf (MsgBuffer, "%s: length is zero", PredefinedName); 650 651 AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer); 652 } 653 654 655 /******************************************************************************* 656 * 657 * FUNCTION: ApPackageTooLarge 658 * 659 * PARAMETERS: PredefinedName - Name of the predefined object 660 * Op - Current parser op 661 * Count - Actual package element count 662 * ExpectedCount - Expected package element count 663 * 664 * RETURN: None 665 * 666 * DESCRIPTION: Issue a remark for a package that is larger than expected. 667 * 668 ******************************************************************************/ 669 670 static void 671 ApPackageTooLarge ( 672 const char *PredefinedName, 673 ACPI_PARSE_OBJECT *Op, 674 UINT32 Count, 675 UINT32 ExpectedCount) 676 { 677 678 sprintf (MsgBuffer, "%s: length is %u, only %u required", 679 PredefinedName, Count, ExpectedCount); 680 681 AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer); 682 }