1 2 /****************************************************************************** 3 * 4 * Module Name: aslresource - Resource templates and descriptors 5 * $Revision: 31 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2003, 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 "aslcompiler.h" 120 #include "aslcompiler.y.h" 121 #include "amlcode.h" 122 123 124 #define _COMPONENT ACPI_COMPILER 125 ACPI_MODULE_NAME ("aslresource") 126 127 128 /******************************************************************************* 129 * 130 * FUNCTION: RsAllocateResourceNode 131 * 132 * PARAMETERS: Size - Size of node in bytes 133 * 134 * RETURN: The allocated node - aborts on allocation failure 135 * 136 * DESCRIPTION: Allocate a resource description node and the resource 137 * descriptor itself (the nodes are used to link descriptors). 138 * 139 ******************************************************************************/ 140 141 ASL_RESOURCE_NODE * 142 RsAllocateResourceNode ( 143 UINT32 Size) 144 { 145 ASL_RESOURCE_NODE *Rnode; 146 147 148 /* Allocate the node */ 149 150 Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE)); 151 152 /* Allocate the resource descriptor itself */ 153 154 Rnode->Buffer = UtLocalCalloc (Size); 155 Rnode->BufferLength = Size; 156 157 return (Rnode); 158 } 159 160 161 /******************************************************************************* 162 * 163 * FUNCTION: RsCreateBitField 164 * 165 * PARAMETERS: Op - Resource field node 166 * Name - Name of the field (Used only to reference 167 * the field in the ASL, not in the AML) 168 * ByteOffset - Offset from the field start 169 * BitOffset - Additional bit offset 170 * 171 * RETURN: None, sets fields within the input node 172 * 173 * DESCRIPTION: Utility function to generate a named bit field within a 174 * resource descriptor. Mark a node as 1) a field in a resource 175 * descriptor, and 2) set the value to be a BIT offset 176 * 177 ******************************************************************************/ 178 179 void 180 RsCreateBitField ( 181 ACPI_PARSE_OBJECT *Op, 182 char *Name, 183 UINT32 ByteOffset, 184 UINT32 BitOffset) 185 { 186 187 Op->Asl.ExternalName = Name; 188 Op->Asl.Value.Integer = (ByteOffset * 8) + BitOffset; 189 Op->Asl.CompileFlags |= (NODE_IS_RESOURCE_FIELD | NODE_IS_BIT_OFFSET); 190 } 191 192 193 /******************************************************************************* 194 * 195 * FUNCTION: RsCreateByteField 196 * 197 * PARAMETERS: Op - Resource field node 198 * Name - Name of the field (Used only to reference 199 * the field in the ASL, not in the AML) 200 * ByteOffset - Offset from the field start 201 * 202 * RETURN: None, sets fields within the input node 203 * 204 * DESCRIPTION: Utility function to generate a named byte field within a 205 * resource descriptor. Mark a node as 1) a field in a resource 206 * descriptor, and 2) set the value to be a BYTE offset 207 * 208 ******************************************************************************/ 209 210 void 211 RsCreateByteField ( 212 ACPI_PARSE_OBJECT *Op, 213 char *Name, 214 UINT32 ByteOffset) 215 { 216 217 Op->Asl.ExternalName = Name; 218 Op->Asl.Value.Integer = ByteOffset; 219 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD; 220 } 221 222 223 /******************************************************************************* 224 * 225 * FUNCTION: RsSetFlagBits 226 * 227 * PARAMETERS: *Flags - Pointer to the flag byte 228 * Op - Flag initialization node 229 * Position - Bit position within the flag byte 230 * Default - Used if the node is DEFAULT. 231 * 232 * RETURN: Sets bits within the *Flags output byte. 233 * 234 * DESCRIPTION: Set a bit in a cumulative flags word from an initialization 235 * node. Will use a default value if the node is DEFAULT, meaning 236 * that no value was specified in the ASL. Used to merge multiple 237 * keywords into a single flags byte. 238 * 239 ******************************************************************************/ 240 241 void 242 RsSetFlagBits ( 243 UINT8 *Flags, 244 ACPI_PARSE_OBJECT *Op, 245 UINT8 Position, 246 UINT8 DefaultBit) 247 { 248 249 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 250 { 251 /* Use the default bit */ 252 253 *Flags |= (DefaultBit << Position); 254 } 255 else 256 { 257 /* Use the bit specified in the initialization node */ 258 259 *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position); 260 } 261 } 262 263 264 /******************************************************************************* 265 * 266 * FUNCTION: RsCompleteNodeAndGetNext 267 * 268 * PARAMETERS: Op - Resource node to be completed 269 * 270 * RETURN: The next peer to the input node. 271 * 272 * DESCRIPTION: Mark the current node completed and return the next peer. 273 * The node ParseOpcode is set to DEFAULT_ARG, meaning that 274 * this node is to be ignored from now on. 275 * 276 ******************************************************************************/ 277 278 ACPI_PARSE_OBJECT * 279 RsCompleteNodeAndGetNext ( 280 ACPI_PARSE_OBJECT *Op) 281 { 282 283 /* Mark this node unused */ 284 285 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 286 287 /* Move on to the next peer node in the initializer list */ 288 289 return (ASL_GET_PEER_NODE (Op)); 290 } 291 292 293 /******************************************************************************* 294 * 295 * FUNCTION: RsDoOneResourceDescriptor 296 * 297 * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor 298 * CurrentByteOffset - Offset in the resource descriptor 299 * buffer. 300 * 301 * RETURN: A valid resource node for the descriptor 302 * 303 * DESCRIPTION: Dispatches the processing of one resource descriptor 304 * 305 ******************************************************************************/ 306 307 ASL_RESOURCE_NODE * 308 RsDoOneResourceDescriptor ( 309 ACPI_PARSE_OBJECT *DescriptorTypeOp, 310 UINT32 CurrentByteOffset, 311 UINT8 *State) 312 { 313 ASL_RESOURCE_NODE *Rnode = NULL; 314 315 316 /* Determine type of resource */ 317 318 switch (DescriptorTypeOp->Asl.ParseOpcode) 319 { 320 case PARSEOP_DMA: 321 Rnode = RsDoDmaDescriptor (DescriptorTypeOp, CurrentByteOffset); 322 break; 323 324 case PARSEOP_DWORDIO: 325 Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp, CurrentByteOffset); 326 break; 327 328 case PARSEOP_DWORDMEMORY: 329 Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp, CurrentByteOffset); 330 break; 331 332 case PARSEOP_ENDDEPENDENTFN: 333 switch (*State) 334 { 335 case ACPI_RSTATE_NORMAL: 336 AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT, DescriptorTypeOp, NULL); 337 break; 338 339 case ACPI_RSTATE_START_DEPENDENT: 340 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, DescriptorTypeOp, NULL); 341 break; 342 343 case ACPI_RSTATE_DEPENDENT_LIST: 344 default: 345 break; 346 } 347 348 *State = ACPI_RSTATE_NORMAL; 349 Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp, CurrentByteOffset); 350 break; 351 352 case PARSEOP_FIXEDIO: 353 Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp, CurrentByteOffset); 354 break; 355 356 case PARSEOP_INTERRUPT: 357 Rnode = RsDoInterruptDescriptor (DescriptorTypeOp, CurrentByteOffset); 358 break; 359 360 case PARSEOP_IO: 361 Rnode = RsDoIoDescriptor (DescriptorTypeOp, CurrentByteOffset); 362 break; 363 364 case PARSEOP_IRQ: 365 Rnode = RsDoIrqDescriptor (DescriptorTypeOp, CurrentByteOffset); 366 break; 367 368 case PARSEOP_IRQNOFLAGS: 369 Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp, CurrentByteOffset); 370 break; 371 372 case PARSEOP_MEMORY24: 373 Rnode = RsDoMemory24Descriptor (DescriptorTypeOp, CurrentByteOffset); 374 break; 375 376 case PARSEOP_MEMORY32: 377 Rnode = RsDoMemory32Descriptor (DescriptorTypeOp, CurrentByteOffset); 378 break; 379 380 case PARSEOP_MEMORY32FIXED: 381 Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp, CurrentByteOffset); 382 break; 383 384 case PARSEOP_QWORDIO: 385 Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp, CurrentByteOffset); 386 break; 387 388 case PARSEOP_QWORDMEMORY: 389 Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp, CurrentByteOffset); 390 break; 391 392 case PARSEOP_REGISTER: 393 Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp, CurrentByteOffset); 394 break; 395 396 case PARSEOP_STARTDEPENDENTFN: 397 switch (*State) 398 { 399 case ACPI_RSTATE_START_DEPENDENT: 400 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, DescriptorTypeOp, NULL); 401 break; 402 403 case ACPI_RSTATE_NORMAL: 404 case ACPI_RSTATE_DEPENDENT_LIST: 405 default: 406 break; 407 } 408 409 *State = ACPI_RSTATE_START_DEPENDENT; 410 Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp, CurrentByteOffset); 411 *State = ACPI_RSTATE_DEPENDENT_LIST; 412 break; 413 414 case PARSEOP_STARTDEPENDENTFN_NOPRI: 415 switch (*State) 416 { 417 case ACPI_RSTATE_START_DEPENDENT: 418 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, DescriptorTypeOp, NULL); 419 break; 420 421 case ACPI_RSTATE_NORMAL: 422 case ACPI_RSTATE_DEPENDENT_LIST: 423 default: 424 break; 425 } 426 427 *State = ACPI_RSTATE_START_DEPENDENT; 428 Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp, CurrentByteOffset); 429 *State = ACPI_RSTATE_DEPENDENT_LIST; 430 break; 431 432 case PARSEOP_VENDORLONG: 433 Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp, CurrentByteOffset); 434 break; 435 436 case PARSEOP_VENDORSHORT: 437 Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp, CurrentByteOffset); 438 break; 439 440 case PARSEOP_WORDBUSNUMBER: 441 Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp, CurrentByteOffset); 442 break; 443 444 case PARSEOP_WORDIO: 445 Rnode = RsDoWordIoDescriptor (DescriptorTypeOp, CurrentByteOffset); 446 break; 447 448 case PARSEOP_DEFAULT_ARG: 449 /* Just ignore any of these, they are used as fillers/placeholders */ 450 break; 451 452 default: 453 printf ("Unknown resource descriptor type [%s]\n", 454 DescriptorTypeOp->Asl.ParseOpName); 455 break; 456 } 457 458 /* 459 * Mark original node as unused, but head of a resource descriptor. 460 * This allows the resource to be installed in the namespace so that 461 * references to the descriptor can be resolved. 462 */ 463 DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 464 DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC; 465 466 return (Rnode); 467 } 468 469 470 /******************************************************************************* 471 * 472 * FUNCTION: RsLinkDescriptorChain 473 * 474 * PARAMETERS: PreviousRnode - Pointer to the node that will be previous 475 * to the linked node, At exit, set to the 476 * last node in the new chain. 477 * Rnode - Resource node to link into the list 478 * 479 * RETURN: Cumulative buffer byte offset of the new segment of chain 480 * 481 * DESCRIPTION: Link a descriptor chain at the end of an existing chain. 482 * 483 ******************************************************************************/ 484 485 UINT32 486 RsLinkDescriptorChain ( 487 ASL_RESOURCE_NODE **PreviousRnode, 488 ASL_RESOURCE_NODE *Rnode) 489 { 490 ASL_RESOURCE_NODE *LastRnode; 491 UINT32 CurrentByteOffset; 492 493 494 /* Anything to do? */ 495 496 if (!Rnode) 497 { 498 return 0; 499 } 500 501 /* Point the previous node to the new node */ 502 503 (*PreviousRnode)->Next = Rnode; 504 CurrentByteOffset = Rnode->BufferLength; 505 506 /* Walk to the end of the chain headed by Rnode */ 507 508 LastRnode = Rnode; 509 while (LastRnode->Next) 510 { 511 LastRnode = LastRnode->Next; 512 CurrentByteOffset += LastRnode->BufferLength; 513 } 514 515 /* Previous node becomes the last node in the chain */ 516 517 *PreviousRnode = LastRnode; 518 return CurrentByteOffset; 519 } 520 521 522 /******************************************************************************* 523 * 524 * FUNCTION: RsDoResourceTemplate 525 * 526 * PARAMETERS: Op - Parent of a resource template list 527 * 528 * RETURN: None. Sets input node to point to a list of AML code 529 * 530 * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer, 531 * in preparation for output to the AML output file. 532 * 533 ******************************************************************************/ 534 535 void 536 RsDoResourceTemplate ( 537 ACPI_PARSE_OBJECT *Op) 538 { 539 ACPI_PARSE_OBJECT *BufferLengthOp; 540 ACPI_PARSE_OBJECT *BufferOp; 541 ACPI_PARSE_OBJECT *DescriptorTypeOp; 542 ACPI_PARSE_OBJECT *LastOp = NULL; 543 ASL_RESOURCE_DESC *Descriptor; 544 UINT32 CurrentByteOffset = 0; 545 ASL_RESOURCE_NODE HeadRnode; 546 ASL_RESOURCE_NODE *PreviousRnode; 547 ASL_RESOURCE_NODE *Rnode; 548 UINT8 State; 549 550 551 /* ResourceTemplate Opcode is first (Op) */ 552 /* Buffer Length node is first child */ 553 554 BufferLengthOp = ASL_GET_CHILD_NODE (Op); 555 556 /* Buffer Op is first peer */ 557 558 BufferOp = ASL_GET_PEER_NODE (BufferLengthOp); 559 560 /* First Descriptor type is next */ 561 562 DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp); 563 564 /* Process all resource descriptors in the list */ 565 566 State = ACPI_RSTATE_NORMAL; 567 PreviousRnode = &HeadRnode; 568 while (DescriptorTypeOp) 569 { 570 Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset, &State); 571 572 /* 573 * Update current byte offset to indicate the number of bytes from the 574 * start of the buffer. Buffer can include multiple descriptors, we 575 * must keep track of the offset of not only each descriptor, but each 576 * element (field) within each descriptor as well. 577 */ 578 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode); 579 580 /* Get the next descriptor in the list */ 581 582 LastOp = DescriptorTypeOp; 583 DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp); 584 } 585 586 if (State == ACPI_RSTATE_DEPENDENT_LIST) 587 { 588 if (LastOp) 589 { 590 LastOp = LastOp->Asl.Parent; 591 } 592 AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL); 593 } 594 595 /* 596 * Insert the EndTag descriptor after all other descriptors have been processed 597 */ 598 Rnode = RsAllocateResourceNode (sizeof (ASL_END_TAG_DESC)); 599 600 Descriptor = Rnode->Buffer; 601 Descriptor->Et.DescriptorType = ACPI_RDESC_TYPE_END_TAG | 602 ASL_RDESC_END_TAG_SIZE; 603 Descriptor->Et.Checksum = 0; 604 605 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode); 606 607 /* 608 * Transform the nodes into the following 609 * 610 * Op -> AML_BUFFER_OP 611 * First Child -> BufferLength 612 * Second Child -> Descriptor Buffer (raw byte data) 613 */ 614 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 615 Op->Asl.AmlOpcode = AML_BUFFER_OP; 616 Op->Asl.CompileFlags = NODE_AML_PACKAGE; 617 618 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 619 BufferLengthOp->Asl.Value.Integer = CurrentByteOffset; 620 621 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 622 623 BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 624 BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 625 BufferOp->Asl.AmlOpcodeLength = 0; 626 BufferOp->Asl.AmlLength = CurrentByteOffset; 627 BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next; 628 629 return; 630 } 631 632 633