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 - 2021, 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 "aslcompiler.h" 153 #include "aslcompiler.y.h" 154 #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: RsDoPinFunctionDescriptor 1393 * 1394 * PARAMETERS: Info - Parse Op and resource template offset 1395 * 1396 * RETURN: Completed resource node 1397 * 1398 * DESCRIPTION: Construct a long "PinFunction" descriptor 1399 * 1400 ******************************************************************************/ 1401 1402 ASL_RESOURCE_NODE * 1403 RsDoPinFunctionDescriptor ( 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 *PinList = NULL; 1412 UINT16 ResSourceLength; 1413 UINT16 VendorLength; 1414 UINT16 PinListLength; 1415 UINT16 DescriptorSize; 1416 UINT32 CurrentByteOffset; 1417 UINT32 PinCount = 0; 1418 UINT32 i; 1419 1420 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1421 CurrentByteOffset = Info->CurrentByteOffset; 1422 1423 /* 1424 * Calculate lengths for fields that have variable length: 1425 * 1) Resource Source string 1426 * 2) Vendor Data buffer 1427 * 3) PIN (interrupt) list 1428 */ 1429 ResSourceLength = RsGetStringDataLength (InitializerOp); 1430 VendorLength = RsGetBufferDataLength (InitializerOp); 1431 PinListLength = RsGetInterruptDataLength (InitializerOp, 8); 1432 1433 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_FUNCTION) + 1434 ResSourceLength + VendorLength + PinListLength; 1435 1436 /* Allocate the local resource node and initialize */ 1437 1438 Rnode = RsAllocateResourceNode (DescriptorSize + 1439 sizeof (AML_RESOURCE_LARGE_HEADER)); 1440 1441 Descriptor = Rnode->Buffer; 1442 Descriptor->PinFunction.ResourceLength = DescriptorSize; 1443 Descriptor->PinFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_FUNCTION; 1444 Descriptor->PinFunction.RevisionId = AML_RESOURCE_PIN_FUNCTION_REVISION; 1445 1446 /* Build pointers to optional areas */ 1447 1448 PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_FUNCTION)); 1449 ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength); 1450 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 1451 1452 /* Setup offsets within the descriptor */ 1453 1454 Descriptor->PinFunction.PinTableOffset = (UINT16) 1455 ACPI_PTR_DIFF (PinList, Descriptor); 1456 1457 Descriptor->PinFunction.ResSourceOffset = (UINT16) 1458 ACPI_PTR_DIFF (ResourceSource, Descriptor); 1459 1460 /* Process all child initialization nodes */ 1461 1462 for (i = 0; InitializerOp; i++) 1463 { 1464 switch (i) 1465 { 1466 case 0: /* Share Type [Flags] (_SHR) */ 1467 1468 RsSetFlagBits16 (&Descriptor->PinFunction.Flags, InitializerOp, 0, 0); 1469 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1470 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.Flags), 0); 1471 break; 1472 1473 case 1: /* Pin Config [BYTE] (_PPI) */ 1474 1475 Descriptor->PinFunction.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer; 1476 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG, 1477 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.PinConfig)); 1478 break; 1479 1480 case 2: /* Function Number [WORD] (_FUN) */ 1481 1482 Descriptor->PinFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer; 1483 RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION, 1484 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.FunctionNumber)); 1485 break; 1486 1487 case 3: /* ResSource [Optional Field - STRING] */ 1488 1489 if (ResSourceLength) 1490 { 1491 /* Copy string to the descriptor */ 1492 1493 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 1494 } 1495 break; 1496 1497 case 4: /* Resource Index */ 1498 1499 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1500 { 1501 Descriptor->PinFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 1502 } 1503 break; 1504 1505 case 5: /* Resource Usage (consumer/producer) */ 1506 1507 /* Assumed to be consumer */ 1508 1509 break; 1510 1511 case 6: /* Resource Tag (Descriptor Name) */ 1512 1513 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1514 break; 1515 1516 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1517 /* 1518 * Always set the VendorOffset even if there is no Vendor Data. 1519 * This field is required in order to calculate the length 1520 * of the ResourceSource at runtime. 1521 */ 1522 Descriptor->PinFunction.VendorOffset = (UINT16) 1523 ACPI_PTR_DIFF (VendorData, Descriptor); 1524 1525 if (RsGetVendorData (InitializerOp, VendorData, 1526 (CurrentByteOffset + Descriptor->PinFunction.VendorOffset))) 1527 { 1528 Descriptor->PinFunction.VendorLength = VendorLength; 1529 } 1530 break; 1531 1532 default: 1533 /* 1534 * PINs come through here, repeatedly. Each PIN must be a WORD. 1535 * NOTE: there is no "length" field for this, so from ACPI spec: 1536 * The number of pins in the table can be calculated from: 1537 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 1538 * (implies resource source must immediately follow the pin list.) 1539 * Name: _PIN 1540 */ 1541 *PinList = (UINT16) InitializerOp->Asl.Value.Integer; 1542 PinList++; 1543 PinCount++; 1544 1545 /* Case 8: First pin number in list */ 1546 1547 if (i == 8) 1548 { 1549 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1550 { 1551 /* Must be at least one interrupt */ 1552 1553 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 1554 InitializerOp, NULL); 1555 } 1556 1557 /* Check now for duplicates in list */ 1558 1559 RsCheckListForDuplicates (InitializerOp); 1560 1561 /* Create a named field at the start of the list */ 1562 1563 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 1564 CurrentByteOffset + Descriptor->PinFunction.PinTableOffset); 1565 } 1566 break; 1567 } 1568 1569 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1570 } 1571 1572 return (Rnode); 1573 } 1574 1575 1576 /******************************************************************************* 1577 * 1578 * FUNCTION: RsDoPinConfigDescriptor 1579 * 1580 * PARAMETERS: Info - Parse Op and resource template offset 1581 * 1582 * RETURN: Completed resource node 1583 * 1584 * DESCRIPTION: Construct a long "PinConfig" descriptor 1585 * 1586 ******************************************************************************/ 1587 1588 ASL_RESOURCE_NODE * 1589 RsDoPinConfigDescriptor ( 1590 ASL_RESOURCE_INFO *Info) 1591 { 1592 AML_RESOURCE *Descriptor; 1593 ACPI_PARSE_OBJECT *InitializerOp; 1594 ASL_RESOURCE_NODE *Rnode; 1595 char *ResourceSource = NULL; 1596 UINT8 *VendorData = NULL; 1597 UINT16 *PinList = NULL; 1598 UINT16 ResSourceLength; 1599 UINT16 VendorLength; 1600 UINT16 PinListLength; 1601 UINT16 DescriptorSize; 1602 UINT32 CurrentByteOffset; 1603 UINT32 PinCount = 0; 1604 UINT32 i; 1605 1606 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1607 CurrentByteOffset = Info->CurrentByteOffset; 1608 1609 /* 1610 * Calculate lengths for fields that have variable length: 1611 * 1) Resource Source string 1612 * 2) Vendor Data buffer 1613 * 3) PIN (interrupt) list 1614 */ 1615 ResSourceLength = RsGetStringDataLength (InitializerOp); 1616 VendorLength = RsGetBufferDataLength (InitializerOp); 1617 PinListLength = RsGetInterruptDataLength (InitializerOp, 8); 1618 1619 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_CONFIG) + 1620 ResSourceLength + VendorLength + PinListLength; 1621 1622 /* Allocate the local resource node and initialize */ 1623 1624 Rnode = RsAllocateResourceNode (DescriptorSize + 1625 sizeof (AML_RESOURCE_LARGE_HEADER)); 1626 1627 Descriptor = Rnode->Buffer; 1628 Descriptor->PinConfig.ResourceLength = DescriptorSize; 1629 Descriptor->PinConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_CONFIG; 1630 Descriptor->PinConfig.RevisionId = AML_RESOURCE_PIN_CONFIG_REVISION; 1631 1632 /* Build pointers to optional areas */ 1633 1634 PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_CONFIG)); 1635 ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength); 1636 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 1637 1638 /* Setup offsets within the descriptor */ 1639 1640 Descriptor->PinConfig.PinTableOffset = (UINT16) 1641 ACPI_PTR_DIFF (PinList, Descriptor); 1642 1643 Descriptor->PinConfig.ResSourceOffset = (UINT16) 1644 ACPI_PTR_DIFF (ResourceSource, Descriptor); 1645 1646 /* Process all child initialization nodes */ 1647 1648 for (i = 0; InitializerOp; i++) 1649 { 1650 BOOLEAN isValid; 1651 1652 switch (i) 1653 { 1654 case 0: /* Share Type [Flags] (_SHR) */ 1655 1656 RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 0, 0); 1657 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1658 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.Flags), 0); 1659 break; 1660 1661 case 1: /* Pin Config Type [BYTE] (_TYP) */ 1662 1663 isValid = InitializerOp->Asl.Value.Integer <= 0x0d; 1664 if (!isValid) 1665 { 1666 isValid = InitializerOp->Asl.Value.Integer >= 0x80 && 1667 InitializerOp->Asl.Value.Integer <= 0xff; 1668 } 1669 if (!isValid) 1670 { 1671 AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL); 1672 } 1673 1674 Descriptor->PinConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer; 1675 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE, 1676 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigType)); 1677 1678 break; 1679 1680 case 2: /* Pin Config Value [DWORD] (_VAL) */ 1681 1682 Descriptor->PinConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer; 1683 RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE, 1684 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigValue)); 1685 break; 1686 1687 case 3: /* ResSource [Optional Field - STRING] */ 1688 1689 if (ResSourceLength) 1690 { 1691 /* Copy string to the descriptor */ 1692 1693 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 1694 } 1695 break; 1696 1697 case 4: /* Resource Index */ 1698 1699 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1700 { 1701 Descriptor->PinConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 1702 } 1703 break; 1704 1705 case 5: /* Resource Usage (consumer/producer) */ 1706 1707 RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 1, 1); 1708 1709 break; 1710 1711 case 6: /* Resource Tag (Descriptor Name) */ 1712 1713 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1714 break; 1715 1716 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1717 /* 1718 * Always set the VendorOffset even if there is no Vendor Data. 1719 * This field is required in order to calculate the length 1720 * of the ResourceSource at runtime. 1721 */ 1722 Descriptor->PinConfig.VendorOffset = (UINT16) 1723 ACPI_PTR_DIFF (VendorData, Descriptor); 1724 1725 if (RsGetVendorData (InitializerOp, VendorData, 1726 (CurrentByteOffset + Descriptor->PinConfig.VendorOffset))) 1727 { 1728 Descriptor->PinConfig.VendorLength = VendorLength; 1729 } 1730 break; 1731 1732 default: 1733 /* 1734 * PINs come through here, repeatedly. Each PIN must be a WORD. 1735 * NOTE: there is no "length" field for this, so from ACPI spec: 1736 * The number of pins in the table can be calculated from: 1737 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 1738 * (implies resource source must immediately follow the pin list.) 1739 * Name: _PIN 1740 */ 1741 *PinList = (UINT16) InitializerOp->Asl.Value.Integer; 1742 PinList++; 1743 PinCount++; 1744 1745 /* Case 8: First pin number in list */ 1746 1747 if (i == 8) 1748 { 1749 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1750 { 1751 /* Must be at least one interrupt */ 1752 1753 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 1754 InitializerOp, NULL); 1755 } 1756 1757 /* Check now for duplicates in list */ 1758 1759 RsCheckListForDuplicates (InitializerOp); 1760 1761 /* Create a named field at the start of the list */ 1762 1763 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 1764 CurrentByteOffset + Descriptor->PinConfig.PinTableOffset); 1765 } 1766 break; 1767 } 1768 1769 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1770 } 1771 1772 return (Rnode); 1773 } 1774 1775 1776 /******************************************************************************* 1777 * 1778 * FUNCTION: RsDoPinGroupDescriptor 1779 * 1780 * PARAMETERS: Info - Parse Op and resource template offset 1781 * 1782 * RETURN: Completed resource node 1783 * 1784 * DESCRIPTION: Construct a long "PinGroup" descriptor 1785 * 1786 ******************************************************************************/ 1787 1788 ASL_RESOURCE_NODE * 1789 RsDoPinGroupDescriptor ( 1790 ASL_RESOURCE_INFO *Info) 1791 { 1792 AML_RESOURCE *Descriptor; 1793 ACPI_PARSE_OBJECT *InitializerOp; 1794 ASL_RESOURCE_NODE *Rnode; 1795 UINT8 *VendorData = NULL; 1796 UINT16 *PinList = NULL; 1797 char *Label = NULL; 1798 UINT16 LabelLength; 1799 UINT16 VendorLength; 1800 UINT16 PinListLength; 1801 UINT16 DescriptorSize; 1802 UINT32 CurrentByteOffset; 1803 UINT32 PinCount = 0; 1804 UINT32 i; 1805 1806 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1807 CurrentByteOffset = Info->CurrentByteOffset; 1808 1809 /* 1810 * Calculate lengths for fields that have variable length: 1811 * 1) Label 1812 * 2) Vendor Data buffer 1813 * 3) PIN (interrupt) list 1814 */ 1815 LabelLength = RsGetStringDataLength (InitializerOp); 1816 VendorLength = RsGetBufferDataLength (InitializerOp); 1817 PinListLength = RsGetInterruptDataLength (InitializerOp, 4); 1818 1819 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP) + 1820 LabelLength + VendorLength + PinListLength; 1821 1822 /* Allocate the local resource node and initialize */ 1823 1824 Rnode = RsAllocateResourceNode (DescriptorSize + 1825 sizeof (AML_RESOURCE_LARGE_HEADER)); 1826 1827 Descriptor = Rnode->Buffer; 1828 Descriptor->PinGroup.ResourceLength = DescriptorSize; 1829 Descriptor->PinGroup.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP; 1830 Descriptor->PinGroup.RevisionId = AML_RESOURCE_PIN_GROUP_REVISION; 1831 1832 /* Build pointers to optional areas */ 1833 1834 PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP)); 1835 Label = ACPI_ADD_PTR (char, PinList, PinListLength); 1836 VendorData = ACPI_ADD_PTR (UINT8, Label, LabelLength); 1837 1838 /* Setup offsets within the descriptor */ 1839 1840 Descriptor->PinGroup.PinTableOffset = (UINT16) ACPI_PTR_DIFF (PinList, Descriptor); 1841 Descriptor->PinGroup.LabelOffset = (UINT16) ACPI_PTR_DIFF (Label, Descriptor); 1842 1843 /* Process all child initialization nodes */ 1844 1845 for (i = 0; InitializerOp; i++) 1846 { 1847 switch (i) 1848 { 1849 case 0: /* Resource Label */ 1850 1851 if (LabelLength < 2) 1852 { 1853 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL); 1854 } 1855 strcpy (Label, InitializerOp->Asl.Value.String); 1856 1857 break; 1858 1859 case 1: /* Resource Usage (consumer/producer) */ 1860 1861 RsSetFlagBits16 (&Descriptor->PinGroup.Flags, InitializerOp, 0, 0); 1862 1863 break; 1864 1865 case 2: /* Resource Tag (Descriptor Name) */ 1866 1867 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1868 break; 1869 1870 case 3: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1871 /* 1872 * Always set the VendorOffset even if there is no Vendor Data. 1873 * This field is required in order to calculate the length 1874 * of the ResourceSource at runtime. 1875 */ 1876 Descriptor->PinGroup.VendorOffset = (UINT16) 1877 ACPI_PTR_DIFF (VendorData, Descriptor); 1878 1879 if (RsGetVendorData (InitializerOp, VendorData, 1880 (CurrentByteOffset + Descriptor->PinGroup.VendorOffset))) 1881 { 1882 Descriptor->PinGroup.VendorLength = VendorLength; 1883 } 1884 break; 1885 1886 default: 1887 /* 1888 * PINs come through here, repeatedly. Each PIN must be a WORD. 1889 * NOTE: there is no "length" field for this, so from ACPI spec: 1890 * The number of pins in the table can be calculated from: 1891 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 1892 * (implies resource source must immediately follow the pin list.) 1893 * Name: _PIN 1894 */ 1895 *PinList = (UINT16) InitializerOp->Asl.Value.Integer; 1896 PinList++; 1897 PinCount++; 1898 1899 /* Case 3: First pin number in list */ 1900 1901 if (i == 4) 1902 { 1903 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1904 { 1905 /* Must be at least one interrupt */ 1906 1907 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 1908 InitializerOp, NULL); 1909 } 1910 1911 /* Check now for duplicates in list */ 1912 1913 RsCheckListForDuplicates (InitializerOp); 1914 1915 /* Create a named field at the start of the list */ 1916 1917 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 1918 CurrentByteOffset + Descriptor->PinGroup.PinTableOffset); 1919 } 1920 break; 1921 } 1922 1923 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1924 } 1925 1926 return (Rnode); 1927 } 1928 1929 1930 /******************************************************************************* 1931 * 1932 * FUNCTION: RsDoPinGroupFunctionDescriptor 1933 * 1934 * PARAMETERS: Info - Parse Op and resource template offset 1935 * 1936 * RETURN: Completed resource node 1937 * 1938 * DESCRIPTION: Construct a long "PinGroupFunction" descriptor 1939 * 1940 ******************************************************************************/ 1941 1942 ASL_RESOURCE_NODE * 1943 RsDoPinGroupFunctionDescriptor ( 1944 ASL_RESOURCE_INFO *Info) 1945 { 1946 AML_RESOURCE *Descriptor; 1947 ACPI_PARSE_OBJECT *InitializerOp; 1948 ASL_RESOURCE_NODE *Rnode; 1949 char *ResourceSource = NULL; 1950 char *ResourceSourceLabel = NULL; 1951 UINT8 *VendorData = NULL; 1952 UINT16 ResSourceLength; 1953 UINT16 ResSourceLabelLength; 1954 UINT16 VendorLength; 1955 UINT16 DescriptorSize; 1956 UINT32 CurrentByteOffset; 1957 UINT32 i; 1958 1959 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1960 CurrentByteOffset = Info->CurrentByteOffset; 1961 1962 /* 1963 * Calculate lengths for fields that have variable length: 1964 * 1) Resource Source string 1965 * 2) Resource Source Label string 1966 * 3) Vendor Data buffer 1967 */ 1968 ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 2); 1969 ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 4); 1970 VendorLength = RsGetBufferDataLength (InitializerOp); 1971 1972 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_FUNCTION) + 1973 ResSourceLength + ResSourceLabelLength + VendorLength; 1974 1975 /* Allocate the local resource node and initialize */ 1976 1977 Rnode = RsAllocateResourceNode (DescriptorSize + 1978 sizeof (AML_RESOURCE_LARGE_HEADER)); 1979 1980 Descriptor = Rnode->Buffer; 1981 Descriptor->PinGroupFunction.ResourceLength = DescriptorSize; 1982 Descriptor->PinGroupFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION; 1983 Descriptor->PinGroupFunction.RevisionId = AML_RESOURCE_PIN_GROUP_FUNCTION_REVISION; 1984 1985 /* Build pointers to optional areas */ 1986 1987 ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_FUNCTION)); 1988 ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength); 1989 VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength); 1990 1991 /* Setup offsets within the descriptor */ 1992 1993 Descriptor->PinGroupFunction.ResSourceOffset = (UINT16) 1994 ACPI_PTR_DIFF (ResourceSource, Descriptor); 1995 Descriptor->PinGroupFunction.ResSourceLabelOffset = (UINT16) 1996 ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor); 1997 1998 /* Process all child initialization nodes */ 1999 2000 for (i = 0; InitializerOp; i++) 2001 { 2002 switch (i) 2003 { 2004 case 0: /* Share Type [Flags] (_SHR) */ 2005 2006 RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 0, 0); 2007 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 2008 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.Flags), 0); 2009 break; 2010 2011 case 1: /* Function Number [WORD] */ 2012 2013 Descriptor->PinGroupFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer; 2014 RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION, 2015 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.FunctionNumber)); 2016 break; 2017 2018 case 2: /* ResourceSource [STRING] */ 2019 2020 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 2021 break; 2022 2023 case 3: /* Resource Index */ 2024 2025 Descriptor->PinGroupFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 2026 break; 2027 2028 case 4: /* ResourceSourceLabel [STRING] */ 2029 2030 if (ResSourceLabelLength < 2) 2031 { 2032 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL); 2033 } 2034 2035 strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String); 2036 break; 2037 2038 case 5: /* Resource Usage (consumer/producer) */ 2039 2040 RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 1, 1); 2041 2042 break; 2043 2044 case 6: /* Resource Tag (Descriptor Name) */ 2045 2046 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 2047 break; 2048 2049 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 2050 /* 2051 * Always set the VendorOffset even if there is no Vendor Data. 2052 * This field is required in order to calculate the length 2053 * of the ResourceSource at runtime. 2054 */ 2055 Descriptor->PinGroupFunction.VendorOffset = (UINT16) 2056 ACPI_PTR_DIFF (VendorData, Descriptor); 2057 2058 if (RsGetVendorData (InitializerOp, VendorData, 2059 (CurrentByteOffset + Descriptor->PinGroupFunction.VendorOffset))) 2060 { 2061 Descriptor->PinGroupFunction.VendorLength = VendorLength; 2062 } 2063 break; 2064 2065 default: 2066 break; 2067 } 2068 2069 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 2070 } 2071 2072 return (Rnode); 2073 } 2074 2075 2076 /******************************************************************************* 2077 * 2078 * FUNCTION: RsDoPinGroupConfigDescriptor 2079 * 2080 * PARAMETERS: Info - Parse Op and resource template offset 2081 * 2082 * RETURN: Completed resource node 2083 * 2084 * DESCRIPTION: Construct a long "PinGroupConfig" descriptor 2085 * 2086 ******************************************************************************/ 2087 2088 ASL_RESOURCE_NODE * 2089 RsDoPinGroupConfigDescriptor ( 2090 ASL_RESOURCE_INFO *Info) 2091 { 2092 AML_RESOURCE *Descriptor; 2093 ACPI_PARSE_OBJECT *InitializerOp; 2094 ASL_RESOURCE_NODE *Rnode; 2095 char *ResourceSource = NULL; 2096 char *ResourceSourceLabel = NULL; 2097 UINT8 *VendorData = NULL; 2098 UINT16 ResSourceLength; 2099 UINT16 ResSourceLabelLength; 2100 UINT16 VendorLength; 2101 UINT16 DescriptorSize; 2102 UINT32 CurrentByteOffset; 2103 UINT32 i; 2104 2105 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 2106 CurrentByteOffset = Info->CurrentByteOffset; 2107 2108 /* 2109 * Calculate lengths for fields that have variable length: 2110 * 1) Resource Source string 2111 * 2) Resource Source Label string 2112 * 3) Vendor Data buffer 2113 */ 2114 ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 3); 2115 ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 5); 2116 VendorLength = RsGetBufferDataLength (InitializerOp); 2117 2118 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_CONFIG) + 2119 ResSourceLength + ResSourceLabelLength + VendorLength; 2120 2121 /* Allocate the local resource node and initialize */ 2122 2123 Rnode = RsAllocateResourceNode (DescriptorSize + 2124 sizeof (AML_RESOURCE_LARGE_HEADER)); 2125 2126 Descriptor = Rnode->Buffer; 2127 Descriptor->PinGroupConfig.ResourceLength = DescriptorSize; 2128 Descriptor->PinGroupConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG; 2129 Descriptor->PinGroupConfig.RevisionId = AML_RESOURCE_PIN_GROUP_CONFIG_REVISION; 2130 2131 /* Build pointers to optional areas */ 2132 2133 ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_CONFIG)); 2134 ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength); 2135 VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength); 2136 2137 /* Setup offsets within the descriptor */ 2138 2139 Descriptor->PinGroupConfig.ResSourceOffset = (UINT16) 2140 ACPI_PTR_DIFF (ResourceSource, Descriptor); 2141 Descriptor->PinGroupConfig.ResSourceLabelOffset = (UINT16) 2142 ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor); 2143 2144 /* Process all child initialization nodes */ 2145 2146 for (i = 0; InitializerOp; i++) 2147 { 2148 BOOLEAN isValid; 2149 2150 switch (i) 2151 { 2152 case 0: /* Share Type [Flags] (_SHR) */ 2153 2154 RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 0, 0); 2155 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 2156 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.Flags), 0); 2157 break; 2158 2159 case 1: /* Pin Config Type [BYTE] (_TYP) */ 2160 2161 isValid = InitializerOp->Asl.Value.Integer <= 0x0d; 2162 if (!isValid) 2163 { 2164 isValid = InitializerOp->Asl.Value.Integer >= 0x80 && 2165 InitializerOp->Asl.Value.Integer <= 0xff; 2166 } 2167 if (!isValid) 2168 { 2169 AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL); 2170 } 2171 2172 Descriptor->PinGroupConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer; 2173 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE, 2174 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigType)); 2175 2176 break; 2177 2178 case 2: /* Pin Config Value [DWORD] (_VAL) */ 2179 2180 Descriptor->PinGroupConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer; 2181 RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE, 2182 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigValue)); 2183 break; 2184 2185 case 3: /* ResourceSource [STRING] */ 2186 2187 /* Copy string to the descriptor */ 2188 2189 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 2190 break; 2191 2192 case 4: /* Resource Index */ 2193 2194 Descriptor->PinGroupConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 2195 break; 2196 2197 case 5: /* ResourceSourceLabel [STRING] */ 2198 2199 if (ResSourceLabelLength < 2) 2200 { 2201 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL); 2202 } 2203 2204 strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String); 2205 break; 2206 2207 case 6: /* Resource Usage (consumer/producer) */ 2208 2209 RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 1, 1); 2210 2211 break; 2212 2213 case 7: /* Resource Tag (Descriptor Name) */ 2214 2215 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 2216 break; 2217 2218 case 8: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 2219 /* 2220 * Always set the VendorOffset even if there is no Vendor Data. 2221 * This field is required in order to calculate the length 2222 * of the ResourceSource at runtime. 2223 */ 2224 Descriptor->PinGroupConfig.VendorOffset = (UINT16) 2225 ACPI_PTR_DIFF (VendorData, Descriptor); 2226 2227 if (RsGetVendorData (InitializerOp, VendorData, 2228 (CurrentByteOffset + Descriptor->PinGroupConfig.VendorOffset))) 2229 { 2230 Descriptor->PinGroupConfig.VendorLength = VendorLength; 2231 } 2232 break; 2233 2234 default: 2235 break; 2236 } 2237 2238 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 2239 } 2240 2241 return (Rnode); 2242 } 2243