1 2 /****************************************************************************** 3 * 4 * Module Name: asllength - Tree walk to determine package and opcode lengths 5 * $Revision: 1.37 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118 119 #include <contrib/dev/acpica/compiler/aslcompiler.h> 120 #include "aslcompiler.y.h" 121 #include <contrib/dev/acpica/amlcode.h> 122 123 124 #define _COMPONENT ACPI_COMPILER 125 ACPI_MODULE_NAME ("asllength") 126 127 /* Local prototypes */ 128 129 static UINT8 130 CgGetPackageLenByteCount ( 131 ACPI_PARSE_OBJECT *Op, 132 UINT32 PackageLength); 133 134 static void 135 CgGenerateAmlOpcodeLength ( 136 ACPI_PARSE_OBJECT *Op); 137 138 139 #ifdef ACPI_OBSOLETE_FUNCTIONS 140 void 141 LnAdjustLengthToRoot ( 142 ACPI_PARSE_OBJECT *Op, 143 UINT32 LengthDelta); 144 #endif 145 146 147 /******************************************************************************* 148 * 149 * FUNCTION: LnInitLengthsWalk 150 * 151 * PARAMETERS: ASL_WALK_CALLBACK 152 * 153 * RETURN: Status 154 * 155 * DESCRIPTION: Walk callback to initialize (and re-initialize) the node 156 * subtree length(s) to zero. The Subtree lengths are bubbled 157 * up to the root node in order to get a total AML length. 158 * 159 ******************************************************************************/ 160 161 ACPI_STATUS 162 LnInitLengthsWalk ( 163 ACPI_PARSE_OBJECT *Op, 164 UINT32 Level, 165 void *Context) 166 { 167 168 Op->Asl.AmlSubtreeLength = 0; 169 return (AE_OK); 170 } 171 172 173 /******************************************************************************* 174 * 175 * FUNCTION: LnPackageLengthWalk 176 * 177 * PARAMETERS: ASL_WALK_CALLBACK 178 * 179 * RETURN: Status 180 * 181 * DESCRIPTION: Walk callback to calculate the total AML length. 182 * 1) Calculate the AML lengths (opcode, package length, etc.) for 183 * THIS node. 184 * 2) Bubbble up all of these lengths to the parent node by summing 185 * them all into the parent subtree length. 186 * 187 * Note: The SubtreeLength represents the total AML length of all child nodes 188 * in all subtrees under a given node. Therefore, once this walk is 189 * complete, the Root Node subtree length is the AML length of the entire 190 * tree (and thus, the entire ACPI table) 191 * 192 ******************************************************************************/ 193 194 ACPI_STATUS 195 LnPackageLengthWalk ( 196 ACPI_PARSE_OBJECT *Op, 197 UINT32 Level, 198 void *Context) 199 { 200 201 /* Generate the AML lengths for this node */ 202 203 CgGenerateAmlLengths (Op); 204 205 /* Bubble up all lengths (this node and all below it) to the parent */ 206 207 if ((Op->Asl.Parent) && 208 (Op->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 209 { 210 Op->Asl.Parent->Asl.AmlSubtreeLength += (Op->Asl.AmlLength + 211 Op->Asl.AmlOpcodeLength + 212 Op->Asl.AmlPkgLenBytes + 213 Op->Asl.AmlSubtreeLength); 214 } 215 return (AE_OK); 216 } 217 218 219 /******************************************************************************* 220 * 221 * FUNCTION: CgGetPackageLenByteCount 222 * 223 * PARAMETERS: Op - Parse node 224 * PackageLength - Length to be encoded 225 * 226 * RETURN: Required length of the package length encoding 227 * 228 * DESCRIPTION: Calculate the number of bytes required to encode the given 229 * package length. 230 * 231 ******************************************************************************/ 232 233 static UINT8 234 CgGetPackageLenByteCount ( 235 ACPI_PARSE_OBJECT *Op, 236 UINT32 PackageLength) 237 { 238 239 /* 240 * Determine the number of bytes required to encode the package length 241 * Note: the package length includes the number of bytes used to encode 242 * the package length, so we must account for this also. 243 */ 244 if (PackageLength <= (0x0000003F - 1)) 245 { 246 return (1); 247 } 248 else if (PackageLength <= (0x00000FFF - 2)) 249 { 250 return (2); 251 } 252 else if (PackageLength <= (0x000FFFFF - 3)) 253 { 254 return (3); 255 } 256 else if (PackageLength <= (0x0FFFFFFF - 4)) 257 { 258 return (4); 259 } 260 else 261 { 262 /* Fatal error - the package length is too large to encode */ 263 264 AslError (ASL_ERROR, ASL_MSG_ENCODING_LENGTH, Op, NULL); 265 } 266 267 return (0); 268 } 269 270 271 /******************************************************************************* 272 * 273 * FUNCTION: CgGenerateAmlOpcodeLength 274 * 275 * PARAMETERS: Op - Parse node whose AML opcode lengths will be 276 * calculated 277 * 278 * RETURN: None. 279 * 280 * DESCRIPTION: Calculate the AmlOpcodeLength, AmlPkgLenBytes, and AmlLength 281 * fields for this node. 282 * 283 ******************************************************************************/ 284 285 static void 286 CgGenerateAmlOpcodeLength ( 287 ACPI_PARSE_OBJECT *Op) 288 { 289 290 /* Check for two-byte opcode */ 291 292 if (Op->Asl.AmlOpcode > 0x00FF) 293 { 294 Op->Asl.AmlOpcodeLength = 2; 295 } 296 else 297 { 298 Op->Asl.AmlOpcodeLength = 1; 299 } 300 301 /* Does this opcode have an associated "PackageLength" field? */ 302 303 Op->Asl.AmlPkgLenBytes = 0; 304 if (Op->Asl.CompileFlags & NODE_AML_PACKAGE) 305 { 306 Op->Asl.AmlPkgLenBytes = CgGetPackageLenByteCount ( 307 Op, Op->Asl.AmlSubtreeLength); 308 } 309 310 /* Data opcode lengths are easy */ 311 312 switch (Op->Asl.AmlOpcode) 313 { 314 case AML_BYTE_OP: 315 316 Op->Asl.AmlLength = 1; 317 break; 318 319 case AML_WORD_OP: 320 321 Op->Asl.AmlLength = 2; 322 break; 323 324 case AML_DWORD_OP: 325 326 Op->Asl.AmlLength = 4; 327 break; 328 329 case AML_QWORD_OP: 330 331 Op->Asl.AmlLength = 8; 332 break; 333 334 default: 335 /* All data opcodes must be above */ 336 break; 337 } 338 } 339 340 341 /******************************************************************************* 342 * 343 * FUNCTION: CgGenerateAmlLengths 344 * 345 * PARAMETERS: Op - Parse node 346 * 347 * RETURN: None. 348 * 349 * DESCRIPTION: Generate internal length fields based on the AML opcode or 350 * parse opcode. 351 * 352 ******************************************************************************/ 353 354 void 355 CgGenerateAmlLengths ( 356 ACPI_PARSE_OBJECT *Op) 357 { 358 char *Buffer; 359 ACPI_STATUS Status; 360 361 362 switch (Op->Asl.AmlOpcode) 363 { 364 case AML_RAW_DATA_BYTE: 365 366 Op->Asl.AmlOpcodeLength = 0; 367 Op->Asl.AmlLength = 1; 368 return; 369 370 case AML_RAW_DATA_WORD: 371 372 Op->Asl.AmlOpcodeLength = 0; 373 Op->Asl.AmlLength = 2; 374 return; 375 376 case AML_RAW_DATA_DWORD: 377 378 Op->Asl.AmlOpcodeLength = 0; 379 Op->Asl.AmlLength = 4; 380 return; 381 382 case AML_RAW_DATA_QWORD: 383 384 Op->Asl.AmlOpcodeLength = 0; 385 Op->Asl.AmlLength = 8; 386 return; 387 388 case AML_RAW_DATA_BUFFER: 389 390 /* Aml length is/was set by creator */ 391 392 Op->Asl.AmlOpcodeLength = 0; 393 return; 394 395 case AML_RAW_DATA_CHAIN: 396 397 /* Aml length is/was set by creator */ 398 399 Op->Asl.AmlOpcodeLength = 0; 400 return; 401 402 default: 403 break; 404 } 405 406 switch (Op->Asl.ParseOpcode) 407 { 408 case PARSEOP_DEFINITIONBLOCK: 409 410 Gbl_TableLength = sizeof (ACPI_TABLE_HEADER) + 411 Op->Asl.AmlSubtreeLength; 412 break; 413 414 case PARSEOP_NAMESEG: 415 416 Op->Asl.AmlOpcodeLength = 0; 417 Op->Asl.AmlLength = 4; 418 Op->Asl.ExternalName = Op->Asl.Value.String; 419 break; 420 421 case PARSEOP_NAMESTRING: 422 case PARSEOP_METHODCALL: 423 424 if (Op->Asl.CompileFlags & NODE_NAME_INTERNALIZED) 425 { 426 break; 427 } 428 429 Op->Asl.AmlOpcodeLength = 0; 430 Status = UtInternalizeName (Op->Asl.Value.String, &Buffer); 431 if (ACPI_FAILURE (Status)) 432 { 433 DbgPrint (ASL_DEBUG_OUTPUT, 434 "Failure from internalize name %X\n", Status); 435 break; 436 } 437 438 Op->Asl.ExternalName = Op->Asl.Value.String; 439 Op->Asl.Value.String = Buffer; 440 Op->Asl.CompileFlags |= NODE_NAME_INTERNALIZED; 441 442 Op->Asl.AmlLength = strlen (Buffer); 443 444 /* 445 * Check for single backslash reference to root, 446 * make it a null terminated string in the AML 447 */ 448 if (Op->Asl.AmlLength == 1) 449 { 450 Op->Asl.AmlLength = 2; 451 } 452 break; 453 454 case PARSEOP_STRING_LITERAL: 455 456 Op->Asl.AmlOpcodeLength = 1; 457 458 /* Get null terminator */ 459 460 Op->Asl.AmlLength = strlen (Op->Asl.Value.String) + 1; 461 break; 462 463 case PARSEOP_PACKAGE_LENGTH: 464 465 Op->Asl.AmlOpcodeLength = 0; 466 Op->Asl.AmlPkgLenBytes = CgGetPackageLenByteCount (Op, 467 (UINT32) Op->Asl.Value.Integer); 468 break; 469 470 case PARSEOP_RAW_DATA: 471 472 Op->Asl.AmlOpcodeLength = 0; 473 break; 474 475 case PARSEOP_DEFAULT_ARG: 476 case PARSEOP_EXTERNAL: 477 case PARSEOP_INCLUDE: 478 case PARSEOP_INCLUDE_END: 479 480 /* Ignore the "default arg" nodes, they are extraneous at this point */ 481 482 break; 483 484 default: 485 486 CgGenerateAmlOpcodeLength (Op); 487 break; 488 } 489 } 490 491 492 #ifdef ACPI_OBSOLETE_FUNCTIONS 493 /******************************************************************************* 494 * 495 * FUNCTION: LnAdjustLengthToRoot 496 * 497 * PARAMETERS: Op - Node whose Length was changed 498 * 499 * RETURN: None. 500 * 501 * DESCRIPTION: Change the Subtree length of the given node, and bubble the 502 * change all the way up to the root node. This allows for 503 * last second changes to a package length (for example, if the 504 * package length encoding gets shorter or longer.) 505 * 506 ******************************************************************************/ 507 508 void 509 LnAdjustLengthToRoot ( 510 ACPI_PARSE_OBJECT *SubtreeOp, 511 UINT32 LengthDelta) 512 { 513 ACPI_PARSE_OBJECT *Op; 514 515 516 /* Adjust all subtree lengths up to the root */ 517 518 Op = SubtreeOp->Asl.Parent; 519 while (Op) 520 { 521 Op->Asl.AmlSubtreeLength -= LengthDelta; 522 Op = Op->Asl.Parent; 523 } 524 525 /* Adjust the global table length */ 526 527 Gbl_TableLength -= LengthDelta; 528 } 529 #endif 530 531 532