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