1 /****************************************************************************** 2 * 3 * Module Name: aslrestype2s - Serial Large resource descriptors 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2023, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include <contrib/dev/acpica/compiler/aslcompiler.h> 153 #include "aslcompiler.y.h" 154 #include <contrib/dev/acpica/include/amlcode.h> 155 156 #define _COMPONENT ACPI_COMPILER 157 ACPI_MODULE_NAME ("aslrestype2s") 158 159 160 static UINT16 161 RsGetBufferDataLength ( 162 ACPI_PARSE_OBJECT *InitializerOp); 163 164 static UINT16 165 RsGetInterruptDataLength ( 166 ACPI_PARSE_OBJECT *InitializerOp, 167 UINT32 StartIndex); 168 169 static BOOLEAN 170 RsGetVendorData ( 171 ACPI_PARSE_OBJECT *InitializerOp, 172 UINT8 *VendorData, 173 ACPI_SIZE DescriptorOffset); 174 175 static UINT16 176 RsGetStringDataLengthAt ( 177 ACPI_PARSE_OBJECT *InitializerOp, 178 UINT32 StartIndex); 179 180 /* 181 * This module contains descriptors for serial buses and GPIO: 182 * 183 * GpioInt 184 * GpioIo 185 * I2cSerialBus 186 * SpiSerialBus 187 * UartSerialBus 188 * PinFunction 189 * PinConfig 190 * PinGroup 191 * PinGroupFunction 192 * PinGroupConfig 193 */ 194 195 196 /******************************************************************************* 197 * 198 * FUNCTION: RsGetBufferDataLength 199 * 200 * PARAMETERS: InitializerOp - Current parse op, start of the resource 201 * descriptor 202 * 203 * RETURN: Length of the data buffer 204 * 205 * DESCRIPTION: Get the length of a RawDataBuffer, used for vendor data. 206 * 207 ******************************************************************************/ 208 209 static UINT16 210 RsGetBufferDataLength ( 211 ACPI_PARSE_OBJECT *InitializerOp) 212 { 213 UINT16 ExtraDataSize = 0; 214 ACPI_PARSE_OBJECT *DataList; 215 216 217 /* Find the byte-initializer list */ 218 219 while (InitializerOp) 220 { 221 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DATABUFFER) 222 { 223 /* First child is the optional length (ignore it here) */ 224 225 DataList = InitializerOp->Asl.Child; 226 DataList = ASL_GET_PEER_NODE (DataList); 227 228 /* Count the data items (each one is a byte of data) */ 229 230 while (DataList) 231 { 232 ExtraDataSize++; 233 DataList = ASL_GET_PEER_NODE (DataList); 234 } 235 236 return (ExtraDataSize); 237 } 238 239 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 240 } 241 242 return (ExtraDataSize); 243 } 244 245 246 /******************************************************************************* 247 * 248 * FUNCTION: RsGetInterruptDataLength 249 * 250 * PARAMETERS: InitializerOp - Current parse op, start of the resource 251 * descriptor 252 * StartIndex - Start index of interrupt/pin list 253 * 254 * RETURN: Length of the interrupt data list 255 * 256 * DESCRIPTION: Get the length of a list of interrupt DWORDs for the GPIO 257 * descriptors. 258 * 259 ******************************************************************************/ 260 261 static UINT16 262 RsGetInterruptDataLength ( 263 ACPI_PARSE_OBJECT *InitializerOp, 264 UINT32 StartIndex) 265 { 266 UINT16 InterruptLength; 267 UINT32 i; 268 269 270 /* Count the interrupt numbers */ 271 272 InterruptLength = 0; 273 for (i = 0; InitializerOp; i++) 274 { 275 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 276 277 /* Interrupt list starts at offset StartIndex (Gpio descriptors) */ 278 279 if (i >= StartIndex) 280 { 281 InterruptLength += 2; 282 } 283 } 284 285 return (InterruptLength); 286 } 287 288 289 /******************************************************************************* 290 * 291 * FUNCTION: RsGetVendorData 292 * 293 * PARAMETERS: InitializerOp - Current parse op, start of the resource 294 * descriptor. 295 * VendorData - Where the vendor data is returned 296 * DescriptorOffset - Where vendor data begins in descriptor 297 * 298 * RETURN: TRUE if valid vendor data was returned, FALSE otherwise. 299 * 300 * DESCRIPTION: Extract the vendor data and construct a vendor data buffer. 301 * 302 ******************************************************************************/ 303 304 static BOOLEAN 305 RsGetVendorData ( 306 ACPI_PARSE_OBJECT *InitializerOp, 307 UINT8 *VendorData, 308 ACPI_SIZE DescriptorOffset) 309 { 310 ACPI_PARSE_OBJECT *BufferOp; 311 UINT32 SpecifiedLength = ACPI_UINT32_MAX; 312 UINT16 ActualLength = 0; 313 314 315 /* Vendor Data field is always optional */ 316 317 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 318 { 319 return (FALSE); 320 } 321 322 BufferOp = InitializerOp->Asl.Child; 323 if (!BufferOp) 324 { 325 AslError (ASL_ERROR, ASL_MSG_SYNTAX, InitializerOp, ""); 326 return (FALSE); 327 } 328 329 /* First child is the optional buffer length (WORD) */ 330 331 if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 332 { 333 SpecifiedLength = (UINT16) BufferOp->Asl.Value.Integer; 334 } 335 336 /* Insert field tag _VEN */ 337 338 RsCreateByteField (InitializerOp, ACPI_RESTAG_VENDORDATA, 339 (UINT16) DescriptorOffset); 340 341 /* Walk the list of buffer initializers (each is one byte) */ 342 343 BufferOp = RsCompleteNodeAndGetNext (BufferOp); 344 if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 345 { 346 while (BufferOp) 347 { 348 *VendorData = (UINT8) BufferOp->Asl.Value.Integer; 349 VendorData++; 350 ActualLength++; 351 BufferOp = RsCompleteNodeAndGetNext (BufferOp); 352 } 353 } 354 355 /* Length validation. Buffer cannot be of zero length */ 356 357 if ((SpecifiedLength == 0) || 358 ((SpecifiedLength == ACPI_UINT32_MAX) && (ActualLength == 0))) 359 { 360 AslError (ASL_ERROR, ASL_MSG_BUFFER_LENGTH, InitializerOp, NULL); 361 return (FALSE); 362 } 363 364 if (SpecifiedLength != ACPI_UINT32_MAX) 365 { 366 /* ActualLength > SpecifiedLength -> error */ 367 368 if (ActualLength > SpecifiedLength) 369 { 370 AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG, InitializerOp, NULL); 371 return (FALSE); 372 } 373 374 /* ActualLength < SpecifiedLength -> remark */ 375 376 else if (ActualLength < SpecifiedLength) 377 { 378 AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT, InitializerOp, NULL); 379 return (FALSE); 380 } 381 } 382 383 return (TRUE); 384 } 385 386 387 /******************************************************************************* 388 * 389 * FUNCTION: RsGetStringDataLengthAt 390 * 391 * PARAMETERS: InitializerOp - Start of a subtree of init nodes 392 * StartIndex - Starting index of the string node 393 * 394 * RETURN: Valid string length if a string node is found at given 395 * StartIndex or 0 otherwise. 396 * 397 * DESCRIPTION: In a list of peer nodes, find the first one at given index 398 * that contains a string and return length. 399 * 400 ******************************************************************************/ 401 402 static UINT16 403 RsGetStringDataLengthAt ( 404 ACPI_PARSE_OBJECT *InitializerOp, 405 UINT32 StartIndex) 406 { 407 UINT32 i; 408 409 for (i = 0; InitializerOp; i++) 410 { 411 if (i == StartIndex && 412 InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) 413 { 414 return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1)); 415 } 416 417 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 418 } 419 420 return (0); 421 } 422 423 424 /******************************************************************************* 425 * 426 * FUNCTION: RsDoGpioIntDescriptor 427 * 428 * PARAMETERS: Info - Parse Op and resource template offset 429 * 430 * RETURN: Completed resource node 431 * 432 * DESCRIPTION: Construct a long "GpioInt" descriptor 433 * 434 ******************************************************************************/ 435 436 ASL_RESOURCE_NODE * 437 RsDoGpioIntDescriptor ( 438 ASL_RESOURCE_INFO *Info) 439 { 440 AML_RESOURCE *Descriptor; 441 ACPI_PARSE_OBJECT *InitializerOp; 442 ASL_RESOURCE_NODE *Rnode; 443 char *ResourceSource = NULL; 444 UINT8 *VendorData = NULL; 445 UINT16 *InterruptList = NULL; 446 UINT16 *PinList = NULL; 447 UINT16 ResSourceLength; 448 UINT16 VendorLength; 449 UINT16 InterruptLength; 450 UINT16 DescriptorSize; 451 UINT32 CurrentByteOffset; 452 UINT32 PinCount = 0; 453 UINT32 i; 454 455 456 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 457 CurrentByteOffset = Info->CurrentByteOffset; 458 459 /* 460 * Calculate lengths for fields that have variable length: 461 * 1) Resource Source string 462 * 2) Vendor Data buffer 463 * 3) PIN (interrupt) list 464 */ 465 ResSourceLength = RsGetStringDataLength (InitializerOp); 466 VendorLength = RsGetBufferDataLength (InitializerOp); 467 InterruptLength = RsGetInterruptDataLength (InitializerOp, 10); 468 469 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) + 470 ResSourceLength + VendorLength + InterruptLength; 471 472 /* Allocate the local resource node and initialize */ 473 474 Rnode = RsAllocateResourceNode (DescriptorSize + 475 sizeof (AML_RESOURCE_LARGE_HEADER)); 476 477 Descriptor = Rnode->Buffer; 478 Descriptor->Gpio.ResourceLength = DescriptorSize; 479 Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO; 480 Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION; 481 Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_INT; 482 483 /* Build pointers to optional areas */ 484 485 InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, 486 sizeof (AML_RESOURCE_GPIO)); 487 PinList = InterruptList; 488 ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength); 489 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 490 491 /* Setup offsets within the descriptor */ 492 493 Descriptor->Gpio.PinTableOffset = (UINT16) 494 ACPI_PTR_DIFF (InterruptList, Descriptor); 495 496 Descriptor->Gpio.ResSourceOffset = (UINT16) 497 ACPI_PTR_DIFF (ResourceSource, Descriptor); 498 499 /* Process all child initialization nodes */ 500 501 for (i = 0; InitializerOp; i++) 502 { 503 switch (i) 504 { 505 case 0: /* Interrupt Mode - edge/level [Flag] (_MOD) */ 506 507 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0); 508 RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE, 509 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0); 510 break; 511 512 case 1: /* Interrupt Polarity - Active high/low [Flags] (_POL) */ 513 514 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 1, 0); 515 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_POLARITY, 516 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 1, 2); 517 break; 518 519 case 2: /* Share Type - Default: exclusive (0) [Flags] (_SHR) */ 520 521 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0); 522 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 523 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3, 2); 524 break; 525 526 case 3: /* Pin Config [BYTE] (_PPI) */ 527 528 Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer; 529 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG, 530 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig)); 531 break; 532 533 case 4: /* Debounce Timeout [WORD] (_DBT) */ 534 535 Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer; 536 RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME, 537 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout)); 538 break; 539 540 case 5: /* ResSource [Optional Field - STRING] */ 541 542 if (ResSourceLength) 543 { 544 /* Copy string to the descriptor */ 545 546 strcpy (ResourceSource, 547 InitializerOp->Asl.Value.String); 548 } 549 break; 550 551 case 6: /* Resource Index */ 552 553 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 554 { 555 Descriptor->Gpio.ResSourceIndex = 556 (UINT8) InitializerOp->Asl.Value.Integer; 557 } 558 break; 559 560 case 7: /* Resource Usage (consumer/producer) */ 561 562 RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1); 563 break; 564 565 case 8: /* Resource Tag (Descriptor Name) */ 566 567 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 568 break; 569 570 case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 571 572 /* 573 * Always set the VendorOffset even if there is no Vendor Data. 574 * This field is required in order to calculate the length 575 * of the ResourceSource at runtime. 576 */ 577 Descriptor->Gpio.VendorOffset = (UINT16) 578 ACPI_PTR_DIFF (VendorData, Descriptor); 579 580 if (RsGetVendorData (InitializerOp, VendorData, 581 (CurrentByteOffset + Descriptor->Gpio.VendorOffset))) 582 { 583 Descriptor->Gpio.VendorLength = VendorLength; 584 } 585 break; 586 587 default: 588 /* 589 * PINs come through here, repeatedly. Each PIN must be a WORD. 590 * NOTE: there is no "length" field for this, so from ACPI spec: 591 * The number of pins in the table can be calculated from: 592 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 593 * (implies resource source must immediately follow the pin list.) 594 * Name: _PIN 595 */ 596 *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer; 597 InterruptList++; 598 PinCount++; 599 600 /* Case 10: First interrupt number in list */ 601 602 if (i == 10) 603 { 604 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 605 { 606 /* Must be at least one interrupt */ 607 608 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 609 InitializerOp, NULL); 610 } 611 612 /* Check now for duplicates in list */ 613 614 RsCheckListForDuplicates (InitializerOp); 615 616 /* Create a named field at the start of the list */ 617 618 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 619 CurrentByteOffset + Descriptor->Gpio.PinTableOffset); 620 } 621 break; 622 } 623 624 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 625 } 626 627 MpSaveGpioInfo (Info->MappingOp, Descriptor, 628 PinCount, PinList, ResourceSource); 629 return (Rnode); 630 } 631 632 633 /******************************************************************************* 634 * 635 * FUNCTION: RsDoGpioIoDescriptor 636 * 637 * PARAMETERS: Info - Parse Op and resource template offset 638 * 639 * RETURN: Completed resource node 640 * 641 * DESCRIPTION: Construct a long "GpioIo" descriptor 642 * 643 ******************************************************************************/ 644 645 ASL_RESOURCE_NODE * 646 RsDoGpioIoDescriptor ( 647 ASL_RESOURCE_INFO *Info) 648 { 649 AML_RESOURCE *Descriptor; 650 ACPI_PARSE_OBJECT *InitializerOp; 651 ASL_RESOURCE_NODE *Rnode; 652 char *ResourceSource = NULL; 653 UINT8 *VendorData = NULL; 654 UINT16 *InterruptList = NULL; 655 UINT16 *PinList = NULL; 656 UINT16 ResSourceLength; 657 UINT16 VendorLength; 658 UINT16 InterruptLength; 659 UINT16 DescriptorSize; 660 UINT32 CurrentByteOffset; 661 UINT32 PinCount = 0; 662 UINT32 i; 663 664 665 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 666 CurrentByteOffset = Info->CurrentByteOffset; 667 668 /* 669 * Calculate lengths for fields that have variable length: 670 * 1) Resource Source string 671 * 2) Vendor Data buffer 672 * 3) PIN (interrupt) list 673 */ 674 ResSourceLength = RsGetStringDataLength (InitializerOp); 675 VendorLength = RsGetBufferDataLength (InitializerOp); 676 InterruptLength = RsGetInterruptDataLength (InitializerOp, 10); 677 678 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) + 679 ResSourceLength + VendorLength + InterruptLength; 680 681 /* Allocate the local resource node and initialize */ 682 683 Rnode = RsAllocateResourceNode (DescriptorSize + 684 sizeof (AML_RESOURCE_LARGE_HEADER)); 685 686 Descriptor = Rnode->Buffer; 687 Descriptor->Gpio.ResourceLength = DescriptorSize; 688 Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO; 689 Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION; 690 Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_IO; 691 692 /* Build pointers to optional areas */ 693 694 InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO)); 695 PinList = InterruptList; 696 ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength); 697 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 698 699 /* Setup offsets within the descriptor */ 700 701 Descriptor->Gpio.PinTableOffset = (UINT16) 702 ACPI_PTR_DIFF (InterruptList, Descriptor); 703 704 Descriptor->Gpio.ResSourceOffset = (UINT16) 705 ACPI_PTR_DIFF (ResourceSource, Descriptor); 706 707 /* Process all child initialization nodes */ 708 709 for (i = 0; InitializerOp; i++) 710 { 711 switch (i) 712 { 713 case 0: /* Share Type [Flags] (_SHR) */ 714 715 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0); 716 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 717 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3); 718 break; 719 720 case 1: /* Pin Config [BYTE] (_PPI) */ 721 722 Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer; 723 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG, 724 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig)); 725 break; 726 727 case 2: /* Debounce Timeout [WORD] (_DBT) */ 728 729 Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer; 730 RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME, 731 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout)); 732 break; 733 734 case 3: /* Drive Strength [WORD] (_DRS) */ 735 736 Descriptor->Gpio.DriveStrength = (UINT16) InitializerOp->Asl.Value.Integer; 737 RsCreateWordField (InitializerOp, ACPI_RESTAG_DRIVESTRENGTH, 738 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DriveStrength)); 739 break; 740 741 case 4: /* I/O Restriction [Flag] (_IOR) */ 742 743 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0); 744 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_IORESTRICTION, 745 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0, 2); 746 break; 747 748 case 5: /* ResSource [Optional Field - STRING] */ 749 750 if (ResSourceLength) 751 { 752 /* Copy string to the descriptor */ 753 754 strcpy (ResourceSource, 755 InitializerOp->Asl.Value.String); 756 } 757 break; 758 759 case 6: /* Resource Index */ 760 761 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 762 { 763 Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 764 } 765 break; 766 767 case 7: /* Resource Usage (consumer/producer) */ 768 769 RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1); 770 break; 771 772 case 8: /* Resource Tag (Descriptor Name) */ 773 774 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 775 break; 776 777 case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 778 /* 779 * Always set the VendorOffset even if there is no Vendor Data. 780 * This field is required in order to calculate the length 781 * of the ResourceSource at runtime. 782 */ 783 Descriptor->Gpio.VendorOffset = (UINT16) 784 ACPI_PTR_DIFF (VendorData, Descriptor); 785 786 if (RsGetVendorData (InitializerOp, VendorData, 787 (CurrentByteOffset + Descriptor->Gpio.VendorOffset))) 788 { 789 Descriptor->Gpio.VendorLength = VendorLength; 790 } 791 break; 792 793 default: 794 /* 795 * PINs come through here, repeatedly. Each PIN must be a WORD. 796 * NOTE: there is no "length" field for this, so from ACPI spec: 797 * The number of pins in the table can be calculated from: 798 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 799 * (implies resource source must immediately follow the pin list.) 800 * Name: _PIN 801 */ 802 *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer; 803 InterruptList++; 804 PinCount++; 805 806 /* Case 10: First interrupt number in list */ 807 808 if (i == 10) 809 { 810 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 811 { 812 /* Must be at least one interrupt */ 813 814 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 815 InitializerOp, NULL); 816 } 817 818 /* Check now for duplicates in list */ 819 820 RsCheckListForDuplicates (InitializerOp); 821 822 /* Create a named field at the start of the list */ 823 824 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 825 CurrentByteOffset + Descriptor->Gpio.PinTableOffset); 826 } 827 break; 828 } 829 830 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 831 } 832 833 MpSaveGpioInfo (Info->MappingOp, Descriptor, 834 PinCount, PinList, ResourceSource); 835 return (Rnode); 836 } 837 838 839 /******************************************************************************* 840 * 841 * FUNCTION: RsDoI2cSerialBusDescriptor 842 * 843 * PARAMETERS: Info - Parse Op and resource template offset 844 * 845 * RETURN: Completed resource node 846 * 847 * DESCRIPTION: Construct a long "I2cSerialBus" descriptor 848 * 849 ******************************************************************************/ 850 851 ASL_RESOURCE_NODE * 852 RsDoI2cSerialBusDescriptor ( 853 ASL_RESOURCE_INFO *Info) 854 { 855 AML_RESOURCE *Descriptor; 856 ACPI_PARSE_OBJECT *InitializerOp; 857 ASL_RESOURCE_NODE *Rnode; 858 char *ResourceSource = NULL; 859 UINT8 *VendorData = NULL; 860 UINT16 ResSourceLength; 861 UINT16 VendorLength; 862 UINT16 DescriptorSize; 863 UINT32 CurrentByteOffset; 864 UINT32 i; 865 866 867 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 868 CurrentByteOffset = Info->CurrentByteOffset; 869 870 /* 871 * Calculate lengths for fields that have variable length: 872 * 1) Resource Source string 873 * 2) Vendor Data buffer 874 */ 875 ResSourceLength = RsGetStringDataLength (InitializerOp); 876 VendorLength = RsGetBufferDataLength (InitializerOp); 877 878 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS) + 879 ResSourceLength + VendorLength; 880 881 /* Allocate the local resource node and initialize */ 882 883 Rnode = RsAllocateResourceNode (DescriptorSize + 884 sizeof (AML_RESOURCE_LARGE_HEADER)); 885 886 Descriptor = Rnode->Buffer; 887 Descriptor->I2cSerialBus.ResourceLength = DescriptorSize; 888 Descriptor->I2cSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 889 Descriptor->I2cSerialBus.RevisionId = AML_RESOURCE_I2C_REVISION; 890 Descriptor->I2cSerialBus.TypeRevisionId = AML_RESOURCE_I2C_TYPE_REVISION; 891 Descriptor->I2cSerialBus.Type = AML_RESOURCE_I2C_SERIALBUSTYPE; 892 Descriptor->I2cSerialBus.TypeDataLength = AML_RESOURCE_I2C_MIN_DATA_LEN + VendorLength; 893 894 if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_I2C_SERIALBUS_V2) 895 { 896 Descriptor->I2cSerialBus.RevisionId = 2; 897 } 898 899 /* Build pointers to optional areas */ 900 901 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_I2C_SERIALBUS)); 902 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 903 904 /* Process all child initialization nodes */ 905 906 for (i = 0; InitializerOp; i++) 907 { 908 switch (i) 909 { 910 case 0: /* Slave Address [WORD] (_ADR) */ 911 912 Descriptor->I2cSerialBus.SlaveAddress = (UINT16) InitializerOp->Asl.Value.Integer; 913 RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS, 914 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.SlaveAddress)); 915 break; 916 917 case 1: /* Slave Mode [Flag] (_SLV) */ 918 919 RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 0, 0); 920 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 921 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0); 922 break; 923 924 case 2: /* Connection Speed [DWORD] (_SPE) */ 925 926 Descriptor->I2cSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer; 927 RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, 928 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.ConnectionSpeed)); 929 break; 930 931 case 3: /* Addressing Mode [Flag] (_MOD) */ 932 933 RsSetFlagBits16 (&Descriptor->I2cSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 934 RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE, 935 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.TypeSpecificFlags), 0); 936 break; 937 938 case 4: /* ResSource [Optional Field - STRING] */ 939 940 if (ResSourceLength) 941 { 942 /* Copy string to the descriptor */ 943 944 strcpy (ResourceSource, 945 InitializerOp->Asl.Value.String); 946 } 947 break; 948 949 case 5: /* Resource Index */ 950 951 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 952 { 953 Descriptor->I2cSerialBus.ResSourceIndex = 954 (UINT8) InitializerOp->Asl.Value.Integer; 955 } 956 break; 957 958 case 6: /* Resource Usage (consumer/producer) */ 959 960 RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 1, 1); 961 break; 962 963 case 7: /* Resource Tag (Descriptor Name) */ 964 965 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 966 break; 967 968 case 8: 969 /* 970 * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor 971 * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from 972 * the ASL parser) 973 */ 974 RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 2, 0); 975 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 976 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 2); 977 break; 978 979 case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 980 981 RsGetVendorData (InitializerOp, VendorData, 982 CurrentByteOffset + sizeof (AML_RESOURCE_I2C_SERIALBUS)); 983 break; 984 985 default: /* Ignore any extra nodes */ 986 987 break; 988 } 989 990 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 991 } 992 993 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 994 return (Rnode); 995 } 996 997 998 /******************************************************************************* 999 * 1000 * FUNCTION: RsDoSpiSerialBusDescriptor 1001 * 1002 * PARAMETERS: Info - Parse Op and resource template offset 1003 * 1004 * RETURN: Completed resource node 1005 * 1006 * DESCRIPTION: Construct a long "SPI Serial Bus" descriptor 1007 * 1008 ******************************************************************************/ 1009 1010 ASL_RESOURCE_NODE * 1011 RsDoSpiSerialBusDescriptor ( 1012 ASL_RESOURCE_INFO *Info) 1013 { 1014 AML_RESOURCE *Descriptor; 1015 ACPI_PARSE_OBJECT *InitializerOp; 1016 ASL_RESOURCE_NODE *Rnode; 1017 char *ResourceSource = NULL; 1018 UINT8 *VendorData = NULL; 1019 UINT16 ResSourceLength; 1020 UINT16 VendorLength; 1021 UINT16 DescriptorSize; 1022 UINT32 CurrentByteOffset; 1023 UINT32 i; 1024 1025 1026 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1027 CurrentByteOffset = Info->CurrentByteOffset; 1028 1029 /* 1030 * Calculate lengths for fields that have variable length: 1031 * 1) Resource Source string 1032 * 2) Vendor Data buffer 1033 */ 1034 ResSourceLength = RsGetStringDataLength (InitializerOp); 1035 VendorLength = RsGetBufferDataLength (InitializerOp); 1036 1037 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS) + 1038 ResSourceLength + VendorLength; 1039 1040 /* Allocate the local resource node and initialize */ 1041 1042 Rnode = RsAllocateResourceNode (DescriptorSize + 1043 sizeof (AML_RESOURCE_LARGE_HEADER)); 1044 1045 Descriptor = Rnode->Buffer; 1046 Descriptor->SpiSerialBus.ResourceLength = DescriptorSize; 1047 Descriptor->SpiSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 1048 Descriptor->SpiSerialBus.RevisionId = AML_RESOURCE_SPI_REVISION; 1049 Descriptor->SpiSerialBus.TypeRevisionId = AML_RESOURCE_SPI_TYPE_REVISION; 1050 Descriptor->SpiSerialBus.Type = AML_RESOURCE_SPI_SERIALBUSTYPE; 1051 Descriptor->SpiSerialBus.TypeDataLength = AML_RESOURCE_SPI_MIN_DATA_LEN + VendorLength; 1052 1053 if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_SPI_SERIALBUS_V2) 1054 { 1055 Descriptor->I2cSerialBus.RevisionId = 2; 1056 } 1057 1058 /* Build pointers to optional areas */ 1059 1060 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, 1061 sizeof (AML_RESOURCE_SPI_SERIALBUS)); 1062 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 1063 1064 /* Process all child initialization nodes */ 1065 1066 for (i = 0; InitializerOp; i++) 1067 { 1068 switch (i) 1069 { 1070 case 0: /* Device Selection [WORD] (_ADR) */ 1071 1072 Descriptor->SpiSerialBus.DeviceSelection = (UINT16) InitializerOp->Asl.Value.Integer; 1073 RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS, 1074 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DeviceSelection)); 1075 break; 1076 1077 case 1: /* Device Polarity [Flag] (_DPL) */ 1078 1079 RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 1, 0); 1080 RsCreateBitField (InitializerOp, ACPI_RESTAG_DEVICEPOLARITY, 1081 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 1); 1082 break; 1083 1084 case 2: /* Wire Mode [Flag] (_MOD) */ 1085 1086 RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 1087 RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE, 1088 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 0); 1089 break; 1090 1091 case 3: /* Device Bit Length [BYTE] (_LEN) */ 1092 1093 Descriptor->SpiSerialBus.DataBitLength = (UINT8) InitializerOp->Asl.Value.Integer; 1094 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH, 1095 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DataBitLength)); 1096 break; 1097 1098 case 4: /* Slave Mode [Flag] (_SLV) */ 1099 1100 RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 0, 0); 1101 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 1102 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 0); 1103 break; 1104 1105 case 5: /* Connection Speed [DWORD] (_SPE) */ 1106 1107 Descriptor->SpiSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer; 1108 RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, 1109 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ConnectionSpeed)); 1110 break; 1111 1112 case 6: /* Clock Polarity [BYTE] (_POL) */ 1113 1114 Descriptor->SpiSerialBus.ClockPolarity = (UINT8) InitializerOp->Asl.Value.Integer; 1115 RsCreateByteField (InitializerOp, ACPI_RESTAG_POLARITY, 1116 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPolarity)); 1117 break; 1118 1119 case 7: /* Clock Phase [BYTE] (_PHA) */ 1120 1121 Descriptor->SpiSerialBus.ClockPhase = (UINT8) InitializerOp->Asl.Value.Integer; 1122 RsCreateByteField (InitializerOp, ACPI_RESTAG_PHASE, 1123 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPhase)); 1124 break; 1125 1126 case 8: /* ResSource [Optional Field - STRING] */ 1127 1128 if (ResSourceLength) 1129 { 1130 /* Copy string to the descriptor */ 1131 1132 strcpy (ResourceSource, 1133 InitializerOp->Asl.Value.String); 1134 } 1135 break; 1136 1137 case 9: /* Resource Index */ 1138 1139 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1140 { 1141 Descriptor->SpiSerialBus.ResSourceIndex = 1142 (UINT8) InitializerOp->Asl.Value.Integer; 1143 } 1144 break; 1145 1146 case 10: /* Resource Usage (consumer/producer) */ 1147 1148 RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 1, 1); 1149 break; 1150 1151 case 11: /* Resource Tag (Descriptor Name) */ 1152 1153 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1154 break; 1155 1156 case 12: 1157 /* 1158 * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor 1159 * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from 1160 * the ASL parser) 1161 */ 1162 RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 2, 0); 1163 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1164 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 2); 1165 break; 1166 1167 case 13: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1168 1169 RsGetVendorData (InitializerOp, VendorData, 1170 CurrentByteOffset + sizeof (AML_RESOURCE_SPI_SERIALBUS)); 1171 break; 1172 1173 default: /* Ignore any extra nodes */ 1174 1175 break; 1176 } 1177 1178 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1179 } 1180 1181 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 1182 return (Rnode); 1183 } 1184 1185 1186 /******************************************************************************* 1187 * 1188 * FUNCTION: RsDoUartSerialBusDescriptor 1189 * 1190 * PARAMETERS: Info - Parse Op and resource template offset 1191 * 1192 * RETURN: Completed resource node 1193 * 1194 * DESCRIPTION: Construct a long "UART Serial Bus" descriptor 1195 * 1196 ******************************************************************************/ 1197 1198 ASL_RESOURCE_NODE * 1199 RsDoUartSerialBusDescriptor ( 1200 ASL_RESOURCE_INFO *Info) 1201 { 1202 AML_RESOURCE *Descriptor; 1203 ACPI_PARSE_OBJECT *InitializerOp; 1204 ASL_RESOURCE_NODE *Rnode; 1205 char *ResourceSource = NULL; 1206 UINT8 *VendorData = NULL; 1207 UINT16 ResSourceLength; 1208 UINT16 VendorLength; 1209 UINT16 DescriptorSize; 1210 UINT32 CurrentByteOffset; 1211 UINT32 i; 1212 1213 1214 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1215 CurrentByteOffset = Info->CurrentByteOffset; 1216 1217 /* 1218 * Calculate lengths for fields that have variable length: 1219 * 1) Resource Source string 1220 * 2) Vendor Data buffer 1221 */ 1222 ResSourceLength = RsGetStringDataLength (InitializerOp); 1223 VendorLength = RsGetBufferDataLength (InitializerOp); 1224 1225 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS) + 1226 ResSourceLength + VendorLength; 1227 1228 /* Allocate the local resource node and initialize */ 1229 1230 Rnode = RsAllocateResourceNode (DescriptorSize + 1231 sizeof (AML_RESOURCE_LARGE_HEADER)); 1232 1233 Descriptor = Rnode->Buffer; 1234 Descriptor->UartSerialBus.ResourceLength = DescriptorSize; 1235 Descriptor->UartSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 1236 Descriptor->UartSerialBus.RevisionId = AML_RESOURCE_UART_REVISION; 1237 Descriptor->UartSerialBus.TypeRevisionId = AML_RESOURCE_UART_TYPE_REVISION; 1238 Descriptor->UartSerialBus.Type = AML_RESOURCE_UART_SERIALBUSTYPE; 1239 Descriptor->UartSerialBus.TypeDataLength = AML_RESOURCE_UART_MIN_DATA_LEN + VendorLength; 1240 1241 if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_UART_SERIALBUS_V2) 1242 { 1243 Descriptor->I2cSerialBus.RevisionId = 2; 1244 } 1245 1246 /* Build pointers to optional areas */ 1247 1248 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_UART_SERIALBUS)); 1249 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 1250 1251 /* Process all child initialization nodes */ 1252 1253 for (i = 0; InitializerOp; i++) 1254 { 1255 switch (i) 1256 { 1257 case 0: /* Connection Speed (Baud Rate) [DWORD] (_SPE) */ 1258 1259 Descriptor->UartSerialBus.DefaultBaudRate = (UINT32) InitializerOp->Asl.Value.Integer; 1260 RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, 1261 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.DefaultBaudRate)); 1262 break; 1263 1264 case 1: /* Bits Per Byte [Flags] (_LEN) */ 1265 1266 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 4, 3); 1267 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LENGTH, 1268 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 4, 3); 1269 break; 1270 1271 case 2: /* Stop Bits [Flags] (_STB) */ 1272 1273 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 2, 1); 1274 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_STOPBITS, 1275 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 2, 2); 1276 break; 1277 1278 case 3: /* Lines In Use [BYTE] (_LIN) */ 1279 1280 Descriptor->UartSerialBus.LinesEnabled = (UINT8) InitializerOp->Asl.Value.Integer; 1281 RsCreateByteField (InitializerOp, ACPI_RESTAG_LINE, 1282 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.LinesEnabled)); 1283 break; 1284 1285 case 4: /* Endianness [Flag] (_END) */ 1286 1287 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 7, 0); 1288 RsCreateBitField (InitializerOp, ACPI_RESTAG_ENDIANNESS, 1289 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 7); 1290 break; 1291 1292 case 5: /* Parity [BYTE] (_PAR) */ 1293 1294 Descriptor->UartSerialBus.Parity = (UINT8) InitializerOp->Asl.Value.Integer; 1295 RsCreateByteField (InitializerOp, ACPI_RESTAG_PARITY, 1296 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Parity)); 1297 break; 1298 1299 case 6: /* Flow Control [Flags] (_FLC) */ 1300 1301 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 1302 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_FLOWCONTROL, 1303 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 0, 2); 1304 break; 1305 1306 case 7: /* Rx Buffer Size [WORD] (_RXL) */ 1307 1308 Descriptor->UartSerialBus.RxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer; 1309 RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_RX, 1310 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.RxFifoSize)); 1311 break; 1312 1313 case 8: /* Tx Buffer Size [WORD] (_TXL) */ 1314 1315 Descriptor->UartSerialBus.TxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer; 1316 RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_TX, 1317 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TxFifoSize)); 1318 break; 1319 1320 case 9: /* ResSource [Optional Field - STRING] */ 1321 1322 if (ResSourceLength) 1323 { 1324 /* Copy string to the descriptor */ 1325 1326 strcpy (ResourceSource, 1327 InitializerOp->Asl.Value.String); 1328 } 1329 break; 1330 1331 case 10: /* Resource Index */ 1332 1333 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1334 { 1335 Descriptor->UartSerialBus.ResSourceIndex = 1336 (UINT8) InitializerOp->Asl.Value.Integer; 1337 } 1338 break; 1339 1340 case 11: /* Resource Usage (consumer/producer) */ 1341 1342 RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 1, 1); 1343 1344 /* 1345 * Slave Mode [Flag] (_SLV) 1346 * 1347 * Note: There is no SlaveMode argument to the UartSerialBus macro, but 1348 * we add this name anyway to allow the flag to be set by ASL in the 1349 * rare case where there is a slave mode associated with the UART. 1350 */ 1351 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 1352 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 0); 1353 break; 1354 1355 case 12: /* Resource Tag (Descriptor Name) */ 1356 1357 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1358 break; 1359 1360 case 13: 1361 /* 1362 * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor 1363 * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from 1364 * the ASL parser) 1365 */ 1366 RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 2, 0); 1367 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1368 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 2); 1369 break; 1370 1371 case 14: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1372 1373 RsGetVendorData (InitializerOp, VendorData, 1374 CurrentByteOffset + sizeof (AML_RESOURCE_UART_SERIALBUS)); 1375 break; 1376 1377 default: /* Ignore any extra nodes */ 1378 1379 break; 1380 } 1381 1382 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1383 } 1384 1385 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 1386 return (Rnode); 1387 } 1388 1389 1390 /******************************************************************************* 1391 * 1392 * FUNCTION: RsDoCsi2SerialBusDescriptor 1393 * 1394 * PARAMETERS: Info - Parse Op and resource template offset 1395 * 1396 * RETURN: Completed resource node 1397 * 1398 * DESCRIPTION: Construct a long "Csi2SerialBus" descriptor 1399 * 1400 ******************************************************************************/ 1401 1402 ASL_RESOURCE_NODE * 1403 RsDoCsi2SerialBusDescriptor ( 1404 ASL_RESOURCE_INFO *Info) 1405 { 1406 AML_RESOURCE *Descriptor; 1407 ACPI_PARSE_OBJECT *InitializerOp; 1408 ASL_RESOURCE_NODE *Rnode; 1409 char *ResourceSource = NULL; 1410 UINT8 *VendorData = NULL; 1411 UINT16 ResSourceLength; 1412 UINT16 VendorLength; 1413 UINT16 DescriptorSize; 1414 UINT32 CurrentByteOffset; 1415 UINT32 i; 1416 1417 1418 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1419 CurrentByteOffset = Info->CurrentByteOffset; 1420 1421 /* 1422 * Calculate lengths for fields that have variable length: 1423 * 1) Resource Source string 1424 * 2) Vendor Data buffer 1425 */ 1426 ResSourceLength = RsGetStringDataLength (InitializerOp); 1427 VendorLength = RsGetBufferDataLength (InitializerOp); 1428 1429 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_CSI2_SERIALBUS) + 1430 ResSourceLength + VendorLength; 1431 1432 /* Allocate the local resource node and initialize */ 1433 1434 Rnode = RsAllocateResourceNode (DescriptorSize + 1435 sizeof (AML_RESOURCE_LARGE_HEADER)); 1436 1437 Descriptor = Rnode->Buffer; 1438 Descriptor->Csi2SerialBus.ResourceLength = DescriptorSize; 1439 Descriptor->Csi2SerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 1440 Descriptor->Csi2SerialBus.RevisionId = AML_RESOURCE_CSI2_REVISION; 1441 Descriptor->Csi2SerialBus.TypeRevisionId = AML_RESOURCE_CSI2_TYPE_REVISION; 1442 Descriptor->Csi2SerialBus.Type = AML_RESOURCE_CSI2_SERIALBUSTYPE; 1443 Descriptor->Csi2SerialBus.TypeDataLength = AML_RESOURCE_CSI2_MIN_DATA_LEN + VendorLength; 1444 1445 /* Build pointers to optional areas */ 1446 1447 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_CSI2_SERIALBUS)); 1448 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 1449 1450 /* Process all child initialization nodes */ 1451 1452 for (i = 0; InitializerOp; i++) 1453 { 1454 switch (i) 1455 { 1456 case 0: /* Slave Mode [Flag] (_SLV) */ 1457 1458 RsSetFlagBits (&Descriptor->Csi2SerialBus.Flags, InitializerOp, 0, 0); 1459 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 1460 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0); 1461 break; 1462 1463 case 1: /* Phy Type [Flag] (_PHY) */ 1464 1465 RsSetFlagBits16 ((UINT16 *) &Descriptor->Csi2SerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 1466 RsCreateBitField (InitializerOp, ACPI_RESTAG_PHYTYPE, 1467 CurrentByteOffset + ASL_RESDESC_OFFSET (Csi2SerialBus.TypeSpecificFlags), 0); 1468 break; 1469 1470 case 2: /* Local Port Instance [Integer] (_PRT) */ 1471 1472 RsSetFlagBits16 ((UINT16 *) &Descriptor->Csi2SerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 1473 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LOCALPORT, 1474 CurrentByteOffset + ASL_RESDESC_OFFSET (Csi2SerialBus.TypeSpecificFlags), 2, 6); 1475 break; 1476 1477 case 3: /* ResSource [Optional Field - STRING] */ 1478 1479 if (ResSourceLength) 1480 { 1481 /* Copy string to the descriptor */ 1482 1483 strcpy (ResourceSource, 1484 InitializerOp->Asl.Value.String); 1485 } 1486 break; 1487 1488 case 4: /* Resource Index */ 1489 1490 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1491 { 1492 Descriptor->Csi2SerialBus.ResSourceIndex = 1493 (UINT8) InitializerOp->Asl.Value.Integer; 1494 } 1495 break; 1496 1497 case 5: /* Resource Usage (consumer/producer) */ 1498 1499 RsSetFlagBits (&Descriptor->Csi2SerialBus.Flags, InitializerOp, 1, 1); 1500 break; 1501 1502 case 6: /* Resource Tag (Descriptor Name) */ 1503 1504 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1505 break; 1506 1507 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1508 1509 RsGetVendorData (InitializerOp, VendorData, 1510 CurrentByteOffset + sizeof (AML_RESOURCE_CSI2_SERIALBUS)); 1511 break; 1512 1513 default: /* Ignore any extra nodes */ 1514 1515 break; 1516 } 1517 1518 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1519 } 1520 1521 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 1522 return (Rnode); 1523 } 1524 1525 1526 /******************************************************************************* 1527 * 1528 * FUNCTION: RsDoPinFunctionDescriptor 1529 * 1530 * PARAMETERS: Info - Parse Op and resource template offset 1531 * 1532 * RETURN: Completed resource node 1533 * 1534 * DESCRIPTION: Construct a long "PinFunction" descriptor 1535 * 1536 ******************************************************************************/ 1537 1538 ASL_RESOURCE_NODE * 1539 RsDoPinFunctionDescriptor ( 1540 ASL_RESOURCE_INFO *Info) 1541 { 1542 AML_RESOURCE *Descriptor; 1543 ACPI_PARSE_OBJECT *InitializerOp; 1544 ASL_RESOURCE_NODE *Rnode; 1545 char *ResourceSource = NULL; 1546 UINT8 *VendorData = NULL; 1547 UINT16 *PinList = NULL; 1548 UINT16 ResSourceLength; 1549 UINT16 VendorLength; 1550 UINT16 PinListLength; 1551 UINT16 DescriptorSize; 1552 UINT32 CurrentByteOffset; 1553 UINT32 i; 1554 1555 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1556 CurrentByteOffset = Info->CurrentByteOffset; 1557 1558 /* 1559 * Calculate lengths for fields that have variable length: 1560 * 1) Resource Source string 1561 * 2) Vendor Data buffer 1562 * 3) PIN (interrupt) list 1563 */ 1564 ResSourceLength = RsGetStringDataLength (InitializerOp); 1565 VendorLength = RsGetBufferDataLength (InitializerOp); 1566 PinListLength = RsGetInterruptDataLength (InitializerOp, 8); 1567 1568 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_FUNCTION) + 1569 ResSourceLength + VendorLength + PinListLength; 1570 1571 /* Allocate the local resource node and initialize */ 1572 1573 Rnode = RsAllocateResourceNode (DescriptorSize + 1574 sizeof (AML_RESOURCE_LARGE_HEADER)); 1575 1576 Descriptor = Rnode->Buffer; 1577 Descriptor->PinFunction.ResourceLength = DescriptorSize; 1578 Descriptor->PinFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_FUNCTION; 1579 Descriptor->PinFunction.RevisionId = AML_RESOURCE_PIN_FUNCTION_REVISION; 1580 1581 /* Build pointers to optional areas */ 1582 1583 PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_FUNCTION)); 1584 ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength); 1585 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 1586 1587 /* Setup offsets within the descriptor */ 1588 1589 Descriptor->PinFunction.PinTableOffset = (UINT16) 1590 ACPI_PTR_DIFF (PinList, Descriptor); 1591 1592 Descriptor->PinFunction.ResSourceOffset = (UINT16) 1593 ACPI_PTR_DIFF (ResourceSource, Descriptor); 1594 1595 /* Process all child initialization nodes */ 1596 1597 for (i = 0; InitializerOp; i++) 1598 { 1599 switch (i) 1600 { 1601 case 0: /* Share Type [Flags] (_SHR) */ 1602 1603 RsSetFlagBits16 (&Descriptor->PinFunction.Flags, InitializerOp, 0, 0); 1604 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1605 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.Flags), 0); 1606 break; 1607 1608 case 1: /* Pin Config [BYTE] (_PPI) */ 1609 1610 Descriptor->PinFunction.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer; 1611 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG, 1612 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.PinConfig)); 1613 break; 1614 1615 case 2: /* Function Number [WORD] (_FUN) */ 1616 1617 Descriptor->PinFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer; 1618 RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION, 1619 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.FunctionNumber)); 1620 break; 1621 1622 case 3: /* ResSource [Optional Field - STRING] */ 1623 1624 if (ResSourceLength) 1625 { 1626 /* Copy string to the descriptor */ 1627 1628 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 1629 } 1630 break; 1631 1632 case 4: /* Resource Index */ 1633 1634 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1635 { 1636 Descriptor->PinFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 1637 } 1638 break; 1639 1640 case 5: /* Resource Usage (consumer/producer) */ 1641 1642 /* Assumed to be consumer */ 1643 1644 break; 1645 1646 case 6: /* Resource Tag (Descriptor Name) */ 1647 1648 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1649 break; 1650 1651 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1652 /* 1653 * Always set the VendorOffset even if there is no Vendor Data. 1654 * This field is required in order to calculate the length 1655 * of the ResourceSource at runtime. 1656 */ 1657 Descriptor->PinFunction.VendorOffset = (UINT16) 1658 ACPI_PTR_DIFF (VendorData, Descriptor); 1659 1660 if (RsGetVendorData (InitializerOp, VendorData, 1661 (CurrentByteOffset + Descriptor->PinFunction.VendorOffset))) 1662 { 1663 Descriptor->PinFunction.VendorLength = VendorLength; 1664 } 1665 break; 1666 1667 default: 1668 /* 1669 * PINs come through here, repeatedly. Each PIN must be a WORD. 1670 * Name: _PIN 1671 */ 1672 *PinList = (UINT16) InitializerOp->Asl.Value.Integer; 1673 PinList++; 1674 1675 /* Case 8: First pin number in list */ 1676 1677 if (i == 8) 1678 { 1679 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1680 { 1681 /* Must be at least one interrupt */ 1682 1683 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 1684 InitializerOp, NULL); 1685 } 1686 1687 /* Check now for duplicates in list */ 1688 1689 RsCheckListForDuplicates (InitializerOp); 1690 1691 /* Create a named field at the start of the list */ 1692 1693 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 1694 CurrentByteOffset + Descriptor->PinFunction.PinTableOffset); 1695 } 1696 break; 1697 } 1698 1699 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1700 } 1701 1702 return (Rnode); 1703 } 1704 1705 /******************************************************************************* 1706 * 1707 * FUNCTION: RsDoClockInputDescriptor 1708 * 1709 * PARAMETERS: Info - Parse Op and resource template offset 1710 * 1711 * RETURN: Completed resource node 1712 * 1713 * DESCRIPTION: Construct a long "ClockInput" descriptor 1714 * 1715 ******************************************************************************/ 1716 1717 ASL_RESOURCE_NODE * 1718 RsDoClockInputDescriptor ( 1719 ASL_RESOURCE_INFO *Info) 1720 { 1721 AML_RESOURCE *Descriptor; 1722 ACPI_PARSE_OBJECT *InitializerOp; 1723 ASL_RESOURCE_NODE *Rnode; 1724 char *ResourceSourceString = NULL; 1725 UINT8 *ResourceSourceIndex = NULL; 1726 UINT16 ResSourceLength; 1727 UINT16 DescriptorSize; 1728 UINT32 i; 1729 UINT32 CurrentByteOffset; 1730 1731 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1732 CurrentByteOffset = Info->CurrentByteOffset; 1733 1734 /* 1735 * Calculate lengths for fields that have variable length: 1736 * 1) Resource Source string 1737 */ 1738 ResSourceLength = RsGetStringDataLength (InitializerOp); 1739 1740 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_CLOCK_INPUT) + ResSourceLength + 1; 1741 1742 /* Allocate the local resource node and initialize */ 1743 1744 Rnode = RsAllocateResourceNode (DescriptorSize + 1745 sizeof (AML_RESOURCE_LARGE_HEADER)); 1746 1747 Descriptor = Rnode->Buffer; 1748 Descriptor->ClockInput.ResourceLength = DescriptorSize; 1749 Descriptor->ClockInput.DescriptorType = ACPI_RESOURCE_NAME_CLOCK_INPUT; 1750 Descriptor->ClockInput.RevisionId = AML_RESOURCE_CLOCK_INPUT_REVISION; 1751 1752 /* Build pointers to optional areas */ 1753 1754 if (ResSourceLength){ 1755 ResourceSourceIndex = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_CLOCK_INPUT)); 1756 ResourceSourceString = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_CLOCK_INPUT) + 1); 1757 } 1758 1759 /* Process all child initialization nodes */ 1760 1761 for (i = 0; InitializerOp; i++) 1762 { 1763 switch (i) 1764 { 1765 case 0: 1766 Descriptor->ClockInput.FrequencyNumerator = (UINT32)InitializerOp->Asl.Value.Integer; 1767 RsCreateDwordField (InitializerOp, ACPI_RESTAG_FQN, 1768 CurrentByteOffset + ASL_RESDESC_OFFSET (ClockInput.FrequencyNumerator)); 1769 1770 break; 1771 1772 case 1: 1773 Descriptor->ClockInput.FrequencyDivisor = (UINT16)InitializerOp->Asl.Value.Integer; 1774 RsCreateWordField (InitializerOp, ACPI_RESTAG_FQD, 1775 CurrentByteOffset + ASL_RESDESC_OFFSET (ClockInput.FrequencyDivisor)); 1776 1777 break; 1778 1779 case 2: 1780 RsSetFlagBits16 (&Descriptor->ClockInput.Flags, InitializerOp, 1, 0); 1781 break; 1782 1783 case 3: 1784 RsSetFlagBits16 (&Descriptor->ClockInput.Flags, InitializerOp, 0, 0); 1785 break; 1786 1787 case 4: /* ResSource String [Optional Field] */ 1788 1789 if (ResourceSourceString) 1790 { 1791 /* Copy string to the descriptor */ 1792 1793 strcpy (ResourceSourceString, InitializerOp->Asl.Value.String); 1794 } 1795 break; 1796 1797 case 5: /* ResSource Index [Optional Field] */ 1798 if (ResourceSourceIndex) 1799 { 1800 *ResourceSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 1801 } 1802 break; 1803 1804 default: 1805 break; 1806 } 1807 1808 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1809 } 1810 1811 return (Rnode); 1812 } 1813 1814 1815 /******************************************************************************* 1816 * 1817 * FUNCTION: RsDoPinConfigDescriptor 1818 * 1819 * PARAMETERS: Info - Parse Op and resource template offset 1820 * 1821 * RETURN: Completed resource node 1822 * 1823 * DESCRIPTION: Construct a long "PinConfig" descriptor 1824 * 1825 ******************************************************************************/ 1826 1827 ASL_RESOURCE_NODE * 1828 RsDoPinConfigDescriptor ( 1829 ASL_RESOURCE_INFO *Info) 1830 { 1831 AML_RESOURCE *Descriptor; 1832 ACPI_PARSE_OBJECT *InitializerOp; 1833 ASL_RESOURCE_NODE *Rnode; 1834 char *ResourceSource = NULL; 1835 UINT8 *VendorData = NULL; 1836 UINT16 *PinList = NULL; 1837 UINT16 ResSourceLength; 1838 UINT16 VendorLength; 1839 UINT16 PinListLength; 1840 UINT16 DescriptorSize; 1841 UINT32 CurrentByteOffset; 1842 UINT32 i; 1843 1844 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1845 CurrentByteOffset = Info->CurrentByteOffset; 1846 1847 /* 1848 * Calculate lengths for fields that have variable length: 1849 * 1) Resource Source string 1850 * 2) Vendor Data buffer 1851 * 3) PIN (interrupt) list 1852 */ 1853 ResSourceLength = RsGetStringDataLength (InitializerOp); 1854 VendorLength = RsGetBufferDataLength (InitializerOp); 1855 PinListLength = RsGetInterruptDataLength (InitializerOp, 8); 1856 1857 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_CONFIG) + 1858 ResSourceLength + VendorLength + PinListLength; 1859 1860 /* Allocate the local resource node and initialize */ 1861 1862 Rnode = RsAllocateResourceNode (DescriptorSize + 1863 sizeof (AML_RESOURCE_LARGE_HEADER)); 1864 1865 Descriptor = Rnode->Buffer; 1866 Descriptor->PinConfig.ResourceLength = DescriptorSize; 1867 Descriptor->PinConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_CONFIG; 1868 Descriptor->PinConfig.RevisionId = AML_RESOURCE_PIN_CONFIG_REVISION; 1869 1870 /* Build pointers to optional areas */ 1871 1872 PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_CONFIG)); 1873 ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength); 1874 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 1875 1876 /* Setup offsets within the descriptor */ 1877 1878 Descriptor->PinConfig.PinTableOffset = (UINT16) 1879 ACPI_PTR_DIFF (PinList, Descriptor); 1880 1881 Descriptor->PinConfig.ResSourceOffset = (UINT16) 1882 ACPI_PTR_DIFF (ResourceSource, Descriptor); 1883 1884 /* Process all child initialization nodes */ 1885 1886 for (i = 0; InitializerOp; i++) 1887 { 1888 BOOLEAN isValid; 1889 1890 switch (i) 1891 { 1892 case 0: /* Share Type [Flags] (_SHR) */ 1893 1894 RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 0, 0); 1895 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1896 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.Flags), 0); 1897 break; 1898 1899 case 1: /* Pin Config Type [BYTE] (_TYP) */ 1900 1901 isValid = InitializerOp->Asl.Value.Integer <= 0x0d; 1902 if (!isValid) 1903 { 1904 isValid = InitializerOp->Asl.Value.Integer >= 0x80 && 1905 InitializerOp->Asl.Value.Integer <= 0xff; 1906 } 1907 if (!isValid) 1908 { 1909 AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL); 1910 } 1911 1912 Descriptor->PinConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer; 1913 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE, 1914 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigType)); 1915 1916 break; 1917 1918 case 2: /* Pin Config Value [DWORD] (_VAL) */ 1919 1920 Descriptor->PinConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer; 1921 RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE, 1922 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigValue)); 1923 break; 1924 1925 case 3: /* ResSource [Optional Field - STRING] */ 1926 1927 if (ResSourceLength) 1928 { 1929 /* Copy string to the descriptor */ 1930 1931 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 1932 } 1933 break; 1934 1935 case 4: /* Resource Index */ 1936 1937 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1938 { 1939 Descriptor->PinConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 1940 } 1941 break; 1942 1943 case 5: /* Resource Usage (consumer/producer) */ 1944 1945 RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 1, 1); 1946 1947 break; 1948 1949 case 6: /* Resource Tag (Descriptor Name) */ 1950 1951 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1952 break; 1953 1954 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1955 /* 1956 * Always set the VendorOffset even if there is no Vendor Data. 1957 * This field is required in order to calculate the length 1958 * of the ResourceSource at runtime. 1959 */ 1960 Descriptor->PinConfig.VendorOffset = (UINT16) 1961 ACPI_PTR_DIFF (VendorData, Descriptor); 1962 1963 if (RsGetVendorData (InitializerOp, VendorData, 1964 (CurrentByteOffset + Descriptor->PinConfig.VendorOffset))) 1965 { 1966 Descriptor->PinConfig.VendorLength = VendorLength; 1967 } 1968 break; 1969 1970 default: 1971 /* 1972 * PINs come through here, repeatedly. Each PIN must be a WORD. 1973 * Name: _PIN 1974 */ 1975 *PinList = (UINT16) InitializerOp->Asl.Value.Integer; 1976 PinList++; 1977 1978 /* Case 8: First pin number in list */ 1979 1980 if (i == 8) 1981 { 1982 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1983 { 1984 /* Must be at least one interrupt */ 1985 1986 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 1987 InitializerOp, NULL); 1988 } 1989 1990 /* Check now for duplicates in list */ 1991 1992 RsCheckListForDuplicates (InitializerOp); 1993 1994 /* Create a named field at the start of the list */ 1995 1996 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 1997 CurrentByteOffset + Descriptor->PinConfig.PinTableOffset); 1998 } 1999 break; 2000 } 2001 2002 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 2003 } 2004 2005 return (Rnode); 2006 } 2007 2008 2009 /******************************************************************************* 2010 * 2011 * FUNCTION: RsDoPinGroupDescriptor 2012 * 2013 * PARAMETERS: Info - Parse Op and resource template offset 2014 * 2015 * RETURN: Completed resource node 2016 * 2017 * DESCRIPTION: Construct a long "PinGroup" descriptor 2018 * 2019 ******************************************************************************/ 2020 2021 ASL_RESOURCE_NODE * 2022 RsDoPinGroupDescriptor ( 2023 ASL_RESOURCE_INFO *Info) 2024 { 2025 AML_RESOURCE *Descriptor; 2026 ACPI_PARSE_OBJECT *InitializerOp; 2027 ASL_RESOURCE_NODE *Rnode; 2028 UINT8 *VendorData = NULL; 2029 UINT16 *PinList = NULL; 2030 char *Label = NULL; 2031 UINT16 LabelLength; 2032 UINT16 VendorLength; 2033 UINT16 PinListLength; 2034 UINT16 DescriptorSize; 2035 UINT32 CurrentByteOffset; 2036 UINT32 i; 2037 2038 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 2039 CurrentByteOffset = Info->CurrentByteOffset; 2040 2041 /* 2042 * Calculate lengths for fields that have variable length: 2043 * 1) Label 2044 * 2) Vendor Data buffer 2045 * 3) PIN (interrupt) list 2046 */ 2047 LabelLength = RsGetStringDataLength (InitializerOp); 2048 VendorLength = RsGetBufferDataLength (InitializerOp); 2049 PinListLength = RsGetInterruptDataLength (InitializerOp, 4); 2050 2051 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP) + 2052 LabelLength + VendorLength + PinListLength; 2053 2054 /* Allocate the local resource node and initialize */ 2055 2056 Rnode = RsAllocateResourceNode (DescriptorSize + 2057 sizeof (AML_RESOURCE_LARGE_HEADER)); 2058 2059 Descriptor = Rnode->Buffer; 2060 Descriptor->PinGroup.ResourceLength = DescriptorSize; 2061 Descriptor->PinGroup.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP; 2062 Descriptor->PinGroup.RevisionId = AML_RESOURCE_PIN_GROUP_REVISION; 2063 2064 /* Build pointers to optional areas */ 2065 2066 PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP)); 2067 Label = ACPI_ADD_PTR (char, PinList, PinListLength); 2068 VendorData = ACPI_ADD_PTR (UINT8, Label, LabelLength); 2069 2070 /* Setup offsets within the descriptor */ 2071 2072 Descriptor->PinGroup.PinTableOffset = (UINT16) ACPI_PTR_DIFF (PinList, Descriptor); 2073 Descriptor->PinGroup.LabelOffset = (UINT16) ACPI_PTR_DIFF (Label, Descriptor); 2074 2075 /* Process all child initialization nodes */ 2076 2077 for (i = 0; InitializerOp; i++) 2078 { 2079 switch (i) 2080 { 2081 case 0: /* Resource Label */ 2082 2083 if (LabelLength < 2) 2084 { 2085 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL); 2086 } 2087 strcpy (Label, InitializerOp->Asl.Value.String); 2088 2089 break; 2090 2091 case 1: /* Resource Usage (consumer/producer) */ 2092 2093 RsSetFlagBits16 (&Descriptor->PinGroup.Flags, InitializerOp, 0, 0); 2094 2095 break; 2096 2097 case 2: /* Resource Tag (Descriptor Name) */ 2098 2099 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 2100 break; 2101 2102 case 3: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 2103 /* 2104 * Always set the VendorOffset even if there is no Vendor Data. 2105 * This field is required in order to calculate the length 2106 * of the ResourceSource at runtime. 2107 */ 2108 Descriptor->PinGroup.VendorOffset = (UINT16) 2109 ACPI_PTR_DIFF (VendorData, Descriptor); 2110 2111 if (RsGetVendorData (InitializerOp, VendorData, 2112 (CurrentByteOffset + Descriptor->PinGroup.VendorOffset))) 2113 { 2114 Descriptor->PinGroup.VendorLength = VendorLength; 2115 } 2116 break; 2117 2118 default: 2119 /* 2120 * PINs come through here, repeatedly. Each PIN must be a WORD. 2121 * Name: _PIN 2122 */ 2123 *PinList = (UINT16) InitializerOp->Asl.Value.Integer; 2124 PinList++; 2125 2126 /* Case 3: First pin number in list */ 2127 2128 if (i == 4) 2129 { 2130 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 2131 { 2132 /* Must be at least one interrupt */ 2133 2134 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 2135 InitializerOp, NULL); 2136 } 2137 2138 /* Check now for duplicates in list */ 2139 2140 RsCheckListForDuplicates (InitializerOp); 2141 2142 /* Create a named field at the start of the list */ 2143 2144 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 2145 CurrentByteOffset + Descriptor->PinGroup.PinTableOffset); 2146 } 2147 break; 2148 } 2149 2150 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 2151 } 2152 2153 return (Rnode); 2154 } 2155 2156 2157 /******************************************************************************* 2158 * 2159 * FUNCTION: RsDoPinGroupFunctionDescriptor 2160 * 2161 * PARAMETERS: Info - Parse Op and resource template offset 2162 * 2163 * RETURN: Completed resource node 2164 * 2165 * DESCRIPTION: Construct a long "PinGroupFunction" descriptor 2166 * 2167 ******************************************************************************/ 2168 2169 ASL_RESOURCE_NODE * 2170 RsDoPinGroupFunctionDescriptor ( 2171 ASL_RESOURCE_INFO *Info) 2172 { 2173 AML_RESOURCE *Descriptor; 2174 ACPI_PARSE_OBJECT *InitializerOp; 2175 ASL_RESOURCE_NODE *Rnode; 2176 char *ResourceSource = NULL; 2177 char *ResourceSourceLabel = NULL; 2178 UINT8 *VendorData = NULL; 2179 UINT16 ResSourceLength; 2180 UINT16 ResSourceLabelLength; 2181 UINT16 VendorLength; 2182 UINT16 DescriptorSize; 2183 UINT32 CurrentByteOffset; 2184 UINT32 i; 2185 2186 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 2187 CurrentByteOffset = Info->CurrentByteOffset; 2188 2189 /* 2190 * Calculate lengths for fields that have variable length: 2191 * 1) Resource Source string 2192 * 2) Resource Source Label string 2193 * 3) Vendor Data buffer 2194 */ 2195 ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 2); 2196 ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 4); 2197 VendorLength = RsGetBufferDataLength (InitializerOp); 2198 2199 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_FUNCTION) + 2200 ResSourceLength + ResSourceLabelLength + VendorLength; 2201 2202 /* Allocate the local resource node and initialize */ 2203 2204 Rnode = RsAllocateResourceNode (DescriptorSize + 2205 sizeof (AML_RESOURCE_LARGE_HEADER)); 2206 2207 Descriptor = Rnode->Buffer; 2208 Descriptor->PinGroupFunction.ResourceLength = DescriptorSize; 2209 Descriptor->PinGroupFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION; 2210 Descriptor->PinGroupFunction.RevisionId = AML_RESOURCE_PIN_GROUP_FUNCTION_REVISION; 2211 2212 /* Build pointers to optional areas */ 2213 2214 ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_FUNCTION)); 2215 ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength); 2216 VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength); 2217 2218 /* Setup offsets within the descriptor */ 2219 2220 Descriptor->PinGroupFunction.ResSourceOffset = (UINT16) 2221 ACPI_PTR_DIFF (ResourceSource, Descriptor); 2222 Descriptor->PinGroupFunction.ResSourceLabelOffset = (UINT16) 2223 ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor); 2224 2225 /* Process all child initialization nodes */ 2226 2227 for (i = 0; InitializerOp; i++) 2228 { 2229 switch (i) 2230 { 2231 case 0: /* Share Type [Flags] (_SHR) */ 2232 2233 RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 0, 0); 2234 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 2235 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.Flags), 0); 2236 break; 2237 2238 case 1: /* Function Number [WORD] */ 2239 2240 Descriptor->PinGroupFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer; 2241 RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION, 2242 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.FunctionNumber)); 2243 break; 2244 2245 case 2: /* ResourceSource [STRING] */ 2246 2247 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 2248 break; 2249 2250 case 3: /* Resource Index */ 2251 2252 Descriptor->PinGroupFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 2253 break; 2254 2255 case 4: /* ResourceSourceLabel [STRING] */ 2256 2257 if (ResSourceLabelLength < 2) 2258 { 2259 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL); 2260 } 2261 2262 strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String); 2263 break; 2264 2265 case 5: /* Resource Usage (consumer/producer) */ 2266 2267 RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 1, 1); 2268 2269 break; 2270 2271 case 6: /* Resource Tag (Descriptor Name) */ 2272 2273 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 2274 break; 2275 2276 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 2277 /* 2278 * Always set the VendorOffset even if there is no Vendor Data. 2279 * This field is required in order to calculate the length 2280 * of the ResourceSource at runtime. 2281 */ 2282 Descriptor->PinGroupFunction.VendorOffset = (UINT16) 2283 ACPI_PTR_DIFF (VendorData, Descriptor); 2284 2285 if (RsGetVendorData (InitializerOp, VendorData, 2286 (CurrentByteOffset + Descriptor->PinGroupFunction.VendorOffset))) 2287 { 2288 Descriptor->PinGroupFunction.VendorLength = VendorLength; 2289 } 2290 break; 2291 2292 default: 2293 break; 2294 } 2295 2296 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 2297 } 2298 2299 return (Rnode); 2300 } 2301 2302 2303 /******************************************************************************* 2304 * 2305 * FUNCTION: RsDoPinGroupConfigDescriptor 2306 * 2307 * PARAMETERS: Info - Parse Op and resource template offset 2308 * 2309 * RETURN: Completed resource node 2310 * 2311 * DESCRIPTION: Construct a long "PinGroupConfig" descriptor 2312 * 2313 ******************************************************************************/ 2314 2315 ASL_RESOURCE_NODE * 2316 RsDoPinGroupConfigDescriptor ( 2317 ASL_RESOURCE_INFO *Info) 2318 { 2319 AML_RESOURCE *Descriptor; 2320 ACPI_PARSE_OBJECT *InitializerOp; 2321 ASL_RESOURCE_NODE *Rnode; 2322 char *ResourceSource = NULL; 2323 char *ResourceSourceLabel = NULL; 2324 UINT8 *VendorData = NULL; 2325 UINT16 ResSourceLength; 2326 UINT16 ResSourceLabelLength; 2327 UINT16 VendorLength; 2328 UINT16 DescriptorSize; 2329 UINT32 CurrentByteOffset; 2330 UINT32 i; 2331 2332 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 2333 CurrentByteOffset = Info->CurrentByteOffset; 2334 2335 /* 2336 * Calculate lengths for fields that have variable length: 2337 * 1) Resource Source string 2338 * 2) Resource Source Label string 2339 * 3) Vendor Data buffer 2340 */ 2341 ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 3); 2342 ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 5); 2343 VendorLength = RsGetBufferDataLength (InitializerOp); 2344 2345 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_CONFIG) + 2346 ResSourceLength + ResSourceLabelLength + VendorLength; 2347 2348 /* Allocate the local resource node and initialize */ 2349 2350 Rnode = RsAllocateResourceNode (DescriptorSize + 2351 sizeof (AML_RESOURCE_LARGE_HEADER)); 2352 2353 Descriptor = Rnode->Buffer; 2354 Descriptor->PinGroupConfig.ResourceLength = DescriptorSize; 2355 Descriptor->PinGroupConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG; 2356 Descriptor->PinGroupConfig.RevisionId = AML_RESOURCE_PIN_GROUP_CONFIG_REVISION; 2357 2358 /* Build pointers to optional areas */ 2359 2360 ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_CONFIG)); 2361 ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength); 2362 VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength); 2363 2364 /* Setup offsets within the descriptor */ 2365 2366 Descriptor->PinGroupConfig.ResSourceOffset = (UINT16) 2367 ACPI_PTR_DIFF (ResourceSource, Descriptor); 2368 Descriptor->PinGroupConfig.ResSourceLabelOffset = (UINT16) 2369 ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor); 2370 2371 /* Process all child initialization nodes */ 2372 2373 for (i = 0; InitializerOp; i++) 2374 { 2375 BOOLEAN isValid; 2376 2377 switch (i) 2378 { 2379 case 0: /* Share Type [Flags] (_SHR) */ 2380 2381 RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 0, 0); 2382 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 2383 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.Flags), 0); 2384 break; 2385 2386 case 1: /* Pin Config Type [BYTE] (_TYP) */ 2387 2388 isValid = InitializerOp->Asl.Value.Integer <= 0x0d; 2389 if (!isValid) 2390 { 2391 isValid = InitializerOp->Asl.Value.Integer >= 0x80 && 2392 InitializerOp->Asl.Value.Integer <= 0xff; 2393 } 2394 if (!isValid) 2395 { 2396 AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL); 2397 } 2398 2399 Descriptor->PinGroupConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer; 2400 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE, 2401 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigType)); 2402 2403 break; 2404 2405 case 2: /* Pin Config Value [DWORD] (_VAL) */ 2406 2407 Descriptor->PinGroupConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer; 2408 RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE, 2409 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigValue)); 2410 break; 2411 2412 case 3: /* ResourceSource [STRING] */ 2413 2414 /* Copy string to the descriptor */ 2415 2416 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 2417 break; 2418 2419 case 4: /* Resource Index */ 2420 2421 Descriptor->PinGroupConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 2422 break; 2423 2424 case 5: /* ResourceSourceLabel [STRING] */ 2425 2426 if (ResSourceLabelLength < 2) 2427 { 2428 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL); 2429 } 2430 2431 strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String); 2432 break; 2433 2434 case 6: /* Resource Usage (consumer/producer) */ 2435 2436 RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 1, 1); 2437 2438 break; 2439 2440 case 7: /* Resource Tag (Descriptor Name) */ 2441 2442 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 2443 break; 2444 2445 case 8: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 2446 /* 2447 * Always set the VendorOffset even if there is no Vendor Data. 2448 * This field is required in order to calculate the length 2449 * of the ResourceSource at runtime. 2450 */ 2451 Descriptor->PinGroupConfig.VendorOffset = (UINT16) 2452 ACPI_PTR_DIFF (VendorData, Descriptor); 2453 2454 if (RsGetVendorData (InitializerOp, VendorData, 2455 (CurrentByteOffset + Descriptor->PinGroupConfig.VendorOffset))) 2456 { 2457 Descriptor->PinGroupConfig.VendorLength = VendorLength; 2458 } 2459 break; 2460 2461 default: 2462 break; 2463 } 2464 2465 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 2466 } 2467 2468 return (Rnode); 2469 } 2470