aslrestype2s.c revision 316303
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 <contrib/dev/acpica/compiler/aslcompiler.h> 153#include "aslcompiler.y.h" 154#include <contrib/dev/acpica/include/amlcode.h> 155 156#define _COMPONENT ACPI_COMPILER 157 ACPI_MODULE_NAME ("aslrestype2s") 158 159 160static UINT16 161RsGetBufferDataLength ( 162 ACPI_PARSE_OBJECT *InitializerOp); 163 164static UINT16 165RsGetInterruptDataLength ( 166 ACPI_PARSE_OBJECT *InitializerOp); 167 168static BOOLEAN 169RsGetVendorData ( 170 ACPI_PARSE_OBJECT *InitializerOp, 171 UINT8 *VendorData, 172 ACPI_SIZE DescriptorOffset); 173 174/* 175 * This module contains descriptors for serial buses and GPIO: 176 * 177 * GpioInt 178 * GpioIo 179 * I2cSerialBus 180 * SpiSerialBus 181 * UartSerialBus 182 */ 183 184 185/******************************************************************************* 186 * 187 * FUNCTION: RsGetBufferDataLength 188 * 189 * PARAMETERS: InitializerOp - Current parse op, start of the resource 190 * descriptor 191 * 192 * RETURN: Length of the data buffer 193 * 194 * DESCRIPTION: Get the length of a RawDataBuffer, used for vendor data. 195 * 196 ******************************************************************************/ 197 198static UINT16 199RsGetBufferDataLength ( 200 ACPI_PARSE_OBJECT *InitializerOp) 201{ 202 UINT16 ExtraDataSize = 0; 203 ACPI_PARSE_OBJECT *DataList; 204 205 206 /* Find the byte-initializer list */ 207 208 while (InitializerOp) 209 { 210 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DATABUFFER) 211 { 212 /* First child is the optional length (ignore it here) */ 213 214 DataList = InitializerOp->Asl.Child; 215 DataList = ASL_GET_PEER_NODE (DataList); 216 217 /* Count the data items (each one is a byte of data) */ 218 219 while (DataList) 220 { 221 ExtraDataSize++; 222 DataList = ASL_GET_PEER_NODE (DataList); 223 } 224 225 return (ExtraDataSize); 226 } 227 228 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 229 } 230 231 return (ExtraDataSize); 232} 233 234 235/******************************************************************************* 236 * 237 * FUNCTION: RsGetInterruptDataLength 238 * 239 * PARAMETERS: InitializerOp - Current parse op, start of the resource 240 * descriptor 241 * 242 * RETURN: Length of the interrupt data list 243 * 244 * DESCRIPTION: Get the length of a list of interrupt DWORDs for the GPIO 245 * descriptors. 246 * 247 ******************************************************************************/ 248 249static UINT16 250RsGetInterruptDataLength ( 251 ACPI_PARSE_OBJECT *InitializerOp) 252{ 253 UINT16 InterruptLength; 254 UINT32 i; 255 256 257 /* Count the interrupt numbers */ 258 259 InterruptLength = 0; 260 for (i = 0; InitializerOp; i++) 261 { 262 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 263 264 /* Interrupt list starts at offset 10 (Gpio descriptors) */ 265 266 if (i >= 10) 267 { 268 InterruptLength += 2; 269 } 270 } 271 272 return (InterruptLength); 273} 274 275 276/******************************************************************************* 277 * 278 * FUNCTION: RsGetVendorData 279 * 280 * PARAMETERS: InitializerOp - Current parse op, start of the resource 281 * descriptor. 282 * VendorData - Where the vendor data is returned 283 * DescriptorOffset - Where vendor data begins in descriptor 284 * 285 * RETURN: TRUE if valid vendor data was returned, FALSE otherwise. 286 * 287 * DESCRIPTION: Extract the vendor data and construct a vendor data buffer. 288 * 289 ******************************************************************************/ 290 291static BOOLEAN 292RsGetVendorData ( 293 ACPI_PARSE_OBJECT *InitializerOp, 294 UINT8 *VendorData, 295 ACPI_SIZE DescriptorOffset) 296{ 297 ACPI_PARSE_OBJECT *BufferOp; 298 UINT32 SpecifiedLength = ACPI_UINT32_MAX; 299 UINT16 ActualLength = 0; 300 301 302 /* Vendor Data field is always optional */ 303 304 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 305 { 306 return (FALSE); 307 } 308 309 BufferOp = InitializerOp->Asl.Child; 310 if (!BufferOp) 311 { 312 AslError (ASL_ERROR, ASL_MSG_SYNTAX, InitializerOp, ""); 313 return (FALSE); 314 } 315 316 /* First child is the optional buffer length (WORD) */ 317 318 if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 319 { 320 SpecifiedLength = (UINT16) BufferOp->Asl.Value.Integer; 321 } 322 323 /* Insert field tag _VEN */ 324 325 RsCreateByteField (InitializerOp, ACPI_RESTAG_VENDORDATA, 326 (UINT16) DescriptorOffset); 327 328 /* Walk the list of buffer initializers (each is one byte) */ 329 330 BufferOp = RsCompleteNodeAndGetNext (BufferOp); 331 if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 332 { 333 while (BufferOp) 334 { 335 *VendorData = (UINT8) BufferOp->Asl.Value.Integer; 336 VendorData++; 337 ActualLength++; 338 BufferOp = RsCompleteNodeAndGetNext (BufferOp); 339 } 340 } 341 342 /* Length validation. Buffer cannot be of zero length */ 343 344 if ((SpecifiedLength == 0) || 345 ((SpecifiedLength == ACPI_UINT32_MAX) && (ActualLength == 0))) 346 { 347 AslError (ASL_ERROR, ASL_MSG_BUFFER_LENGTH, InitializerOp, NULL); 348 return (FALSE); 349 } 350 351 if (SpecifiedLength != ACPI_UINT32_MAX) 352 { 353 /* ActualLength > SpecifiedLength -> error */ 354 355 if (ActualLength > SpecifiedLength) 356 { 357 AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG, InitializerOp, NULL); 358 return (FALSE); 359 } 360 361 /* ActualLength < SpecifiedLength -> remark */ 362 363 else if (ActualLength < SpecifiedLength) 364 { 365 AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT, InitializerOp, NULL); 366 return (FALSE); 367 } 368 } 369 370 return (TRUE); 371} 372 373 374/******************************************************************************* 375 * 376 * FUNCTION: RsDoGpioIntDescriptor 377 * 378 * PARAMETERS: Info - Parse Op and resource template offset 379 * 380 * RETURN: Completed resource node 381 * 382 * DESCRIPTION: Construct a long "GpioInt" descriptor 383 * 384 ******************************************************************************/ 385 386ASL_RESOURCE_NODE * 387RsDoGpioIntDescriptor ( 388 ASL_RESOURCE_INFO *Info) 389{ 390 AML_RESOURCE *Descriptor; 391 ACPI_PARSE_OBJECT *InitializerOp; 392 ASL_RESOURCE_NODE *Rnode; 393 char *ResourceSource = NULL; 394 UINT8 *VendorData = NULL; 395 UINT16 *InterruptList = NULL; 396 UINT16 *PinList = NULL; 397 UINT16 ResSourceLength; 398 UINT16 VendorLength; 399 UINT16 InterruptLength; 400 UINT16 DescriptorSize; 401 UINT32 CurrentByteOffset; 402 UINT32 PinCount = 0; 403 UINT32 i; 404 405 406 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 407 CurrentByteOffset = Info->CurrentByteOffset; 408 409 /* 410 * Calculate lengths for fields that have variable length: 411 * 1) Resource Source string 412 * 2) Vendor Data buffer 413 * 3) PIN (interrupt) list 414 */ 415 ResSourceLength = RsGetStringDataLength (InitializerOp); 416 VendorLength = RsGetBufferDataLength (InitializerOp); 417 InterruptLength = RsGetInterruptDataLength (InitializerOp); 418 419 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) + 420 ResSourceLength + VendorLength + InterruptLength; 421 422 /* Allocate the local resource node and initialize */ 423 424 Rnode = RsAllocateResourceNode (DescriptorSize + 425 sizeof (AML_RESOURCE_LARGE_HEADER)); 426 427 Descriptor = Rnode->Buffer; 428 Descriptor->Gpio.ResourceLength = DescriptorSize; 429 Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO; 430 Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION; 431 Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_INT; 432 433 /* Build pointers to optional areas */ 434 435 InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, 436 sizeof (AML_RESOURCE_GPIO)); 437 PinList = InterruptList; 438 ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength); 439 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 440 441 /* Setup offsets within the descriptor */ 442 443 Descriptor->Gpio.PinTableOffset = (UINT16) 444 ACPI_PTR_DIFF (InterruptList, Descriptor); 445 446 Descriptor->Gpio.ResSourceOffset = (UINT16) 447 ACPI_PTR_DIFF (ResourceSource, Descriptor); 448 449 /* Process all child initialization nodes */ 450 451 for (i = 0; InitializerOp; i++) 452 { 453 switch (i) 454 { 455 case 0: /* Interrupt Mode - edge/level [Flag] (_MOD) */ 456 457 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0); 458 RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE, 459 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0); 460 break; 461 462 case 1: /* Interrupt Polarity - Active high/low [Flags] (_POL) */ 463 464 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 1, 0); 465 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_POLARITY, 466 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 1, 2); 467 break; 468 469 case 2: /* Share Type - Default: exclusive (0) [Flags] (_SHR) */ 470 471 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0); 472 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 473 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3, 2); 474 break; 475 476 case 3: /* Pin Config [BYTE] (_PPI) */ 477 478 Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer; 479 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG, 480 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig)); 481 break; 482 483 case 4: /* Debounce Timeout [WORD] (_DBT) */ 484 485 Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer; 486 RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME, 487 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout)); 488 break; 489 490 case 5: /* ResSource [Optional Field - STRING] */ 491 492 if (ResSourceLength) 493 { 494 /* Copy string to the descriptor */ 495 496 strcpy (ResourceSource, 497 InitializerOp->Asl.Value.String); 498 } 499 break; 500 501 case 6: /* Resource Index */ 502 503 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 504 { 505 Descriptor->Gpio.ResSourceIndex = 506 (UINT8) InitializerOp->Asl.Value.Integer; 507 } 508 break; 509 510 case 7: /* Resource Usage (consumer/producer) */ 511 512 RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1); 513 break; 514 515 case 8: /* Resource Tag (Descriptor Name) */ 516 517 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 518 break; 519 520 case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 521 522 /* 523 * Always set the VendorOffset even if there is no Vendor Data. 524 * This field is required in order to calculate the length 525 * of the ResourceSource at runtime. 526 */ 527 Descriptor->Gpio.VendorOffset = (UINT16) 528 ACPI_PTR_DIFF (VendorData, Descriptor); 529 530 if (RsGetVendorData (InitializerOp, VendorData, 531 (CurrentByteOffset + Descriptor->Gpio.VendorOffset))) 532 { 533 Descriptor->Gpio.VendorLength = VendorLength; 534 } 535 break; 536 537 default: 538 /* 539 * PINs come through here, repeatedly. Each PIN must be a WORD. 540 * NOTE: there is no "length" field for this, so from ACPI spec: 541 * The number of pins in the table can be calculated from: 542 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 543 * (implies resource source must immediately follow the pin list.) 544 * Name: _PIN 545 */ 546 *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer; 547 InterruptList++; 548 PinCount++; 549 550 /* Case 10: First interrupt number in list */ 551 552 if (i == 10) 553 { 554 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 555 { 556 /* Must be at least one interrupt */ 557 558 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 559 InitializerOp, NULL); 560 } 561 562 /* Check now for duplicates in list */ 563 564 RsCheckListForDuplicates (InitializerOp); 565 566 /* Create a named field at the start of the list */ 567 568 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 569 CurrentByteOffset + Descriptor->Gpio.PinTableOffset); 570 } 571 break; 572 } 573 574 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 575 } 576 577 MpSaveGpioInfo (Info->MappingOp, Descriptor, 578 PinCount, PinList, ResourceSource); 579 return (Rnode); 580} 581 582 583/******************************************************************************* 584 * 585 * FUNCTION: RsDoGpioIoDescriptor 586 * 587 * PARAMETERS: Info - Parse Op and resource template offset 588 * 589 * RETURN: Completed resource node 590 * 591 * DESCRIPTION: Construct a long "GpioIo" descriptor 592 * 593 ******************************************************************************/ 594 595ASL_RESOURCE_NODE * 596RsDoGpioIoDescriptor ( 597 ASL_RESOURCE_INFO *Info) 598{ 599 AML_RESOURCE *Descriptor; 600 ACPI_PARSE_OBJECT *InitializerOp; 601 ASL_RESOURCE_NODE *Rnode; 602 char *ResourceSource = NULL; 603 UINT8 *VendorData = NULL; 604 UINT16 *InterruptList = NULL; 605 UINT16 *PinList = NULL; 606 UINT16 ResSourceLength; 607 UINT16 VendorLength; 608 UINT16 InterruptLength; 609 UINT16 DescriptorSize; 610 UINT32 CurrentByteOffset; 611 UINT32 PinCount = 0; 612 UINT32 i; 613 614 615 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 616 CurrentByteOffset = Info->CurrentByteOffset; 617 618 /* 619 * Calculate lengths for fields that have variable length: 620 * 1) Resource Source string 621 * 2) Vendor Data buffer 622 * 3) PIN (interrupt) list 623 */ 624 ResSourceLength = RsGetStringDataLength (InitializerOp); 625 VendorLength = RsGetBufferDataLength (InitializerOp); 626 InterruptLength = RsGetInterruptDataLength (InitializerOp); 627 PinList = InterruptList; 628 629 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) + 630 ResSourceLength + VendorLength + InterruptLength; 631 632 /* Allocate the local resource node and initialize */ 633 634 Rnode = RsAllocateResourceNode (DescriptorSize + 635 sizeof (AML_RESOURCE_LARGE_HEADER)); 636 637 Descriptor = Rnode->Buffer; 638 Descriptor->Gpio.ResourceLength = DescriptorSize; 639 Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO; 640 Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION; 641 Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_IO; 642 643 /* Build pointers to optional areas */ 644 645 InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO)); 646 PinList = InterruptList; 647 ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength); 648 VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); 649 650 /* Setup offsets within the descriptor */ 651 652 Descriptor->Gpio.PinTableOffset = (UINT16) 653 ACPI_PTR_DIFF (InterruptList, Descriptor); 654 655 Descriptor->Gpio.ResSourceOffset = (UINT16) 656 ACPI_PTR_DIFF (ResourceSource, Descriptor); 657 658 /* Process all child initialization nodes */ 659 660 for (i = 0; InitializerOp; i++) 661 { 662 switch (i) 663 { 664 case 0: /* Share Type [Flags] (_SHR) */ 665 666 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0); 667 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 668 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3); 669 break; 670 671 case 1: /* Pin Config [BYTE] (_PPI) */ 672 673 Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer; 674 RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG, 675 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig)); 676 break; 677 678 case 2: /* Debounce Timeout [WORD] (_DBT) */ 679 680 Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer; 681 RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME, 682 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout)); 683 break; 684 685 case 3: /* Drive Strength [WORD] (_DRS) */ 686 687 Descriptor->Gpio.DriveStrength = (UINT16) InitializerOp->Asl.Value.Integer; 688 RsCreateWordField (InitializerOp, ACPI_RESTAG_DRIVESTRENGTH, 689 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DriveStrength)); 690 break; 691 692 case 4: /* I/O Restriction [Flag] (_IOR) */ 693 694 RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0); 695 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_IORESTRICTION, 696 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0, 2); 697 break; 698 699 case 5: /* ResSource [Optional Field - STRING] */ 700 701 if (ResSourceLength) 702 { 703 /* Copy string to the descriptor */ 704 705 strcpy (ResourceSource, 706 InitializerOp->Asl.Value.String); 707 } 708 break; 709 710 case 6: /* Resource Index */ 711 712 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 713 { 714 Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 715 } 716 break; 717 718 case 7: /* Resource Usage (consumer/producer) */ 719 720 RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1); 721 break; 722 723 case 8: /* Resource Tag (Descriptor Name) */ 724 725 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 726 break; 727 728 case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 729 /* 730 * Always set the VendorOffset even if there is no Vendor Data. 731 * This field is required in order to calculate the length 732 * of the ResourceSource at runtime. 733 */ 734 Descriptor->Gpio.VendorOffset = (UINT16) 735 ACPI_PTR_DIFF (VendorData, Descriptor); 736 737 if (RsGetVendorData (InitializerOp, VendorData, 738 (CurrentByteOffset + Descriptor->Gpio.VendorOffset))) 739 { 740 Descriptor->Gpio.VendorLength = VendorLength; 741 } 742 break; 743 744 default: 745 /* 746 * PINs come through here, repeatedly. Each PIN must be a WORD. 747 * NOTE: there is no "length" field for this, so from ACPI spec: 748 * The number of pins in the table can be calculated from: 749 * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 750 * (implies resource source must immediately follow the pin list.) 751 * Name: _PIN 752 */ 753 *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer; 754 InterruptList++; 755 PinCount++; 756 757 /* Case 10: First interrupt number in list */ 758 759 if (i == 10) 760 { 761 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 762 { 763 /* Must be at least one interrupt */ 764 765 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 766 InitializerOp, NULL); 767 } 768 769 /* Check now for duplicates in list */ 770 771 RsCheckListForDuplicates (InitializerOp); 772 773 /* Create a named field at the start of the list */ 774 775 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN, 776 CurrentByteOffset + Descriptor->Gpio.PinTableOffset); 777 } 778 break; 779 } 780 781 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 782 } 783 784 MpSaveGpioInfo (Info->MappingOp, Descriptor, 785 PinCount, PinList, ResourceSource); 786 return (Rnode); 787} 788 789 790/******************************************************************************* 791 * 792 * FUNCTION: RsDoI2cSerialBusDescriptor 793 * 794 * PARAMETERS: Info - Parse Op and resource template offset 795 * 796 * RETURN: Completed resource node 797 * 798 * DESCRIPTION: Construct a long "I2cSerialBus" descriptor 799 * 800 ******************************************************************************/ 801 802ASL_RESOURCE_NODE * 803RsDoI2cSerialBusDescriptor ( 804 ASL_RESOURCE_INFO *Info) 805{ 806 AML_RESOURCE *Descriptor; 807 ACPI_PARSE_OBJECT *InitializerOp; 808 ASL_RESOURCE_NODE *Rnode; 809 char *ResourceSource = NULL; 810 UINT8 *VendorData = NULL; 811 UINT16 ResSourceLength; 812 UINT16 VendorLength; 813 UINT16 DescriptorSize; 814 UINT32 CurrentByteOffset; 815 UINT32 i; 816 817 818 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 819 CurrentByteOffset = Info->CurrentByteOffset; 820 821 /* 822 * Calculate lengths for fields that have variable length: 823 * 1) Resource Source string 824 * 2) Vendor Data buffer 825 */ 826 ResSourceLength = RsGetStringDataLength (InitializerOp); 827 VendorLength = RsGetBufferDataLength (InitializerOp); 828 829 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS) + 830 ResSourceLength + VendorLength; 831 832 /* Allocate the local resource node and initialize */ 833 834 Rnode = RsAllocateResourceNode (DescriptorSize + 835 sizeof (AML_RESOURCE_LARGE_HEADER)); 836 837 Descriptor = Rnode->Buffer; 838 Descriptor->I2cSerialBus.ResourceLength = DescriptorSize; 839 Descriptor->I2cSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 840 Descriptor->I2cSerialBus.RevisionId = AML_RESOURCE_I2C_REVISION; 841 Descriptor->I2cSerialBus.TypeRevisionId = AML_RESOURCE_I2C_TYPE_REVISION; 842 Descriptor->I2cSerialBus.Type = AML_RESOURCE_I2C_SERIALBUSTYPE; 843 Descriptor->I2cSerialBus.TypeDataLength = AML_RESOURCE_I2C_MIN_DATA_LEN + VendorLength; 844 845 if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_I2C_SERIALBUS_V2) 846 { 847 Descriptor->I2cSerialBus.RevisionId = 2; 848 } 849 850 /* Build pointers to optional areas */ 851 852 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_I2C_SERIALBUS)); 853 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 854 855 /* Process all child initialization nodes */ 856 857 for (i = 0; InitializerOp; i++) 858 { 859 switch (i) 860 { 861 case 0: /* Slave Address [WORD] (_ADR) */ 862 863 Descriptor->I2cSerialBus.SlaveAddress = (UINT16) InitializerOp->Asl.Value.Integer; 864 RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS, 865 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.SlaveAddress)); 866 break; 867 868 case 1: /* Slave Mode [Flag] (_SLV) */ 869 870 RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 0, 0); 871 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 872 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0); 873 break; 874 875 case 2: /* Connection Speed [DWORD] (_SPE) */ 876 877 Descriptor->I2cSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer; 878 RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, 879 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.ConnectionSpeed)); 880 break; 881 882 case 3: /* Addressing Mode [Flag] (_MOD) */ 883 884 RsSetFlagBits16 (&Descriptor->I2cSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 885 RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE, 886 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.TypeSpecificFlags), 0); 887 break; 888 889 case 4: /* ResSource [Optional Field - STRING] */ 890 891 if (ResSourceLength) 892 { 893 /* Copy string to the descriptor */ 894 895 strcpy (ResourceSource, 896 InitializerOp->Asl.Value.String); 897 } 898 break; 899 900 case 5: /* Resource Index */ 901 902 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 903 { 904 Descriptor->I2cSerialBus.ResSourceIndex = 905 (UINT8) InitializerOp->Asl.Value.Integer; 906 } 907 break; 908 909 case 6: /* Resource Usage (consumer/producer) */ 910 911 RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 1, 1); 912 break; 913 914 case 7: /* Resource Tag (Descriptor Name) */ 915 916 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 917 break; 918 919 case 8: 920 /* 921 * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor 922 * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from 923 * the ASL parser) 924 */ 925 RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 2, 0); 926 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 927 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 2); 928 break; 929 930 case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 931 932 RsGetVendorData (InitializerOp, VendorData, 933 CurrentByteOffset + sizeof (AML_RESOURCE_I2C_SERIALBUS)); 934 break; 935 936 default: /* Ignore any extra nodes */ 937 938 break; 939 } 940 941 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 942 } 943 944 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 945 return (Rnode); 946} 947 948 949/******************************************************************************* 950 * 951 * FUNCTION: RsDoSpiSerialBusDescriptor 952 * 953 * PARAMETERS: Info - Parse Op and resource template offset 954 * 955 * RETURN: Completed resource node 956 * 957 * DESCRIPTION: Construct a long "SPI Serial Bus" descriptor 958 * 959 ******************************************************************************/ 960 961ASL_RESOURCE_NODE * 962RsDoSpiSerialBusDescriptor ( 963 ASL_RESOURCE_INFO *Info) 964{ 965 AML_RESOURCE *Descriptor; 966 ACPI_PARSE_OBJECT *InitializerOp; 967 ASL_RESOURCE_NODE *Rnode; 968 char *ResourceSource = NULL; 969 UINT8 *VendorData = NULL; 970 UINT16 ResSourceLength; 971 UINT16 VendorLength; 972 UINT16 DescriptorSize; 973 UINT32 CurrentByteOffset; 974 UINT32 i; 975 976 977 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 978 CurrentByteOffset = Info->CurrentByteOffset; 979 980 /* 981 * Calculate lengths for fields that have variable length: 982 * 1) Resource Source string 983 * 2) Vendor Data buffer 984 */ 985 ResSourceLength = RsGetStringDataLength (InitializerOp); 986 VendorLength = RsGetBufferDataLength (InitializerOp); 987 988 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS) + 989 ResSourceLength + VendorLength; 990 991 /* Allocate the local resource node and initialize */ 992 993 Rnode = RsAllocateResourceNode (DescriptorSize + 994 sizeof (AML_RESOURCE_LARGE_HEADER)); 995 996 Descriptor = Rnode->Buffer; 997 Descriptor->SpiSerialBus.ResourceLength = DescriptorSize; 998 Descriptor->SpiSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 999 Descriptor->SpiSerialBus.RevisionId = AML_RESOURCE_SPI_REVISION; 1000 Descriptor->SpiSerialBus.TypeRevisionId = AML_RESOURCE_SPI_TYPE_REVISION; 1001 Descriptor->SpiSerialBus.Type = AML_RESOURCE_SPI_SERIALBUSTYPE; 1002 Descriptor->SpiSerialBus.TypeDataLength = AML_RESOURCE_SPI_MIN_DATA_LEN + VendorLength; 1003 1004 if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_SPI_SERIALBUS_V2) 1005 { 1006 Descriptor->I2cSerialBus.RevisionId = 2; 1007 } 1008 1009 /* Build pointers to optional areas */ 1010 1011 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, 1012 sizeof (AML_RESOURCE_SPI_SERIALBUS)); 1013 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 1014 1015 /* Process all child initialization nodes */ 1016 1017 for (i = 0; InitializerOp; i++) 1018 { 1019 switch (i) 1020 { 1021 case 0: /* Device Selection [WORD] (_ADR) */ 1022 1023 Descriptor->SpiSerialBus.DeviceSelection = (UINT16) InitializerOp->Asl.Value.Integer; 1024 RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS, 1025 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DeviceSelection)); 1026 break; 1027 1028 case 1: /* Device Polarity [Flag] (_DPL) */ 1029 1030 RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 1, 0); 1031 RsCreateBitField (InitializerOp, ACPI_RESTAG_DEVICEPOLARITY, 1032 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 1); 1033 break; 1034 1035 case 2: /* Wire Mode [Flag] (_MOD) */ 1036 1037 RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 1038 RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE, 1039 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 0); 1040 break; 1041 1042 case 3: /* Device Bit Length [BYTE] (_LEN) */ 1043 1044 Descriptor->SpiSerialBus.DataBitLength = (UINT8) InitializerOp->Asl.Value.Integer; 1045 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH, 1046 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DataBitLength)); 1047 break; 1048 1049 case 4: /* Slave Mode [Flag] (_SLV) */ 1050 1051 RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 0, 0); 1052 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 1053 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 0); 1054 break; 1055 1056 case 5: /* Connection Speed [DWORD] (_SPE) */ 1057 1058 Descriptor->SpiSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer; 1059 RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, 1060 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ConnectionSpeed)); 1061 break; 1062 1063 case 6: /* Clock Polarity [BYTE] (_POL) */ 1064 1065 Descriptor->SpiSerialBus.ClockPolarity = (UINT8) InitializerOp->Asl.Value.Integer; 1066 RsCreateByteField (InitializerOp, ACPI_RESTAG_POLARITY, 1067 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPolarity)); 1068 break; 1069 1070 case 7: /* Clock Phase [BYTE] (_PHA) */ 1071 1072 Descriptor->SpiSerialBus.ClockPhase = (UINT8) InitializerOp->Asl.Value.Integer; 1073 RsCreateByteField (InitializerOp, ACPI_RESTAG_PHASE, 1074 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPhase)); 1075 break; 1076 1077 case 8: /* ResSource [Optional Field - STRING] */ 1078 1079 if (ResSourceLength) 1080 { 1081 /* Copy string to the descriptor */ 1082 1083 strcpy (ResourceSource, 1084 InitializerOp->Asl.Value.String); 1085 } 1086 break; 1087 1088 case 9: /* Resource Index */ 1089 1090 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1091 { 1092 Descriptor->SpiSerialBus.ResSourceIndex = 1093 (UINT8) InitializerOp->Asl.Value.Integer; 1094 } 1095 break; 1096 1097 case 10: /* Resource Usage (consumer/producer) */ 1098 1099 RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 1, 1); 1100 break; 1101 1102 case 11: /* Resource Tag (Descriptor Name) */ 1103 1104 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1105 break; 1106 1107 case 12: 1108 /* 1109 * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor 1110 * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from 1111 * the ASL parser) 1112 */ 1113 RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 2, 0); 1114 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1115 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 2); 1116 break; 1117 1118 case 13: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1119 1120 RsGetVendorData (InitializerOp, VendorData, 1121 CurrentByteOffset + sizeof (AML_RESOURCE_SPI_SERIALBUS)); 1122 break; 1123 1124 default: /* Ignore any extra nodes */ 1125 1126 break; 1127 } 1128 1129 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1130 } 1131 1132 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 1133 return (Rnode); 1134} 1135 1136 1137/******************************************************************************* 1138 * 1139 * FUNCTION: RsDoUartSerialBusDescriptor 1140 * 1141 * PARAMETERS: Info - Parse Op and resource template offset 1142 * 1143 * RETURN: Completed resource node 1144 * 1145 * DESCRIPTION: Construct a long "UART Serial Bus" descriptor 1146 * 1147 ******************************************************************************/ 1148 1149ASL_RESOURCE_NODE * 1150RsDoUartSerialBusDescriptor ( 1151 ASL_RESOURCE_INFO *Info) 1152{ 1153 AML_RESOURCE *Descriptor; 1154 ACPI_PARSE_OBJECT *InitializerOp; 1155 ASL_RESOURCE_NODE *Rnode; 1156 char *ResourceSource = NULL; 1157 UINT8 *VendorData = NULL; 1158 UINT16 ResSourceLength; 1159 UINT16 VendorLength; 1160 UINT16 DescriptorSize; 1161 UINT32 CurrentByteOffset; 1162 UINT32 i; 1163 1164 1165 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 1166 CurrentByteOffset = Info->CurrentByteOffset; 1167 1168 /* 1169 * Calculate lengths for fields that have variable length: 1170 * 1) Resource Source string 1171 * 2) Vendor Data buffer 1172 */ 1173 ResSourceLength = RsGetStringDataLength (InitializerOp); 1174 VendorLength = RsGetBufferDataLength (InitializerOp); 1175 1176 DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS) + 1177 ResSourceLength + VendorLength; 1178 1179 /* Allocate the local resource node and initialize */ 1180 1181 Rnode = RsAllocateResourceNode (DescriptorSize + 1182 sizeof (AML_RESOURCE_LARGE_HEADER)); 1183 1184 Descriptor = Rnode->Buffer; 1185 Descriptor->UartSerialBus.ResourceLength = DescriptorSize; 1186 Descriptor->UartSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; 1187 Descriptor->UartSerialBus.RevisionId = AML_RESOURCE_UART_REVISION; 1188 Descriptor->UartSerialBus.TypeRevisionId = AML_RESOURCE_UART_TYPE_REVISION; 1189 Descriptor->UartSerialBus.Type = AML_RESOURCE_UART_SERIALBUSTYPE; 1190 Descriptor->UartSerialBus.TypeDataLength = AML_RESOURCE_UART_MIN_DATA_LEN + VendorLength; 1191 1192 if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_UART_SERIALBUS_V2) 1193 { 1194 Descriptor->I2cSerialBus.RevisionId = 2; 1195 } 1196 1197 /* Build pointers to optional areas */ 1198 1199 VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_UART_SERIALBUS)); 1200 ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); 1201 1202 /* Process all child initialization nodes */ 1203 1204 for (i = 0; InitializerOp; i++) 1205 { 1206 switch (i) 1207 { 1208 case 0: /* Connection Speed (Baud Rate) [DWORD] (_SPE) */ 1209 1210 Descriptor->UartSerialBus.DefaultBaudRate = (UINT32) InitializerOp->Asl.Value.Integer; 1211 RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, 1212 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.DefaultBaudRate)); 1213 break; 1214 1215 case 1: /* Bits Per Byte [Flags] (_LEN) */ 1216 1217 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 4, 3); 1218 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LENGTH, 1219 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 4, 3); 1220 break; 1221 1222 case 2: /* Stop Bits [Flags] (_STB) */ 1223 1224 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 2, 1); 1225 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_STOPBITS, 1226 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 2, 2); 1227 break; 1228 1229 case 3: /* Lines In Use [BYTE] (_LIN) */ 1230 1231 Descriptor->UartSerialBus.LinesEnabled = (UINT8) InitializerOp->Asl.Value.Integer; 1232 RsCreateByteField (InitializerOp, ACPI_RESTAG_LINE, 1233 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.LinesEnabled)); 1234 break; 1235 1236 case 4: /* Endianness [Flag] (_END) */ 1237 1238 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 7, 0); 1239 RsCreateBitField (InitializerOp, ACPI_RESTAG_ENDIANNESS, 1240 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 7); 1241 break; 1242 1243 case 5: /* Parity [BYTE] (_PAR) */ 1244 1245 Descriptor->UartSerialBus.Parity = (UINT8) InitializerOp->Asl.Value.Integer; 1246 RsCreateByteField (InitializerOp, ACPI_RESTAG_PARITY, 1247 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Parity)); 1248 break; 1249 1250 case 6: /* Flow Control [Flags] (_FLC) */ 1251 1252 RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); 1253 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_FLOWCONTROL, 1254 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 0, 2); 1255 break; 1256 1257 case 7: /* Rx Buffer Size [WORD] (_RXL) */ 1258 1259 Descriptor->UartSerialBus.RxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer; 1260 RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_RX, 1261 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.RxFifoSize)); 1262 break; 1263 1264 case 8: /* Tx Buffer Size [WORD] (_TXL) */ 1265 1266 Descriptor->UartSerialBus.TxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer; 1267 RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_TX, 1268 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TxFifoSize)); 1269 break; 1270 1271 case 9: /* ResSource [Optional Field - STRING] */ 1272 1273 if (ResSourceLength) 1274 { 1275 /* Copy string to the descriptor */ 1276 1277 strcpy (ResourceSource, 1278 InitializerOp->Asl.Value.String); 1279 } 1280 break; 1281 1282 case 10: /* Resource Index */ 1283 1284 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 1285 { 1286 Descriptor->UartSerialBus.ResSourceIndex = 1287 (UINT8) InitializerOp->Asl.Value.Integer; 1288 } 1289 break; 1290 1291 case 11: /* Resource Usage (consumer/producer) */ 1292 1293 RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 1, 1); 1294 1295 /* 1296 * Slave Mode [Flag] (_SLV) 1297 * 1298 * Note: There is no SlaveMode argument to the UartSerialBus macro, but 1299 * we add this name anyway to allow the flag to be set by ASL in the 1300 * rare case where there is a slave mode associated with the UART. 1301 */ 1302 RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, 1303 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 0); 1304 break; 1305 1306 case 12: /* Resource Tag (Descriptor Name) */ 1307 1308 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 1309 break; 1310 1311 case 13: 1312 /* 1313 * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor 1314 * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from 1315 * the ASL parser) 1316 */ 1317 RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 2, 0); 1318 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 1319 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 2); 1320 break; 1321 1322 case 14: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ 1323 1324 RsGetVendorData (InitializerOp, VendorData, 1325 CurrentByteOffset + sizeof (AML_RESOURCE_UART_SERIALBUS)); 1326 break; 1327 1328 default: /* Ignore any extra nodes */ 1329 1330 break; 1331 } 1332 1333 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 1334 } 1335 1336 MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); 1337 return (Rnode); 1338} 1339