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 - 2017, 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 PinList = InterruptList; 678 679 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) + 680 ResSourceLength + VendorLength + InterruptLength; 681 682 /* Allocate the local resource node and initialize */ 683 684 Rnode = RsAllocateResourceNode (DescriptorSize + 685 sizeof (AML_RESOURCE_LARGE_HEADER)); 686 687 Descriptor = Rnode->Buffer; 688 Descriptor->Gpio.ResourceLength = DescriptorSize; 689 Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO; 690 Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION; 691 Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_IO; 692 693 /* Build pointers to optional areas */ 694 695 InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO)); 696 PinList = InterruptList; 697 ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength); 698 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 699 700 /* Setup offsets within the descriptor */ 701 702 Descriptor->Gpio.PinTableOffset = (UINT16) 703 ACPI_PTR_DIFF (InterruptList, Descriptor); 704 705 Descriptor->Gpio.ResSourceOffset = (UINT16) 706 ACPI_PTR_DIFF (ResourceSource, Descriptor); 707 708 /* Process all child initialization nodes */ 709 710 for (i = 0; InitializerOp; i++) 711 { 712 switch (i) 713 { 714 case 0: /* Share Type [Flags] (_SHR) */ 715 716 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0); 717 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 718 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3); 719 break; 720 721 case 1: /* Pin Config [BYTE] (_PPI) */ 722 723 Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer; 724 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG, 725 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig)); 726 break; 727 728 case 2: /* Debounce Timeout [WORD] (_DBT) */ 729 730 Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer; 731 RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME, 732 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout)); 733 break; 734 735 case 3: /* Drive Strength [WORD] (_DRS) */ 736 737 Descriptor->Gpio.DriveStrength = (UINT16) InitializerOp->Asl.Value.Integer; 738 RsCreateWordField (InitializerOp, ACPI_RESTAG_DRIVESTRENGTH, 739 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DriveStrength)); 740 break; 741 742 case 4: /* I/O Restriction [Flag] (_IOR) */ 743 744 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0); 745 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_IORESTRICTION, 746 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0, 2); 747 break; 748 749 case 5: /* ResSource [Optional Field - STRING] */ 750 751 if (ResSourceLength) 752 { 753 /* Copy string to the descriptor */ 754 755 strcpy (ResourceSource, 756 InitializerOp->Asl.Value.String); 757 } 758 break; 759 760 case 6: /* Resource Index */ 761 762 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 763 { 764 Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 765 } 766 break; 767 768 case 7: /* Resource Usage (consumer/producer) */ 769 770 RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1); 771 break; 772 773 case 8: /* Resource Tag (Descriptor Name) */ 774 775 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 776 break; 777 778 case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 779 /* 780 * Always set the VendorOffset even if there is no Vendor Data. 781 * This field is required in order to calculate the length 782 * of the ResourceSource at runtime. 783 */ 784 Descriptor->Gpio.VendorOffset = (UINT16) 785 ACPI_PTR_DIFF (VendorData, Descriptor); 786 787 if (RsGetVendorData (InitializerOp, VendorData, 788 (CurrentByteOffset + Descriptor->Gpio.VendorOffset))) 789 { 790 Descriptor->Gpio.VendorLength = VendorLength; 791 } 792 break; 793 794 default: 795 /* 796 * PINs come through here, repeatedly. Each PIN must be a WORD. 797 * NOTE: there is no "length" field for this, so from ACPI spec: 798 * The number of pins in the table can be calculated from: 799 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 800 * (implies resource source must immediately follow the pin list.) 801 * Name: _PIN 802 */ 803 *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer; 804 InterruptList++; 805 PinCount++; 806 807 /* Case 10: First interrupt number in list */ 808 809 if (i == 10) 810 { 811 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 812 { 813 /* Must be at least one interrupt */ 814 815 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 816 InitializerOp, NULL); 817 } 818 819 /* Check now for duplicates in list */ 820 821 RsCheckListForDuplicates (InitializerOp); 822 823 /* Create a named field at the start of the list */ 824 825 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 826 CurrentByteOffset + Descriptor->Gpio.PinTableOffset); 827 } 828 break; 829 } 830 831 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 832 } 833 834 MpSaveGpioInfo (Info->MappingOp, Descriptor, 835 PinCount, PinList, ResourceSource); 836 return (Rnode); 837 } 838 839 840 /******************************************************************************* 841 * 842 * FUNCTION: RsDoI2cSerialBusDescriptor 843 * 844 * PARAMETERS: Info - Parse Op and resource template offset 845 * 846 * RETURN: Completed resource node 847 * 848 * DESCRIPTION: Construct a long "I2cSerialBus" descriptor 849 * 850 ******************************************************************************/ 851 852 ASL_RESOURCE_NODE * 853 RsDoI2cSerialBusDescriptor ( 854 ASL_RESOURCE_INFO *Info) 855 { 856 AML_RESOURCE *Descriptor; 857 ACPI_PARSE_OBJECT *InitializerOp; 858 ASL_RESOURCE_NODE *Rnode; 859 char *ResourceSource = NULL; 860 UINT8 *VendorData = NULL; 861 UINT16 ResSourceLength; 862 UINT16 VendorLength; 863 UINT16 DescriptorSize; 864 UINT32 CurrentByteOffset; 865 UINT32 i; 866 867 868 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 869 CurrentByteOffset = Info->CurrentByteOffset; 870 871 /* 872 * Calculate lengths for fields that have variable length: 873 * 1) Resource Source string 874 * 2) Vendor Data buffer 875 */ 876 ResSourceLength = RsGetStringDataLength (InitializerOp); 877 VendorLength = RsGetBufferDataLength (InitializerOp); 878 879 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS) + 880 ResSourceLength + VendorLength; 881 882 /* Allocate the local resource node and initialize */ 883 884 Rnode = RsAllocateResourceNode (DescriptorSize + 885 sizeof (AML_RESOURCE_LARGE_HEADER)); 886 887 Descriptor = Rnode->Buffer; 888 Descriptor->I2cSerialBus.ResourceLength = DescriptorSize; 889 Descriptor->I2cSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 890 Descriptor->I2cSerialBus.RevisionId = AML_RESOURCE_I2C_REVISION; 891 Descriptor->I2cSerialBus.TypeRevisionId = AML_RESOURCE_I2C_TYPE_REVISION; 892 Descriptor->I2cSerialBus.Type = AML_RESOURCE_I2C_SERIALBUSTYPE; 893 Descriptor->I2cSerialBus.TypeDataLength = AML_RESOURCE_I2C_MIN_DATA_LEN + VendorLength; 894 895 if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_I2C_SERIALBUS_V2) 896 { 897 Descriptor->I2cSerialBus.RevisionId = 2; 898 } 899 900 /* Build pointers to optional areas */ 901 902 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_I2C_SERIALBUS)); 903 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 904 905 /* Process all child initialization nodes */ 906 907 for (i = 0; InitializerOp; i++) 908 { 909 switch (i) 910 { 911 case 0: /* Slave Address [WORD] (_ADR) */ 912 913 Descriptor->I2cSerialBus.SlaveAddress = (UINT16) InitializerOp->Asl.Value.Integer; 914 RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS, 915 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.SlaveAddress)); 916 break; 917 918 case 1: /* Slave Mode [Flag] (_SLV) */ 919 920 RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 0, 0); 921 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 922 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0); 923 break; 924 925 case 2: /* Connection Speed [DWORD] (_SPE) */ 926 927 Descriptor->I2cSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer; 928 RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, 929 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.ConnectionSpeed)); 930 break; 931 932 case 3: /* Addressing Mode [Flag] (_MOD) */ 933 934 RsSetFlagBits16 (&Descriptor->I2cSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 935 RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE, 936 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.TypeSpecificFlags), 0); 937 break; 938 939 case 4: /* ResSource [Optional Field - STRING] */ 940 941 if (ResSourceLength) 942 { 943 /* Copy string to the descriptor */ 944 945 strcpy (ResourceSource, 946 InitializerOp->Asl.Value.String); 947 } 948 break; 949 950 case 5: /* Resource Index */ 951 952 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 953 { 954 Descriptor->I2cSerialBus.ResSourceIndex = 955 (UINT8) InitializerOp->Asl.Value.Integer; 956 } 957 break; 958 959 case 6: /* Resource Usage (consumer/producer) */ 960 961 RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 1, 1); 962 break; 963 964 case 7: /* Resource Tag (Descriptor Name) */ 965 966 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 967 break; 968 969 case 8: 970 /* 971 * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor 972 * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from 973 * the ASL parser) 974 */ 975 RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 2, 0); 976 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 977 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 2); 978 break; 979 980 case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 981 982 RsGetVendorData (InitializerOp, VendorData, 983 CurrentByteOffset + sizeof (AML_RESOURCE_I2C_SERIALBUS)); 984 break; 985 986 default: /* Ignore any extra nodes */ 987 988 break; 989 } 990 991 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 992 } 993 994 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 995 return (Rnode); 996 } 997 998 999 /******************************************************************************* 1000 * 1001 * FUNCTION: RsDoSpiSerialBusDescriptor 1002 * 1003 * PARAMETERS: Info - Parse Op and resource template offset 1004 * 1005 * RETURN: Completed resource node 1006 * 1007 * DESCRIPTION: Construct a long "SPI Serial Bus" descriptor 1008 * 1009 ******************************************************************************/ 1010 1011 ASL_RESOURCE_NODE * 1012 RsDoSpiSerialBusDescriptor ( 1013 ASL_RESOURCE_INFO *Info) 1014 { 1015 AML_RESOURCE *Descriptor; 1016 ACPI_PARSE_OBJECT *InitializerOp; 1017 ASL_RESOURCE_NODE *Rnode; 1018 char *ResourceSource = NULL; 1019 UINT8 *VendorData = NULL; 1020 UINT16 ResSourceLength; 1021 UINT16 VendorLength; 1022 UINT16 DescriptorSize; 1023 UINT32 CurrentByteOffset; 1024 UINT32 i; 1025 1026 1027 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1028 CurrentByteOffset = Info->CurrentByteOffset; 1029 1030 /* 1031 * Calculate lengths for fields that have variable length: 1032 * 1) Resource Source string 1033 * 2) Vendor Data buffer 1034 */ 1035 ResSourceLength = RsGetStringDataLength (InitializerOp); 1036 VendorLength = RsGetBufferDataLength (InitializerOp); 1037 1038 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS) + 1039 ResSourceLength + VendorLength; 1040 1041 /* Allocate the local resource node and initialize */ 1042 1043 Rnode = RsAllocateResourceNode (DescriptorSize + 1044 sizeof (AML_RESOURCE_LARGE_HEADER)); 1045 1046 Descriptor = Rnode->Buffer; 1047 Descriptor->SpiSerialBus.ResourceLength = DescriptorSize; 1048 Descriptor->SpiSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 1049 Descriptor->SpiSerialBus.RevisionId = AML_RESOURCE_SPI_REVISION; 1050 Descriptor->SpiSerialBus.TypeRevisionId = AML_RESOURCE_SPI_TYPE_REVISION; 1051 Descriptor->SpiSerialBus.Type = AML_RESOURCE_SPI_SERIALBUSTYPE; 1052 Descriptor->SpiSerialBus.TypeDataLength = AML_RESOURCE_SPI_MIN_DATA_LEN + VendorLength; 1053 1054 if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_SPI_SERIALBUS_V2) 1055 { 1056 Descriptor->I2cSerialBus.RevisionId = 2; 1057 } 1058 1059 /* Build pointers to optional areas */ 1060 1061 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, 1062 sizeof (AML_RESOURCE_SPI_SERIALBUS)); 1063 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 1064 1065 /* Process all child initialization nodes */ 1066 1067 for (i = 0; InitializerOp; i++) 1068 { 1069 switch (i) 1070 { 1071 case 0: /* Device Selection [WORD] (_ADR) */ 1072 1073 Descriptor->SpiSerialBus.DeviceSelection = (UINT16) InitializerOp->Asl.Value.Integer; 1074 RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS, 1075 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DeviceSelection)); 1076 break; 1077 1078 case 1: /* Device Polarity [Flag] (_DPL) */ 1079 1080 RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 1, 0); 1081 RsCreateBitField (InitializerOp, ACPI_RESTAG_DEVICEPOLARITY, 1082 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 1); 1083 break; 1084 1085 case 2: /* Wire Mode [Flag] (_MOD) */ 1086 1087 RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 1088 RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE, 1089 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 0); 1090 break; 1091 1092 case 3: /* Device Bit Length [BYTE] (_LEN) */ 1093 1094 Descriptor->SpiSerialBus.DataBitLength = (UINT8) InitializerOp->Asl.Value.Integer; 1095 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH, 1096 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DataBitLength)); 1097 break; 1098 1099 case 4: /* Slave Mode [Flag] (_SLV) */ 1100 1101 RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 0, 0); 1102 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 1103 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 0); 1104 break; 1105 1106 case 5: /* Connection Speed [DWORD] (_SPE) */ 1107 1108 Descriptor->SpiSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer; 1109 RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, 1110 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ConnectionSpeed)); 1111 break; 1112 1113 case 6: /* Clock Polarity [BYTE] (_POL) */ 1114 1115 Descriptor->SpiSerialBus.ClockPolarity = (UINT8) InitializerOp->Asl.Value.Integer; 1116 RsCreateByteField (InitializerOp, ACPI_RESTAG_POLARITY, 1117 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPolarity)); 1118 break; 1119 1120 case 7: /* Clock Phase [BYTE] (_PHA) */ 1121 1122 Descriptor->SpiSerialBus.ClockPhase = (UINT8) InitializerOp->Asl.Value.Integer; 1123 RsCreateByteField (InitializerOp, ACPI_RESTAG_PHASE, 1124 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPhase)); 1125 break; 1126 1127 case 8: /* ResSource [Optional Field - STRING] */ 1128 1129 if (ResSourceLength) 1130 { 1131 /* Copy string to the descriptor */ 1132 1133 strcpy (ResourceSource, 1134 InitializerOp->Asl.Value.String); 1135 } 1136 break; 1137 1138 case 9: /* Resource Index */ 1139 1140 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1141 { 1142 Descriptor->SpiSerialBus.ResSourceIndex = 1143 (UINT8) InitializerOp->Asl.Value.Integer; 1144 } 1145 break; 1146 1147 case 10: /* Resource Usage (consumer/producer) */ 1148 1149 RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 1, 1); 1150 break; 1151 1152 case 11: /* Resource Tag (Descriptor Name) */ 1153 1154 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1155 break; 1156 1157 case 12: 1158 /* 1159 * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor 1160 * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from 1161 * the ASL parser) 1162 */ 1163 RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 2, 0); 1164 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1165 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 2); 1166 break; 1167 1168 case 13: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1169 1170 RsGetVendorData (InitializerOp, VendorData, 1171 CurrentByteOffset + sizeof (AML_RESOURCE_SPI_SERIALBUS)); 1172 break; 1173 1174 default: /* Ignore any extra nodes */ 1175 1176 break; 1177 } 1178 1179 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1180 } 1181 1182 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 1183 return (Rnode); 1184 } 1185 1186 1187 /******************************************************************************* 1188 * 1189 * FUNCTION: RsDoUartSerialBusDescriptor 1190 * 1191 * PARAMETERS: Info - Parse Op and resource template offset 1192 * 1193 * RETURN: Completed resource node 1194 * 1195 * DESCRIPTION: Construct a long "UART Serial Bus" descriptor 1196 * 1197 ******************************************************************************/ 1198 1199 ASL_RESOURCE_NODE * 1200 RsDoUartSerialBusDescriptor ( 1201 ASL_RESOURCE_INFO *Info) 1202 { 1203 AML_RESOURCE *Descriptor; 1204 ACPI_PARSE_OBJECT *InitializerOp; 1205 ASL_RESOURCE_NODE *Rnode; 1206 char *ResourceSource = NULL; 1207 UINT8 *VendorData = NULL; 1208 UINT16 ResSourceLength; 1209 UINT16 VendorLength; 1210 UINT16 DescriptorSize; 1211 UINT32 CurrentByteOffset; 1212 UINT32 i; 1213 1214 1215 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1216 CurrentByteOffset = Info->CurrentByteOffset; 1217 1218 /* 1219 * Calculate lengths for fields that have variable length: 1220 * 1) Resource Source string 1221 * 2) Vendor Data buffer 1222 */ 1223 ResSourceLength = RsGetStringDataLength (InitializerOp); 1224 VendorLength = RsGetBufferDataLength (InitializerOp); 1225 1226 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS) + 1227 ResSourceLength + VendorLength; 1228 1229 /* Allocate the local resource node and initialize */ 1230 1231 Rnode = RsAllocateResourceNode (DescriptorSize + 1232 sizeof (AML_RESOURCE_LARGE_HEADER)); 1233 1234 Descriptor = Rnode->Buffer; 1235 Descriptor->UartSerialBus.ResourceLength = DescriptorSize; 1236 Descriptor->UartSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 1237 Descriptor->UartSerialBus.RevisionId = AML_RESOURCE_UART_REVISION; 1238 Descriptor->UartSerialBus.TypeRevisionId = AML_RESOURCE_UART_TYPE_REVISION; 1239 Descriptor->UartSerialBus.Type = AML_RESOURCE_UART_SERIALBUSTYPE; 1240 Descriptor->UartSerialBus.TypeDataLength = AML_RESOURCE_UART_MIN_DATA_LEN + VendorLength; 1241 1242 if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_UART_SERIALBUS_V2) 1243 { 1244 Descriptor->I2cSerialBus.RevisionId = 2; 1245 } 1246 1247 /* Build pointers to optional areas */ 1248 1249 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_UART_SERIALBUS)); 1250 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 1251 1252 /* Process all child initialization nodes */ 1253 1254 for (i = 0; InitializerOp; i++) 1255 { 1256 switch (i) 1257 { 1258 case 0: /* Connection Speed (Baud Rate) [DWORD] (_SPE) */ 1259 1260 Descriptor->UartSerialBus.DefaultBaudRate = (UINT32) InitializerOp->Asl.Value.Integer; 1261 RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, 1262 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.DefaultBaudRate)); 1263 break; 1264 1265 case 1: /* Bits Per Byte [Flags] (_LEN) */ 1266 1267 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 4, 3); 1268 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LENGTH, 1269 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 4, 3); 1270 break; 1271 1272 case 2: /* Stop Bits [Flags] (_STB) */ 1273 1274 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 2, 1); 1275 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_STOPBITS, 1276 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 2, 2); 1277 break; 1278 1279 case 3: /* Lines In Use [BYTE] (_LIN) */ 1280 1281 Descriptor->UartSerialBus.LinesEnabled = (UINT8) InitializerOp->Asl.Value.Integer; 1282 RsCreateByteField (InitializerOp, ACPI_RESTAG_LINE, 1283 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.LinesEnabled)); 1284 break; 1285 1286 case 4: /* Endianness [Flag] (_END) */ 1287 1288 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 7, 0); 1289 RsCreateBitField (InitializerOp, ACPI_RESTAG_ENDIANNESS, 1290 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 7); 1291 break; 1292 1293 case 5: /* Parity [BYTE] (_PAR) */ 1294 1295 Descriptor->UartSerialBus.Parity = (UINT8) InitializerOp->Asl.Value.Integer; 1296 RsCreateByteField (InitializerOp, ACPI_RESTAG_PARITY, 1297 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Parity)); 1298 break; 1299 1300 case 6: /* Flow Control [Flags] (_FLC) */ 1301 1302 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 1303 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_FLOWCONTROL, 1304 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 0, 2); 1305 break; 1306 1307 case 7: /* Rx Buffer Size [WORD] (_RXL) */ 1308 1309 Descriptor->UartSerialBus.RxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer; 1310 RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_RX, 1311 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.RxFifoSize)); 1312 break; 1313 1314 case 8: /* Tx Buffer Size [WORD] (_TXL) */ 1315 1316 Descriptor->UartSerialBus.TxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer; 1317 RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_TX, 1318 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TxFifoSize)); 1319 break; 1320 1321 case 9: /* ResSource [Optional Field - STRING] */ 1322 1323 if (ResSourceLength) 1324 { 1325 /* Copy string to the descriptor */ 1326 1327 strcpy (ResourceSource, 1328 InitializerOp->Asl.Value.String); 1329 } 1330 break; 1331 1332 case 10: /* Resource Index */ 1333 1334 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1335 { 1336 Descriptor->UartSerialBus.ResSourceIndex = 1337 (UINT8) InitializerOp->Asl.Value.Integer; 1338 } 1339 break; 1340 1341 case 11: /* Resource Usage (consumer/producer) */ 1342 1343 RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 1, 1); 1344 1345 /* 1346 * Slave Mode [Flag] (_SLV) 1347 * 1348 * Note: There is no SlaveMode argument to the UartSerialBus macro, but 1349 * we add this name anyway to allow the flag to be set by ASL in the 1350 * rare case where there is a slave mode associated with the UART. 1351 */ 1352 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 1353 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 0); 1354 break; 1355 1356 case 12: /* Resource Tag (Descriptor Name) */ 1357 1358 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1359 break; 1360 1361 case 13: 1362 /* 1363 * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor 1364 * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from 1365 * the ASL parser) 1366 */ 1367 RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 2, 0); 1368 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1369 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 2); 1370 break; 1371 1372 case 14: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1373 1374 RsGetVendorData (InitializerOp, VendorData, 1375 CurrentByteOffset + sizeof (AML_RESOURCE_UART_SERIALBUS)); 1376 break; 1377 1378 default: /* Ignore any extra nodes */ 1379 1380 break; 1381 } 1382 1383 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1384 } 1385 1386 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 1387 return (Rnode); 1388 } 1389 1390 1391 /******************************************************************************* 1392 * 1393 * FUNCTION: RsDoPinFunctionDescriptor 1394 * 1395 * PARAMETERS: Info - Parse Op and resource template offset 1396 * 1397 * RETURN: Completed resource node 1398 * 1399 * DESCRIPTION: Construct a long "PinFunction" descriptor 1400 * 1401 ******************************************************************************/ 1402 1403 ASL_RESOURCE_NODE * 1404 RsDoPinFunctionDescriptor ( 1405 ASL_RESOURCE_INFO *Info) 1406 { 1407 AML_RESOURCE *Descriptor; 1408 ACPI_PARSE_OBJECT *InitializerOp; 1409 ASL_RESOURCE_NODE *Rnode; 1410 char *ResourceSource = NULL; 1411 UINT8 *VendorData = NULL; 1412 UINT16 *PinList = NULL; 1413 UINT16 ResSourceLength; 1414 UINT16 VendorLength; 1415 UINT16 PinListLength; 1416 UINT16 DescriptorSize; 1417 UINT32 CurrentByteOffset; 1418 UINT32 PinCount = 0; 1419 UINT32 i; 1420 1421 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1422 CurrentByteOffset = Info->CurrentByteOffset; 1423 1424 /* 1425 * Calculate lengths for fields that have variable length: 1426 * 1) Resource Source string 1427 * 2) Vendor Data buffer 1428 * 3) PIN (interrupt) list 1429 */ 1430 ResSourceLength = RsGetStringDataLength (InitializerOp); 1431 VendorLength = RsGetBufferDataLength (InitializerOp); 1432 PinListLength = RsGetInterruptDataLength (InitializerOp, 8); 1433 1434 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_FUNCTION) + 1435 ResSourceLength + VendorLength + PinListLength; 1436 1437 /* Allocate the local resource node and initialize */ 1438 1439 Rnode = RsAllocateResourceNode (DescriptorSize + 1440 sizeof (AML_RESOURCE_LARGE_HEADER)); 1441 1442 Descriptor = Rnode->Buffer; 1443 Descriptor->PinFunction.ResourceLength = DescriptorSize; 1444 Descriptor->PinFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_FUNCTION; 1445 Descriptor->PinFunction.RevisionId = AML_RESOURCE_PIN_FUNCTION_REVISION; 1446 1447 /* Build pointers to optional areas */ 1448 1449 PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_FUNCTION)); 1450 ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength); 1451 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 1452 1453 /* Setup offsets within the descriptor */ 1454 1455 Descriptor->PinFunction.PinTableOffset = (UINT16) 1456 ACPI_PTR_DIFF (PinList, Descriptor); 1457 1458 Descriptor->PinFunction.ResSourceOffset = (UINT16) 1459 ACPI_PTR_DIFF (ResourceSource, Descriptor); 1460 1461 /* Process all child initialization nodes */ 1462 1463 for (i = 0; InitializerOp; i++) 1464 { 1465 switch (i) 1466 { 1467 case 0: /* Share Type [Flags] (_SHR) */ 1468 1469 RsSetFlagBits16 (&Descriptor->PinFunction.Flags, InitializerOp, 0, 0); 1470 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1471 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.Flags), 0); 1472 break; 1473 1474 case 1: /* Pin Config [BYTE] (_PPI) */ 1475 1476 Descriptor->PinFunction.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer; 1477 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG, 1478 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.PinConfig)); 1479 break; 1480 1481 case 2: /* Function Number [WORD] (_FUN) */ 1482 1483 Descriptor->PinFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer; 1484 RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION, 1485 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.FunctionNumber)); 1486 break; 1487 1488 case 3: /* ResSource [Optional Field - STRING] */ 1489 1490 if (ResSourceLength) 1491 { 1492 /* Copy string to the descriptor */ 1493 1494 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 1495 } 1496 break; 1497 1498 case 4: /* Resource Index */ 1499 1500 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1501 { 1502 Descriptor->PinFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 1503 } 1504 break; 1505 1506 case 5: /* Resource Usage (consumer/producer) */ 1507 1508 /* Assumed to be consumer */ 1509 1510 break; 1511 1512 case 6: /* Resource Tag (Descriptor Name) */ 1513 1514 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1515 break; 1516 1517 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1518 /* 1519 * Always set the VendorOffset even if there is no Vendor Data. 1520 * This field is required in order to calculate the length 1521 * of the ResourceSource at runtime. 1522 */ 1523 Descriptor->PinFunction.VendorOffset = (UINT16) 1524 ACPI_PTR_DIFF (VendorData, Descriptor); 1525 1526 if (RsGetVendorData (InitializerOp, VendorData, 1527 (CurrentByteOffset + Descriptor->PinFunction.VendorOffset))) 1528 { 1529 Descriptor->PinFunction.VendorLength = VendorLength; 1530 } 1531 break; 1532 1533 default: 1534 /* 1535 * PINs come through here, repeatedly. Each PIN must be a WORD. 1536 * NOTE: there is no "length" field for this, so from ACPI spec: 1537 * The number of pins in the table can be calculated from: 1538 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 1539 * (implies resource source must immediately follow the pin list.) 1540 * Name: _PIN 1541 */ 1542 *PinList = (UINT16) InitializerOp->Asl.Value.Integer; 1543 PinList++; 1544 PinCount++; 1545 1546 /* Case 8: First pin number in list */ 1547 1548 if (i == 8) 1549 { 1550 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1551 { 1552 /* Must be at least one interrupt */ 1553 1554 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 1555 InitializerOp, NULL); 1556 } 1557 1558 /* Check now for duplicates in list */ 1559 1560 RsCheckListForDuplicates (InitializerOp); 1561 1562 /* Create a named field at the start of the list */ 1563 1564 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 1565 CurrentByteOffset + Descriptor->PinFunction.PinTableOffset); 1566 } 1567 break; 1568 } 1569 1570 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1571 } 1572 1573 return (Rnode); 1574 } 1575 1576 1577 /******************************************************************************* 1578 * 1579 * FUNCTION: RsDoPinConfigDescriptor 1580 * 1581 * PARAMETERS: Info - Parse Op and resource template offset 1582 * 1583 * RETURN: Completed resource node 1584 * 1585 * DESCRIPTION: Construct a long "PinConfig" descriptor 1586 * 1587 ******************************************************************************/ 1588 1589 ASL_RESOURCE_NODE * 1590 RsDoPinConfigDescriptor ( 1591 ASL_RESOURCE_INFO *Info) 1592 { 1593 AML_RESOURCE *Descriptor; 1594 ACPI_PARSE_OBJECT *InitializerOp; 1595 ASL_RESOURCE_NODE *Rnode; 1596 char *ResourceSource = NULL; 1597 UINT8 *VendorData = NULL; 1598 UINT16 *PinList = NULL; 1599 UINT16 ResSourceLength; 1600 UINT16 VendorLength; 1601 UINT16 PinListLength; 1602 UINT16 DescriptorSize; 1603 UINT32 CurrentByteOffset; 1604 UINT32 PinCount = 0; 1605 UINT32 i; 1606 1607 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1608 CurrentByteOffset = Info->CurrentByteOffset; 1609 1610 /* 1611 * Calculate lengths for fields that have variable length: 1612 * 1) Resource Source string 1613 * 2) Vendor Data buffer 1614 * 3) PIN (interrupt) list 1615 */ 1616 ResSourceLength = RsGetStringDataLength (InitializerOp); 1617 VendorLength = RsGetBufferDataLength (InitializerOp); 1618 PinListLength = RsGetInterruptDataLength (InitializerOp, 8); 1619 1620 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_CONFIG) + 1621 ResSourceLength + VendorLength + PinListLength; 1622 1623 /* Allocate the local resource node and initialize */ 1624 1625 Rnode = RsAllocateResourceNode (DescriptorSize + 1626 sizeof (AML_RESOURCE_LARGE_HEADER)); 1627 1628 Descriptor = Rnode->Buffer; 1629 Descriptor->PinConfig.ResourceLength = DescriptorSize; 1630 Descriptor->PinConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_CONFIG; 1631 Descriptor->PinConfig.RevisionId = AML_RESOURCE_PIN_CONFIG_REVISION; 1632 1633 /* Build pointers to optional areas */ 1634 1635 PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_CONFIG)); 1636 ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength); 1637 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 1638 1639 /* Setup offsets within the descriptor */ 1640 1641 Descriptor->PinConfig.PinTableOffset = (UINT16) 1642 ACPI_PTR_DIFF (PinList, Descriptor); 1643 1644 Descriptor->PinConfig.ResSourceOffset = (UINT16) 1645 ACPI_PTR_DIFF (ResourceSource, Descriptor); 1646 1647 /* Process all child initialization nodes */ 1648 1649 for (i = 0; InitializerOp; i++) 1650 { 1651 BOOLEAN isValid; 1652 1653 switch (i) 1654 { 1655 case 0: /* Share Type [Flags] (_SHR) */ 1656 1657 RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 0, 0); 1658 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1659 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.Flags), 0); 1660 break; 1661 1662 case 1: /* Pin Config Type [BYTE] (_TYP) */ 1663 1664 isValid = InitializerOp->Asl.Value.Integer <= 0x0d; 1665 if (!isValid) 1666 { 1667 isValid = InitializerOp->Asl.Value.Integer >= 0x80 && 1668 InitializerOp->Asl.Value.Integer <= 0xff; 1669 } 1670 if (!isValid) 1671 { 1672 AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL); 1673 } 1674 1675 Descriptor->PinConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer; 1676 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE, 1677 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigType)); 1678 1679 break; 1680 1681 case 2: /* Pin Config Value [DWORD] (_VAL) */ 1682 1683 Descriptor->PinConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer; 1684 RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE, 1685 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigValue)); 1686 break; 1687 1688 case 3: /* ResSource [Optional Field - STRING] */ 1689 1690 if (ResSourceLength) 1691 { 1692 /* Copy string to the descriptor */ 1693 1694 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 1695 } 1696 break; 1697 1698 case 4: /* Resource Index */ 1699 1700 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1701 { 1702 Descriptor->PinConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 1703 } 1704 break; 1705 1706 case 5: /* Resource Usage (consumer/producer) */ 1707 1708 RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 1, 1); 1709 1710 break; 1711 1712 case 6: /* Resource Tag (Descriptor Name) */ 1713 1714 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1715 break; 1716 1717 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1718 /* 1719 * Always set the VendorOffset even if there is no Vendor Data. 1720 * This field is required in order to calculate the length 1721 * of the ResourceSource at runtime. 1722 */ 1723 Descriptor->PinConfig.VendorOffset = (UINT16) 1724 ACPI_PTR_DIFF (VendorData, Descriptor); 1725 1726 if (RsGetVendorData (InitializerOp, VendorData, 1727 (CurrentByteOffset + Descriptor->PinConfig.VendorOffset))) 1728 { 1729 Descriptor->PinConfig.VendorLength = VendorLength; 1730 } 1731 break; 1732 1733 default: 1734 /* 1735 * PINs come through here, repeatedly. Each PIN must be a WORD. 1736 * NOTE: there is no "length" field for this, so from ACPI spec: 1737 * The number of pins in the table can be calculated from: 1738 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 1739 * (implies resource source must immediately follow the pin list.) 1740 * Name: _PIN 1741 */ 1742 *PinList = (UINT16) InitializerOp->Asl.Value.Integer; 1743 PinList++; 1744 PinCount++; 1745 1746 /* Case 8: First pin number in list */ 1747 1748 if (i == 8) 1749 { 1750 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1751 { 1752 /* Must be at least one interrupt */ 1753 1754 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 1755 InitializerOp, NULL); 1756 } 1757 1758 /* Check now for duplicates in list */ 1759 1760 RsCheckListForDuplicates (InitializerOp); 1761 1762 /* Create a named field at the start of the list */ 1763 1764 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 1765 CurrentByteOffset + Descriptor->PinConfig.PinTableOffset); 1766 } 1767 break; 1768 } 1769 1770 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1771 } 1772 1773 return (Rnode); 1774 } 1775 1776 1777 /******************************************************************************* 1778 * 1779 * FUNCTION: RsDoPinGroupDescriptor 1780 * 1781 * PARAMETERS: Info - Parse Op and resource template offset 1782 * 1783 * RETURN: Completed resource node 1784 * 1785 * DESCRIPTION: Construct a long "PinGroup" descriptor 1786 * 1787 ******************************************************************************/ 1788 1789 ASL_RESOURCE_NODE * 1790 RsDoPinGroupDescriptor ( 1791 ASL_RESOURCE_INFO *Info) 1792 { 1793 AML_RESOURCE *Descriptor; 1794 ACPI_PARSE_OBJECT *InitializerOp; 1795 ASL_RESOURCE_NODE *Rnode; 1796 UINT8 *VendorData = NULL; 1797 UINT16 *PinList = NULL; 1798 char *Label = NULL; 1799 UINT16 LabelLength; 1800 UINT16 VendorLength; 1801 UINT16 PinListLength; 1802 UINT16 DescriptorSize; 1803 UINT32 CurrentByteOffset; 1804 UINT32 PinCount = 0; 1805 UINT32 i; 1806 1807 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1808 CurrentByteOffset = Info->CurrentByteOffset; 1809 1810 /* 1811 * Calculate lengths for fields that have variable length: 1812 * 1) Label 1813 * 2) Vendor Data buffer 1814 * 3) PIN (interrupt) list 1815 */ 1816 LabelLength = RsGetStringDataLength (InitializerOp); 1817 VendorLength = RsGetBufferDataLength (InitializerOp); 1818 PinListLength = RsGetInterruptDataLength (InitializerOp, 4); 1819 1820 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP) + 1821 LabelLength + VendorLength + PinListLength; 1822 1823 /* Allocate the local resource node and initialize */ 1824 1825 Rnode = RsAllocateResourceNode (DescriptorSize + 1826 sizeof (AML_RESOURCE_LARGE_HEADER)); 1827 1828 Descriptor = Rnode->Buffer; 1829 Descriptor->PinGroup.ResourceLength = DescriptorSize; 1830 Descriptor->PinGroup.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP; 1831 Descriptor->PinGroup.RevisionId = AML_RESOURCE_PIN_GROUP_REVISION; 1832 1833 /* Build pointers to optional areas */ 1834 1835 PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP)); 1836 Label = ACPI_ADD_PTR (char, PinList, PinListLength); 1837 VendorData = ACPI_ADD_PTR (UINT8, Label, LabelLength); 1838 1839 /* Setup offsets within the descriptor */ 1840 1841 Descriptor->PinGroup.PinTableOffset = (UINT16) ACPI_PTR_DIFF (PinList, Descriptor); 1842 Descriptor->PinGroup.LabelOffset = (UINT16) ACPI_PTR_DIFF (Label, Descriptor); 1843 1844 /* Process all child initialization nodes */ 1845 1846 for (i = 0; InitializerOp; i++) 1847 { 1848 switch (i) 1849 { 1850 case 0: /* Resource Label */ 1851 1852 if (LabelLength < 2) 1853 { 1854 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL); 1855 } 1856 strcpy (Label, InitializerOp->Asl.Value.String); 1857 1858 break; 1859 1860 case 1: /* Resource Usage (consumer/producer) */ 1861 1862 RsSetFlagBits16 (&Descriptor->PinGroup.Flags, InitializerOp, 0, 0); 1863 1864 break; 1865 1866 case 2: /* Resource Tag (Descriptor Name) */ 1867 1868 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1869 break; 1870 1871 case 3: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1872 /* 1873 * Always set the VendorOffset even if there is no Vendor Data. 1874 * This field is required in order to calculate the length 1875 * of the ResourceSource at runtime. 1876 */ 1877 Descriptor->PinGroup.VendorOffset = (UINT16) 1878 ACPI_PTR_DIFF (VendorData, Descriptor); 1879 1880 if (RsGetVendorData (InitializerOp, VendorData, 1881 (CurrentByteOffset + Descriptor->PinGroup.VendorOffset))) 1882 { 1883 Descriptor->PinGroup.VendorLength = VendorLength; 1884 } 1885 break; 1886 1887 default: 1888 /* 1889 * PINs come through here, repeatedly. Each PIN must be a WORD. 1890 * NOTE: there is no "length" field for this, so from ACPI spec: 1891 * The number of pins in the table can be calculated from: 1892 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 1893 * (implies resource source must immediately follow the pin list.) 1894 * Name: _PIN 1895 */ 1896 *PinList = (UINT16) InitializerOp->Asl.Value.Integer; 1897 PinList++; 1898 PinCount++; 1899 1900 /* Case 3: First pin number in list */ 1901 1902 if (i == 4) 1903 { 1904 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1905 { 1906 /* Must be at least one interrupt */ 1907 1908 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 1909 InitializerOp, NULL); 1910 } 1911 1912 /* Check now for duplicates in list */ 1913 1914 RsCheckListForDuplicates (InitializerOp); 1915 1916 /* Create a named field at the start of the list */ 1917 1918 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 1919 CurrentByteOffset + Descriptor->PinGroup.PinTableOffset); 1920 } 1921 break; 1922 } 1923 1924 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1925 } 1926 1927 return (Rnode); 1928 } 1929 1930 1931 /******************************************************************************* 1932 * 1933 * FUNCTION: RsDoPinGroupFunctionDescriptor 1934 * 1935 * PARAMETERS: Info - Parse Op and resource template offset 1936 * 1937 * RETURN: Completed resource node 1938 * 1939 * DESCRIPTION: Construct a long "PinGroupFunction" descriptor 1940 * 1941 ******************************************************************************/ 1942 1943 ASL_RESOURCE_NODE * 1944 RsDoPinGroupFunctionDescriptor ( 1945 ASL_RESOURCE_INFO *Info) 1946 { 1947 AML_RESOURCE *Descriptor; 1948 ACPI_PARSE_OBJECT *InitializerOp; 1949 ASL_RESOURCE_NODE *Rnode; 1950 char *ResourceSource = NULL; 1951 char *ResourceSourceLabel = NULL; 1952 UINT8 *VendorData = NULL; 1953 UINT16 ResSourceLength; 1954 UINT16 ResSourceLabelLength; 1955 UINT16 VendorLength; 1956 UINT16 DescriptorSize; 1957 UINT32 CurrentByteOffset; 1958 UINT32 i; 1959 1960 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1961 CurrentByteOffset = Info->CurrentByteOffset; 1962 1963 /* 1964 * Calculate lengths for fields that have variable length: 1965 * 1) Resource Source string 1966 * 2) Resource Source Label string 1967 * 3) Vendor Data buffer 1968 */ 1969 ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 2); 1970 ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 4); 1971 VendorLength = RsGetBufferDataLength (InitializerOp); 1972 1973 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_FUNCTION) + 1974 ResSourceLength + ResSourceLabelLength + VendorLength; 1975 1976 /* Allocate the local resource node and initialize */ 1977 1978 Rnode = RsAllocateResourceNode (DescriptorSize + 1979 sizeof (AML_RESOURCE_LARGE_HEADER)); 1980 1981 Descriptor = Rnode->Buffer; 1982 Descriptor->PinGroupFunction.ResourceLength = DescriptorSize; 1983 Descriptor->PinGroupFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION; 1984 Descriptor->PinGroupFunction.RevisionId = AML_RESOURCE_PIN_GROUP_FUNCTION_REVISION; 1985 1986 /* Build pointers to optional areas */ 1987 1988 ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_FUNCTION)); 1989 ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength); 1990 VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength); 1991 1992 /* Setup offsets within the descriptor */ 1993 1994 Descriptor->PinGroupFunction.ResSourceOffset = (UINT16) 1995 ACPI_PTR_DIFF (ResourceSource, Descriptor); 1996 Descriptor->PinGroupFunction.ResSourceLabelOffset = (UINT16) 1997 ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor); 1998 1999 /* Process all child initialization nodes */ 2000 2001 for (i = 0; InitializerOp; i++) 2002 { 2003 switch (i) 2004 { 2005 case 0: /* Share Type [Flags] (_SHR) */ 2006 2007 RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 0, 0); 2008 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 2009 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.Flags), 0); 2010 break; 2011 2012 case 1: /* Function Number [WORD] */ 2013 2014 Descriptor->PinGroupFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer; 2015 RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION, 2016 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.FunctionNumber)); 2017 break; 2018 2019 case 2: /* ResourceSource [STRING] */ 2020 2021 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 2022 break; 2023 2024 case 3: /* Resource Index */ 2025 2026 Descriptor->PinGroupFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 2027 break; 2028 2029 case 4: /* ResourceSourceLabel [STRING] */ 2030 2031 if (ResSourceLabelLength < 2) 2032 { 2033 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL); 2034 } 2035 2036 strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String); 2037 break; 2038 2039 case 5: /* Resource Usage (consumer/producer) */ 2040 2041 RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 1, 1); 2042 2043 break; 2044 2045 case 6: /* Resource Tag (Descriptor Name) */ 2046 2047 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 2048 break; 2049 2050 case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 2051 /* 2052 * Always set the VendorOffset even if there is no Vendor Data. 2053 * This field is required in order to calculate the length 2054 * of the ResourceSource at runtime. 2055 */ 2056 Descriptor->PinGroupFunction.VendorOffset = (UINT16) 2057 ACPI_PTR_DIFF (VendorData, Descriptor); 2058 2059 if (RsGetVendorData (InitializerOp, VendorData, 2060 (CurrentByteOffset + Descriptor->PinGroupFunction.VendorOffset))) 2061 { 2062 Descriptor->PinGroupFunction.VendorLength = VendorLength; 2063 } 2064 break; 2065 2066 default: 2067 break; 2068 } 2069 2070 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 2071 } 2072 2073 return (Rnode); 2074 } 2075 2076 2077 /******************************************************************************* 2078 * 2079 * FUNCTION: RsDoPinGroupConfigDescriptor 2080 * 2081 * PARAMETERS: Info - Parse Op and resource template offset 2082 * 2083 * RETURN: Completed resource node 2084 * 2085 * DESCRIPTION: Construct a long "PinGroupConfig" descriptor 2086 * 2087 ******************************************************************************/ 2088 2089 ASL_RESOURCE_NODE * 2090 RsDoPinGroupConfigDescriptor ( 2091 ASL_RESOURCE_INFO *Info) 2092 { 2093 AML_RESOURCE *Descriptor; 2094 ACPI_PARSE_OBJECT *InitializerOp; 2095 ASL_RESOURCE_NODE *Rnode; 2096 char *ResourceSource = NULL; 2097 char *ResourceSourceLabel = NULL; 2098 UINT8 *VendorData = NULL; 2099 UINT16 ResSourceLength; 2100 UINT16 ResSourceLabelLength; 2101 UINT16 VendorLength; 2102 UINT16 DescriptorSize; 2103 UINT32 CurrentByteOffset; 2104 UINT32 i; 2105 2106 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 2107 CurrentByteOffset = Info->CurrentByteOffset; 2108 2109 /* 2110 * Calculate lengths for fields that have variable length: 2111 * 1) Resource Source string 2112 * 2) Resource Source Label string 2113 * 3) Vendor Data buffer 2114 */ 2115 ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 3); 2116 ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 5); 2117 VendorLength = RsGetBufferDataLength (InitializerOp); 2118 2119 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_CONFIG) + 2120 ResSourceLength + ResSourceLabelLength + VendorLength; 2121 2122 /* Allocate the local resource node and initialize */ 2123 2124 Rnode = RsAllocateResourceNode (DescriptorSize + 2125 sizeof (AML_RESOURCE_LARGE_HEADER)); 2126 2127 Descriptor = Rnode->Buffer; 2128 Descriptor->PinGroupConfig.ResourceLength = DescriptorSize; 2129 Descriptor->PinGroupConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG; 2130 Descriptor->PinGroupConfig.RevisionId = AML_RESOURCE_PIN_GROUP_CONFIG_REVISION; 2131 2132 /* Build pointers to optional areas */ 2133 2134 ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_CONFIG)); 2135 ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength); 2136 VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength); 2137 2138 /* Setup offsets within the descriptor */ 2139 2140 Descriptor->PinGroupConfig.ResSourceOffset = (UINT16) 2141 ACPI_PTR_DIFF (ResourceSource, Descriptor); 2142 Descriptor->PinGroupConfig.ResSourceLabelOffset = (UINT16) 2143 ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor); 2144 2145 /* Process all child initialization nodes */ 2146 2147 for (i = 0; InitializerOp; i++) 2148 { 2149 BOOLEAN isValid; 2150 2151 switch (i) 2152 { 2153 case 0: /* Share Type [Flags] (_SHR) */ 2154 2155 RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 0, 0); 2156 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 2157 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.Flags), 0); 2158 break; 2159 2160 case 1: /* Pin Config Type [BYTE] (_TYP) */ 2161 2162 isValid = InitializerOp->Asl.Value.Integer <= 0x0d; 2163 if (!isValid) 2164 { 2165 isValid = InitializerOp->Asl.Value.Integer >= 0x80 && 2166 InitializerOp->Asl.Value.Integer <= 0xff; 2167 } 2168 if (!isValid) 2169 { 2170 AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL); 2171 } 2172 2173 Descriptor->PinGroupConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer; 2174 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE, 2175 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigType)); 2176 2177 break; 2178 2179 case 2: /* Pin Config Value [DWORD] (_VAL) */ 2180 2181 Descriptor->PinGroupConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer; 2182 RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE, 2183 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigValue)); 2184 break; 2185 2186 case 3: /* ResourceSource [STRING] */ 2187 2188 /* Copy string to the descriptor */ 2189 2190 strcpy (ResourceSource, InitializerOp->Asl.Value.String); 2191 break; 2192 2193 case 4: /* Resource Index */ 2194 2195 Descriptor->PinGroupConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 2196 break; 2197 2198 case 5: /* ResourceSourceLabel [STRING] */ 2199 2200 if (ResSourceLabelLength < 2) 2201 { 2202 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL); 2203 } 2204 2205 strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String); 2206 break; 2207 2208 case 6: /* Resource Usage (consumer/producer) */ 2209 2210 RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 1, 1); 2211 2212 break; 2213 2214 case 7: /* Resource Tag (Descriptor Name) */ 2215 2216 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 2217 break; 2218 2219 case 8: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 2220 /* 2221 * Always set the VendorOffset even if there is no Vendor Data. 2222 * This field is required in order to calculate the length 2223 * of the ResourceSource at runtime. 2224 */ 2225 Descriptor->PinGroupConfig.VendorOffset = (UINT16) 2226 ACPI_PTR_DIFF (VendorData, Descriptor); 2227 2228 if (RsGetVendorData (InitializerOp, VendorData, 2229 (CurrentByteOffset + Descriptor->PinGroupConfig.VendorOffset))) 2230 { 2231 Descriptor->PinGroupConfig.VendorLength = VendorLength; 2232 } 2233 break; 2234 2235 default: 2236 break; 2237 } 2238 2239 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 2240 } 2241 2242 return (Rnode); 2243 } 2244