1 /****************************************************************************** 2 * 3 * Module Name: aslprepkg - support for ACPI predefined name package objects 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 <contrib/dev/acpica/compiler/aslcompiler.h> 45 #include "aslcompiler.y.h" 46 #include <contrib/dev/acpica/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 method 98 * 99 * RETURN: None 100 * 101 * DESCRIPTION: Top-level validation for predefined name return package 102 * objects. 103 * 104 ******************************************************************************/ 105 106 void 107 ApCheckPackage ( 108 ACPI_PARSE_OBJECT *ParentOp, 109 const ACPI_PREDEFINED_INFO *Predefined) 110 { 111 ACPI_PARSE_OBJECT *Op; 112 const ACPI_PREDEFINED_INFO *Package; 113 ACPI_STATUS Status; 114 UINT32 ExpectedCount; 115 UINT32 Count; 116 UINT32 i; 117 118 119 /* The package info for this name is in the next table entry */ 120 121 Package = Predefined + 1; 122 123 /* First child is the package length */ 124 125 Op = ParentOp->Asl.Child; 126 Count = (UINT32) Op->Asl.Value.Integer; 127 128 /* 129 * Many of the variable-length top-level packages are allowed to simply 130 * have zero elements. This allows the BIOS to tell the host that even 131 * though the predefined name/method exists, the feature is not supported. 132 * Other package types require one or more elements. In any case, there 133 * is no need to continue validation. 134 */ 135 if (!Count) 136 { 137 switch (Package->RetInfo.Type) 138 { 139 case ACPI_PTYPE1_FIXED: 140 case ACPI_PTYPE1_OPTION: 141 case ACPI_PTYPE2_PKG_COUNT: 142 case ACPI_PTYPE2_REV_FIXED: 143 144 ApZeroLengthPackage (Predefined->Info.Name, ParentOp); 145 break; 146 147 case ACPI_PTYPE1_VAR: 148 case ACPI_PTYPE2: 149 case ACPI_PTYPE2_COUNT: 150 case ACPI_PTYPE2_FIXED: 151 case ACPI_PTYPE2_MIN: 152 case ACPI_PTYPE2_FIX_VAR: 153 default: 154 155 break; 156 } 157 158 return; 159 } 160 161 /* Get the first element of the package */ 162 163 Op = Op->Asl.Next; 164 165 /* Decode the package type */ 166 167 switch (Package->RetInfo.Type) 168 { 169 case ACPI_PTYPE1_FIXED: 170 /* 171 * The package count is fixed and there are no sub-packages 172 * 173 * If package is too small, exit. 174 * If package is larger than expected, issue warning but continue 175 */ 176 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 177 if (Count < ExpectedCount) 178 { 179 goto PackageTooSmall; 180 } 181 else if (Count > ExpectedCount) 182 { 183 ApPackageTooLarge (Predefined->Info.Name, ParentOp, 184 Count, ExpectedCount); 185 } 186 187 /* Validate all elements of the package */ 188 189 ApCheckPackageElements (Predefined->Info.Name, Op, 190 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 191 Package->RetInfo.ObjectType2, Package->RetInfo.Count2); 192 break; 193 194 case ACPI_PTYPE1_VAR: 195 /* 196 * The package count is variable, there are no sub-packages, and all 197 * elements must be of the same type 198 */ 199 for (i = 0; i < Count; i++) 200 { 201 ApCheckObjectType (Predefined->Info.Name, Op, 202 Package->RetInfo.ObjectType1, i); 203 Op = Op->Asl.Next; 204 } 205 break; 206 207 case ACPI_PTYPE1_OPTION: 208 /* 209 * The package count is variable, there are no sub-packages. There are 210 * a fixed number of required elements, and a variable number of 211 * optional elements. 212 * 213 * Check if package is at least as large as the minimum required 214 */ 215 ExpectedCount = Package->RetInfo3.Count; 216 if (Count < ExpectedCount) 217 { 218 goto PackageTooSmall; 219 } 220 221 /* Variable number of sub-objects */ 222 223 for (i = 0; i < Count; i++) 224 { 225 if (i < Package->RetInfo3.Count) 226 { 227 /* These are the required package elements (0, 1, or 2) */ 228 229 ApCheckObjectType (Predefined->Info.Name, Op, 230 Package->RetInfo3.ObjectType[i], i); 231 } 232 else 233 { 234 /* These are the optional package elements */ 235 236 ApCheckObjectType (Predefined->Info.Name, Op, 237 Package->RetInfo3.TailObjectType, i); 238 } 239 Op = Op->Asl.Next; 240 } 241 break; 242 243 case ACPI_PTYPE2_REV_FIXED: 244 245 /* First element is the (Integer) revision */ 246 247 ApCheckObjectType (Predefined->Info.Name, Op, 248 ACPI_RTYPE_INTEGER, 0); 249 250 Op = Op->Asl.Next; 251 Count--; 252 253 /* Examine the sub-packages */ 254 255 ApCheckPackageList (Predefined->Info.Name, Op, 256 Package, 1, Count); 257 break; 258 259 case ACPI_PTYPE2_PKG_COUNT: 260 261 /* First element is the (Integer) count of sub-packages to follow */ 262 263 Status = ApCheckObjectType (Predefined->Info.Name, Op, 264 ACPI_RTYPE_INTEGER, 0); 265 266 /* We must have an integer count from above (otherwise, use Count) */ 267 268 if (ACPI_SUCCESS (Status)) 269 { 270 /* 271 * Count cannot be larger than the parent package length, but allow it 272 * to be smaller. The >= accounts for the Integer above. 273 */ 274 ExpectedCount = (UINT32) Op->Asl.Value.Integer; 275 if (ExpectedCount >= Count) 276 { 277 goto PackageTooSmall; 278 } 279 280 Count = ExpectedCount; 281 } 282 283 Op = Op->Asl.Next; 284 285 /* Examine the sub-packages */ 286 287 ApCheckPackageList (Predefined->Info.Name, Op, 288 Package, 1, Count); 289 break; 290 291 case ACPI_PTYPE2: 292 case ACPI_PTYPE2_FIXED: 293 case ACPI_PTYPE2_MIN: 294 case ACPI_PTYPE2_COUNT: 295 case ACPI_PTYPE2_FIX_VAR: 296 /* 297 * These types all return a single Package that consists of a 298 * variable number of sub-Packages. 299 */ 300 301 /* Examine the sub-packages */ 302 303 ApCheckPackageList (Predefined->Info.Name, Op, 304 Package, 0, Count); 305 break; 306 307 default: 308 return; 309 } 310 311 return; 312 313 PackageTooSmall: 314 ApPackageTooSmall (Predefined->Info.Name, ParentOp, 315 Count, ExpectedCount); 316 } 317 318 319 /******************************************************************************* 320 * 321 * FUNCTION: ApCheckPackageElements 322 * 323 * PARAMETERS: PredefinedName - Pointer to validation data structure 324 * Op - Parser op for the package 325 * Type1 - Object type for first group 326 * Count1 - Count for first group 327 * Type2 - Object type for second group 328 * Count2 - Count for second group 329 * 330 * RETURN: None 331 * 332 * DESCRIPTION: Validate all elements of a package. Works with packages that 333 * are defined to contain up to two groups of different object 334 * types. 335 * 336 ******************************************************************************/ 337 338 static void 339 ApCheckPackageElements ( 340 const char *PredefinedName, 341 ACPI_PARSE_OBJECT *Op, 342 UINT8 Type1, 343 UINT32 Count1, 344 UINT8 Type2, 345 UINT32 Count2) 346 { 347 UINT32 i; 348 349 350 /* 351 * Up to two groups of package elements are supported by the data 352 * structure. All elements in each group must be of the same type. 353 * The second group can have a count of zero. 354 * 355 * Aborts check upon a NULL package element, as this means (at compile 356 * time) that the remainder of the package elements are also NULL 357 * (This is the only way to create NULL package elements.) 358 */ 359 for (i = 0; (i < Count1) && Op; i++) 360 { 361 ApCheckObjectType (PredefinedName, Op, Type1, i); 362 Op = Op->Asl.Next; 363 } 364 365 for (i = 0; (i < Count2) && Op; i++) 366 { 367 ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1)); 368 Op = Op->Asl.Next; 369 } 370 } 371 372 373 /******************************************************************************* 374 * 375 * FUNCTION: ApCheckPackageList 376 * 377 * PARAMETERS: PredefinedName - Name of the predefined object 378 * ParentOp - Parser op of the parent package 379 * Package - Package info for this predefined name 380 * StartIndex - Index in parent package where list begins 381 * ParentCount - Element count of parent package 382 * 383 * RETURN: None 384 * 385 * DESCRIPTION: Validate the individual package elements for a predefined name. 386 * Handles the cases where the predefined name is defined as a 387 * Package of Packages (subpackages). These are the types: 388 * 389 * ACPI_PTYPE2 390 * ACPI_PTYPE2_FIXED 391 * ACPI_PTYPE2_MIN 392 * ACPI_PTYPE2_COUNT 393 * ACPI_PTYPE2_FIX_VAR 394 * 395 ******************************************************************************/ 396 397 static void 398 ApCheckPackageList ( 399 const char *PredefinedName, 400 ACPI_PARSE_OBJECT *ParentOp, 401 const ACPI_PREDEFINED_INFO *Package, 402 UINT32 StartIndex, 403 UINT32 ParentCount) 404 { 405 ACPI_PARSE_OBJECT *SubPackageOp = ParentOp; 406 ACPI_PARSE_OBJECT *Op; 407 ACPI_STATUS Status; 408 UINT32 Count; 409 UINT32 ExpectedCount; 410 UINT32 i; 411 UINT32 j; 412 413 414 /* 415 * Validate each subpackage in the parent Package 416 * 417 * Note: We ignore NULL package elements on the assumption that 418 * they will be initialized by the BIOS or other ASL code. 419 */ 420 for (i = 0; (i < ParentCount) && SubPackageOp; i++) 421 { 422 /* Each object in the list must be of type Package */ 423 424 Status = ApCheckObjectType (PredefinedName, SubPackageOp, 425 ACPI_RTYPE_PACKAGE, i + StartIndex); 426 if (ACPI_FAILURE (Status)) 427 { 428 goto NextSubpackage; 429 } 430 431 /* Examine the different types of expected subpackages */ 432 433 Op = SubPackageOp->Asl.Child; 434 435 /* First child is the package length */ 436 437 Count = (UINT32) Op->Asl.Value.Integer; 438 Op = Op->Asl.Next; 439 440 /* The subpackage must have at least one element */ 441 442 if (!Count) 443 { 444 ApZeroLengthPackage (PredefinedName, SubPackageOp); 445 goto NextSubpackage; 446 } 447 448 /* 449 * Decode the package type. 450 * PTYPE2 indicates that a "package of packages" is expected for 451 * this name. The various flavors of PTYPE2 indicate the number 452 * and format of the subpackages. 453 */ 454 switch (Package->RetInfo.Type) 455 { 456 case ACPI_PTYPE2: 457 case ACPI_PTYPE2_PKG_COUNT: 458 case ACPI_PTYPE2_REV_FIXED: 459 460 /* Each subpackage has a fixed number of elements */ 461 462 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 463 if (Count < ExpectedCount) 464 { 465 ApPackageTooSmall (PredefinedName, SubPackageOp, 466 Count, ExpectedCount); 467 break; 468 } 469 470 ApCheckPackageElements (PredefinedName, Op, 471 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 472 Package->RetInfo.ObjectType2, Package->RetInfo.Count2); 473 break; 474 475 case ACPI_PTYPE2_FIX_VAR: 476 /* 477 * Each subpackage has a fixed number of elements and an 478 * optional element 479 */ 480 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 481 if (Count < ExpectedCount) 482 { 483 ApPackageTooSmall (PredefinedName, SubPackageOp, 484 Count, ExpectedCount); 485 break; 486 } 487 488 ApCheckPackageElements (PredefinedName, Op, 489 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 490 Package->RetInfo.ObjectType2, 491 Count - Package->RetInfo.Count1); 492 break; 493 494 case ACPI_PTYPE2_FIXED: 495 496 /* Each sub-package has a fixed length */ 497 498 ExpectedCount = Package->RetInfo2.Count; 499 if (Count < ExpectedCount) 500 { 501 ApPackageTooSmall (PredefinedName, SubPackageOp, 502 Count, ExpectedCount); 503 break; 504 } 505 506 /* Check each object/type combination */ 507 508 for (j = 0; j < ExpectedCount; j++) 509 { 510 ApCheckObjectType (PredefinedName, Op, 511 Package->RetInfo2.ObjectType[j], j); 512 513 Op = Op->Asl.Next; 514 } 515 break; 516 517 case ACPI_PTYPE2_MIN: 518 519 /* Each sub-package has a variable but minimum length */ 520 521 ExpectedCount = Package->RetInfo.Count1; 522 if (Count < ExpectedCount) 523 { 524 ApPackageTooSmall (PredefinedName, SubPackageOp, 525 Count, ExpectedCount); 526 break; 527 } 528 529 /* Check the type of each sub-package element */ 530 531 ApCheckPackageElements (PredefinedName, Op, 532 Package->RetInfo.ObjectType1, Count, 0, 0); 533 break; 534 535 case ACPI_PTYPE2_COUNT: 536 /* 537 * First element is the (Integer) count of elements, including 538 * the count field (the ACPI name is NumElements) 539 */ 540 Status = ApCheckObjectType (PredefinedName, Op, 541 ACPI_RTYPE_INTEGER, 0); 542 543 /* We must have an integer count from above (otherwise, use Count) */ 544 545 if (ACPI_SUCCESS (Status)) 546 { 547 /* 548 * Make sure package is large enough for the Count and is 549 * is as large as the minimum size 550 */ 551 ExpectedCount = (UINT32) Op->Asl.Value.Integer; 552 553 if (Count < ExpectedCount) 554 { 555 ApPackageTooSmall (PredefinedName, SubPackageOp, 556 Count, ExpectedCount); 557 break; 558 } 559 else if (Count > ExpectedCount) 560 { 561 ApPackageTooLarge (PredefinedName, SubPackageOp, 562 Count, ExpectedCount); 563 } 564 565 /* Some names of this type have a minimum length */ 566 567 if (Count < Package->RetInfo.Count1) 568 { 569 ExpectedCount = Package->RetInfo.Count1; 570 ApPackageTooSmall (PredefinedName, SubPackageOp, 571 Count, ExpectedCount); 572 break; 573 } 574 575 Count = ExpectedCount; 576 } 577 578 /* Check the type of each sub-package element */ 579 580 Op = Op->Asl.Next; 581 ApCheckPackageElements (PredefinedName, Op, 582 Package->RetInfo.ObjectType1, (Count - 1), 0, 0); 583 break; 584 585 default: 586 break; 587 } 588 589 NextSubpackage: 590 SubPackageOp = SubPackageOp->Asl.Next; 591 } 592 } 593 594 595 /******************************************************************************* 596 * 597 * FUNCTION: ApPackageTooSmall 598 * 599 * PARAMETERS: PredefinedName - Name of the predefined object 600 * Op - Current parser op 601 * Count - Actual package element count 602 * ExpectedCount - Expected package element count 603 * 604 * RETURN: None 605 * 606 * DESCRIPTION: Issue error message for a package that is smaller than 607 * required. 608 * 609 ******************************************************************************/ 610 611 static void 612 ApPackageTooSmall ( 613 const char *PredefinedName, 614 ACPI_PARSE_OBJECT *Op, 615 UINT32 Count, 616 UINT32 ExpectedCount) 617 { 618 619 sprintf (MsgBuffer, "%s: length %u, required minimum is %u", 620 PredefinedName, Count, ExpectedCount); 621 622 AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer); 623 } 624 625 626 /******************************************************************************* 627 * 628 * FUNCTION: ApZeroLengthPackage 629 * 630 * PARAMETERS: PredefinedName - Name of the predefined object 631 * Op - Current parser op 632 * 633 * RETURN: None 634 * 635 * DESCRIPTION: Issue error message for a zero-length package (a package that 636 * is required to have a non-zero length). Variable length 637 * packages seem to be allowed to have zero length, however. 638 * Even if not allowed, BIOS code does it. 639 * 640 ******************************************************************************/ 641 642 static void 643 ApZeroLengthPackage ( 644 const char *PredefinedName, 645 ACPI_PARSE_OBJECT *Op) 646 { 647 648 sprintf (MsgBuffer, "%s: length is zero", PredefinedName); 649 650 AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer); 651 } 652 653 654 /******************************************************************************* 655 * 656 * FUNCTION: ApPackageTooLarge 657 * 658 * PARAMETERS: PredefinedName - Name of the predefined object 659 * Op - Current parser op 660 * Count - Actual package element count 661 * ExpectedCount - Expected package element count 662 * 663 * RETURN: None 664 * 665 * DESCRIPTION: Issue a remark for a package that is larger than expected. 666 * 667 ******************************************************************************/ 668 669 static void 670 ApPackageTooLarge ( 671 const char *PredefinedName, 672 ACPI_PARSE_OBJECT *Op, 673 UINT32 Count, 674 UINT32 ExpectedCount) 675 { 676 677 sprintf (MsgBuffer, "%s: length is %u, only %u required", 678 PredefinedName, Count, ExpectedCount); 679 680 AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer); 681 } 682