1 /****************************************************************************** 2 * 3 * Module Name: dttable1.c - handling for specific ACPI tables 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 /* Compile all complex data tables, signatures starting with A-I */ 153 154 #include <contrib/dev/acpica/compiler/aslcompiler.h> 155 #include <contrib/dev/acpica/compiler/dtcompiler.h> 156 157 #define _COMPONENT DT_COMPILER 158 ACPI_MODULE_NAME ("dttable1") 159 160 161 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] = 162 { 163 {ACPI_DMT_BUFFER, 0, "Addresses", 0}, 164 {ACPI_DMT_EXIT, 0, NULL, 0} 165 }; 166 167 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] = 168 { 169 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0}, 170 {ACPI_DMT_EXIT, 0, NULL, 0} 171 }; 172 173 174 /****************************************************************************** 175 * 176 * FUNCTION: DtCompileAsf 177 * 178 * PARAMETERS: List - Current field list pointer 179 * 180 * RETURN: Status 181 * 182 * DESCRIPTION: Compile ASF!. 183 * 184 *****************************************************************************/ 185 186 ACPI_STATUS 187 DtCompileAsf ( 188 void **List) 189 { 190 ACPI_ASF_INFO *AsfTable; 191 DT_SUBTABLE *Subtable; 192 DT_SUBTABLE *ParentTable; 193 ACPI_DMTABLE_INFO *InfoTable; 194 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 195 UINT32 DataCount = 0; 196 ACPI_STATUS Status; 197 UINT32 i; 198 DT_FIELD **PFieldList = (DT_FIELD **) List; 199 DT_FIELD *SubtableStart; 200 201 202 while (*PFieldList) 203 { 204 SubtableStart = *PFieldList; 205 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 206 &Subtable, TRUE); 207 if (ACPI_FAILURE (Status)) 208 { 209 return (Status); 210 } 211 212 ParentTable = DtPeekSubtable (); 213 DtInsertSubtable (ParentTable, Subtable); 214 DtPushSubtable (Subtable); 215 216 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 217 218 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 219 { 220 case ACPI_ASF_TYPE_INFO: 221 222 InfoTable = AcpiDmTableInfoAsf0; 223 break; 224 225 case ACPI_ASF_TYPE_ALERT: 226 227 InfoTable = AcpiDmTableInfoAsf1; 228 break; 229 230 case ACPI_ASF_TYPE_CONTROL: 231 232 InfoTable = AcpiDmTableInfoAsf2; 233 break; 234 235 case ACPI_ASF_TYPE_BOOT: 236 237 InfoTable = AcpiDmTableInfoAsf3; 238 break; 239 240 case ACPI_ASF_TYPE_ADDRESS: 241 242 InfoTable = AcpiDmTableInfoAsf4; 243 break; 244 245 default: 246 247 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 248 return (AE_ERROR); 249 } 250 251 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 252 if (ACPI_FAILURE (Status)) 253 { 254 return (Status); 255 } 256 257 ParentTable = DtPeekSubtable (); 258 DtInsertSubtable (ParentTable, Subtable); 259 260 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 261 { 262 case ACPI_ASF_TYPE_INFO: 263 264 DataInfoTable = NULL; 265 break; 266 267 case ACPI_ASF_TYPE_ALERT: 268 269 DataInfoTable = AcpiDmTableInfoAsf1a; 270 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 271 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 272 sizeof (ACPI_ASF_HEADER)))->Alerts; 273 break; 274 275 case ACPI_ASF_TYPE_CONTROL: 276 277 DataInfoTable = AcpiDmTableInfoAsf2a; 278 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 279 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 280 sizeof (ACPI_ASF_HEADER)))->Controls; 281 break; 282 283 case ACPI_ASF_TYPE_BOOT: 284 285 DataInfoTable = NULL; 286 break; 287 288 case ACPI_ASF_TYPE_ADDRESS: 289 290 DataInfoTable = TableInfoAsfAddress; 291 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 292 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 293 sizeof (ACPI_ASF_HEADER)))->Devices; 294 break; 295 296 default: 297 298 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 299 return (AE_ERROR); 300 } 301 302 if (DataInfoTable) 303 { 304 switch (AsfTable->Header.Type & 0x7F) 305 { 306 case ACPI_ASF_TYPE_ADDRESS: 307 308 while (DataCount > 0) 309 { 310 Status = DtCompileTable (PFieldList, DataInfoTable, 311 &Subtable, TRUE); 312 if (ACPI_FAILURE (Status)) 313 { 314 return (Status); 315 } 316 317 DtInsertSubtable (ParentTable, Subtable); 318 DataCount = DataCount - Subtable->Length; 319 } 320 break; 321 322 default: 323 324 for (i = 0; i < DataCount; i++) 325 { 326 Status = DtCompileTable (PFieldList, DataInfoTable, 327 &Subtable, TRUE); 328 if (ACPI_FAILURE (Status)) 329 { 330 return (Status); 331 } 332 333 DtInsertSubtable (ParentTable, Subtable); 334 } 335 break; 336 } 337 } 338 339 DtPopSubtable (); 340 } 341 342 return (AE_OK); 343 } 344 345 346 /****************************************************************************** 347 * 348 * FUNCTION: DtCompileCpep 349 * 350 * PARAMETERS: List - Current field list pointer 351 * 352 * RETURN: Status 353 * 354 * DESCRIPTION: Compile CPEP. 355 * 356 *****************************************************************************/ 357 358 ACPI_STATUS 359 DtCompileCpep ( 360 void **List) 361 { 362 ACPI_STATUS Status; 363 364 365 Status = DtCompileTwoSubtables (List, 366 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 367 return (Status); 368 } 369 370 371 /****************************************************************************** 372 * 373 * FUNCTION: DtCompileCsrt 374 * 375 * PARAMETERS: List - Current field list pointer 376 * 377 * RETURN: Status 378 * 379 * DESCRIPTION: Compile CSRT. 380 * 381 *****************************************************************************/ 382 383 ACPI_STATUS 384 DtCompileCsrt ( 385 void **List) 386 { 387 ACPI_STATUS Status = AE_OK; 388 DT_SUBTABLE *Subtable; 389 DT_SUBTABLE *ParentTable; 390 DT_FIELD **PFieldList = (DT_FIELD **) List; 391 UINT32 DescriptorCount; 392 UINT32 GroupLength; 393 394 395 /* Subtables (Resource Groups) */ 396 397 ParentTable = DtPeekSubtable (); 398 while (*PFieldList) 399 { 400 /* Resource group subtable */ 401 402 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 403 &Subtable, TRUE); 404 if (ACPI_FAILURE (Status)) 405 { 406 return (Status); 407 } 408 409 /* Compute the number of resource descriptors */ 410 411 GroupLength = 412 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 413 Subtable->Buffer))->Length - 414 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 415 Subtable->Buffer))->SharedInfoLength - 416 sizeof (ACPI_CSRT_GROUP); 417 418 DescriptorCount = (GroupLength / 419 sizeof (ACPI_CSRT_DESCRIPTOR)); 420 421 DtInsertSubtable (ParentTable, Subtable); 422 DtPushSubtable (Subtable); 423 ParentTable = DtPeekSubtable (); 424 425 /* Shared info subtable (One per resource group) */ 426 427 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 428 &Subtable, TRUE); 429 if (ACPI_FAILURE (Status)) 430 { 431 return (Status); 432 } 433 434 DtInsertSubtable (ParentTable, Subtable); 435 436 /* Sub-Subtables (Resource Descriptors) */ 437 438 while (*PFieldList && DescriptorCount) 439 { 440 441 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 442 &Subtable, TRUE); 443 if (ACPI_FAILURE (Status)) 444 { 445 return (Status); 446 } 447 448 DtInsertSubtable (ParentTable, Subtable); 449 450 DtPushSubtable (Subtable); 451 ParentTable = DtPeekSubtable (); 452 if (*PFieldList) 453 { 454 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 455 &Subtable, TRUE); 456 if (ACPI_FAILURE (Status)) 457 { 458 return (Status); 459 } 460 if (Subtable) 461 { 462 DtInsertSubtable (ParentTable, Subtable); 463 } 464 } 465 466 DtPopSubtable (); 467 ParentTable = DtPeekSubtable (); 468 DescriptorCount--; 469 } 470 471 DtPopSubtable (); 472 ParentTable = DtPeekSubtable (); 473 } 474 475 return (Status); 476 } 477 478 479 /****************************************************************************** 480 * 481 * FUNCTION: DtCompileDbg2 482 * 483 * PARAMETERS: List - Current field list pointer 484 * 485 * RETURN: Status 486 * 487 * DESCRIPTION: Compile DBG2. 488 * 489 *****************************************************************************/ 490 491 ACPI_STATUS 492 DtCompileDbg2 ( 493 void **List) 494 { 495 ACPI_STATUS Status; 496 DT_SUBTABLE *Subtable; 497 DT_SUBTABLE *ParentTable; 498 DT_FIELD **PFieldList = (DT_FIELD **) List; 499 UINT32 SubtableCount; 500 ACPI_DBG2_HEADER *Dbg2Header; 501 ACPI_DBG2_DEVICE *DeviceInfo; 502 UINT16 CurrentOffset; 503 UINT32 i; 504 505 506 /* Main table */ 507 508 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE); 509 if (ACPI_FAILURE (Status)) 510 { 511 return (Status); 512 } 513 514 ParentTable = DtPeekSubtable (); 515 DtInsertSubtable (ParentTable, Subtable); 516 517 /* Main table fields */ 518 519 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 520 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 521 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 522 523 SubtableCount = Dbg2Header->InfoCount; 524 DtPushSubtable (Subtable); 525 526 /* Process all Device Information subtables (Count = InfoCount) */ 527 528 while (*PFieldList && SubtableCount) 529 { 530 /* Subtable: Debug Device Information */ 531 532 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 533 &Subtable, TRUE); 534 if (ACPI_FAILURE (Status)) 535 { 536 return (Status); 537 } 538 539 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 540 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 541 542 ParentTable = DtPeekSubtable (); 543 DtInsertSubtable (ParentTable, Subtable); 544 DtPushSubtable (Subtable); 545 546 ParentTable = DtPeekSubtable (); 547 548 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 549 550 DeviceInfo->BaseAddressOffset = CurrentOffset; 551 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 552 { 553 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 554 &Subtable, TRUE); 555 if (ACPI_FAILURE (Status)) 556 { 557 return (Status); 558 } 559 560 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 561 DtInsertSubtable (ParentTable, Subtable); 562 } 563 564 /* AddressSize array (Required, size = RegisterCount) */ 565 566 DeviceInfo->AddressSizeOffset = CurrentOffset; 567 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 568 { 569 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 570 &Subtable, TRUE); 571 if (ACPI_FAILURE (Status)) 572 { 573 return (Status); 574 } 575 576 CurrentOffset += (UINT16) sizeof (UINT32); 577 DtInsertSubtable (ParentTable, Subtable); 578 } 579 580 /* NamespaceString device identifier (Required, size = NamePathLength) */ 581 582 DeviceInfo->NamepathOffset = CurrentOffset; 583 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 584 &Subtable, TRUE); 585 if (ACPI_FAILURE (Status)) 586 { 587 return (Status); 588 } 589 590 /* Update the device info header */ 591 592 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 593 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 594 DtInsertSubtable (ParentTable, Subtable); 595 596 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 597 598 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 599 &Subtable, TRUE); 600 if (ACPI_FAILURE (Status)) 601 { 602 return (Status); 603 } 604 605 /* Update the device info header (zeros if no OEM data present) */ 606 607 DeviceInfo->OemDataOffset = 0; 608 DeviceInfo->OemDataLength = 0; 609 610 /* Optional subtable (OemData) */ 611 612 if (Subtable && Subtable->Length) 613 { 614 DeviceInfo->OemDataOffset = CurrentOffset; 615 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 616 617 DtInsertSubtable (ParentTable, Subtable); 618 } 619 620 SubtableCount--; 621 DtPopSubtable (); /* Get next Device Information subtable */ 622 } 623 624 DtPopSubtable (); 625 return (AE_OK); 626 } 627 628 629 /****************************************************************************** 630 * 631 * FUNCTION: DtCompileDmar 632 * 633 * PARAMETERS: List - Current field list pointer 634 * 635 * RETURN: Status 636 * 637 * DESCRIPTION: Compile DMAR. 638 * 639 *****************************************************************************/ 640 641 ACPI_STATUS 642 DtCompileDmar ( 643 void **List) 644 { 645 ACPI_STATUS Status; 646 DT_SUBTABLE *Subtable; 647 DT_SUBTABLE *ParentTable; 648 DT_FIELD **PFieldList = (DT_FIELD **) List; 649 DT_FIELD *SubtableStart; 650 ACPI_DMTABLE_INFO *InfoTable; 651 ACPI_DMAR_HEADER *DmarHeader; 652 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 653 UINT32 DeviceScopeLength; 654 UINT32 PciPathLength; 655 656 657 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE); 658 if (ACPI_FAILURE (Status)) 659 { 660 return (Status); 661 } 662 663 ParentTable = DtPeekSubtable (); 664 DtInsertSubtable (ParentTable, Subtable); 665 DtPushSubtable (Subtable); 666 667 while (*PFieldList) 668 { 669 /* DMAR Header */ 670 671 SubtableStart = *PFieldList; 672 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 673 &Subtable, TRUE); 674 if (ACPI_FAILURE (Status)) 675 { 676 return (Status); 677 } 678 679 ParentTable = DtPeekSubtable (); 680 DtInsertSubtable (ParentTable, Subtable); 681 DtPushSubtable (Subtable); 682 683 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 684 685 switch (DmarHeader->Type) 686 { 687 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 688 689 InfoTable = AcpiDmTableInfoDmar0; 690 break; 691 692 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 693 694 InfoTable = AcpiDmTableInfoDmar1; 695 break; 696 697 case ACPI_DMAR_TYPE_ROOT_ATS: 698 699 InfoTable = AcpiDmTableInfoDmar2; 700 break; 701 702 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 703 704 InfoTable = AcpiDmTableInfoDmar3; 705 break; 706 707 case ACPI_DMAR_TYPE_NAMESPACE: 708 709 InfoTable = AcpiDmTableInfoDmar4; 710 break; 711 712 default: 713 714 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 715 return (AE_ERROR); 716 } 717 718 /* DMAR Subtable */ 719 720 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 721 if (ACPI_FAILURE (Status)) 722 { 723 return (Status); 724 } 725 726 ParentTable = DtPeekSubtable (); 727 DtInsertSubtable (ParentTable, Subtable); 728 729 /* 730 * Optional Device Scope subtables 731 */ 732 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 733 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 734 { 735 /* These types do not support device scopes */ 736 737 DtPopSubtable (); 738 continue; 739 } 740 741 DtPushSubtable (Subtable); 742 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 743 ParentTable->Length; 744 while (DeviceScopeLength) 745 { 746 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 747 &Subtable, FALSE); 748 if (Status == AE_NOT_FOUND) 749 { 750 break; 751 } 752 753 ParentTable = DtPeekSubtable (); 754 DtInsertSubtable (ParentTable, Subtable); 755 DtPushSubtable (Subtable); 756 757 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 758 759 /* Optional PCI Paths */ 760 761 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 762 while (PciPathLength) 763 { 764 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 765 &Subtable, FALSE); 766 if (Status == AE_NOT_FOUND) 767 { 768 DtPopSubtable (); 769 break; 770 } 771 772 ParentTable = DtPeekSubtable (); 773 DtInsertSubtable (ParentTable, Subtable); 774 PciPathLength -= Subtable->Length; 775 } 776 777 DtPopSubtable (); 778 DeviceScopeLength -= DmarDeviceScope->Length; 779 } 780 781 DtPopSubtable (); 782 DtPopSubtable (); 783 } 784 785 return (AE_OK); 786 } 787 788 789 /****************************************************************************** 790 * 791 * FUNCTION: DtCompileDrtm 792 * 793 * PARAMETERS: List - Current field list pointer 794 * 795 * RETURN: Status 796 * 797 * DESCRIPTION: Compile DRTM. 798 * 799 *****************************************************************************/ 800 801 ACPI_STATUS 802 DtCompileDrtm ( 803 void **List) 804 { 805 ACPI_STATUS Status; 806 DT_SUBTABLE *Subtable; 807 DT_SUBTABLE *ParentTable; 808 DT_FIELD **PFieldList = (DT_FIELD **) List; 809 UINT32 Count; 810 /* ACPI_TABLE_DRTM *Drtm; */ 811 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 812 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 813 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 814 815 816 ParentTable = DtPeekSubtable (); 817 818 /* Compile DRTM header */ 819 820 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 821 &Subtable, TRUE); 822 if (ACPI_FAILURE (Status)) 823 { 824 return (Status); 825 } 826 DtInsertSubtable (ParentTable, Subtable); 827 828 /* 829 * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care 830 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 831 */ 832 #if 0 833 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 834 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 835 #endif 836 /* Compile VTL */ 837 838 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 839 &Subtable, TRUE); 840 if (ACPI_FAILURE (Status)) 841 { 842 return (Status); 843 } 844 845 DtInsertSubtable (ParentTable, Subtable); 846 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 847 848 DtPushSubtable (Subtable); 849 ParentTable = DtPeekSubtable (); 850 Count = 0; 851 852 while (*PFieldList) 853 { 854 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 855 &Subtable, TRUE); 856 if (ACPI_FAILURE (Status)) 857 { 858 return (Status); 859 } 860 if (!Subtable) 861 { 862 break; 863 } 864 DtInsertSubtable (ParentTable, Subtable); 865 Count++; 866 } 867 868 DrtmVtl->ValidatedTableCount = Count; 869 DtPopSubtable (); 870 ParentTable = DtPeekSubtable (); 871 872 /* Compile RL */ 873 874 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 875 &Subtable, TRUE); 876 if (ACPI_FAILURE (Status)) 877 { 878 return (Status); 879 } 880 881 DtInsertSubtable (ParentTable, Subtable); 882 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 883 884 DtPushSubtable (Subtable); 885 ParentTable = DtPeekSubtable (); 886 Count = 0; 887 888 while (*PFieldList) 889 { 890 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 891 &Subtable, TRUE); 892 if (ACPI_FAILURE (Status)) 893 { 894 return (Status); 895 } 896 897 if (!Subtable) 898 { 899 break; 900 } 901 902 DtInsertSubtable (ParentTable, Subtable); 903 Count++; 904 } 905 906 DrtmRl->ResourceCount = Count; 907 DtPopSubtable (); 908 ParentTable = DtPeekSubtable (); 909 910 /* Compile DPS */ 911 912 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 913 &Subtable, TRUE); 914 if (ACPI_FAILURE (Status)) 915 { 916 return (Status); 917 } 918 DtInsertSubtable (ParentTable, Subtable); 919 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 920 921 922 return (AE_OK); 923 } 924 925 926 /****************************************************************************** 927 * 928 * FUNCTION: DtCompileEinj 929 * 930 * PARAMETERS: List - Current field list pointer 931 * 932 * RETURN: Status 933 * 934 * DESCRIPTION: Compile EINJ. 935 * 936 *****************************************************************************/ 937 938 ACPI_STATUS 939 DtCompileEinj ( 940 void **List) 941 { 942 ACPI_STATUS Status; 943 944 945 Status = DtCompileTwoSubtables (List, 946 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 947 return (Status); 948 } 949 950 951 /****************************************************************************** 952 * 953 * FUNCTION: DtCompileErst 954 * 955 * PARAMETERS: List - Current field list pointer 956 * 957 * RETURN: Status 958 * 959 * DESCRIPTION: Compile ERST. 960 * 961 *****************************************************************************/ 962 963 ACPI_STATUS 964 DtCompileErst ( 965 void **List) 966 { 967 ACPI_STATUS Status; 968 969 970 Status = DtCompileTwoSubtables (List, 971 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 972 return (Status); 973 } 974 975 976 /****************************************************************************** 977 * 978 * FUNCTION: DtCompileGtdt 979 * 980 * PARAMETERS: List - Current field list pointer 981 * 982 * RETURN: Status 983 * 984 * DESCRIPTION: Compile GTDT. 985 * 986 *****************************************************************************/ 987 988 ACPI_STATUS 989 DtCompileGtdt ( 990 void **List) 991 { 992 ACPI_STATUS Status; 993 DT_SUBTABLE *Subtable; 994 DT_SUBTABLE *ParentTable; 995 DT_FIELD **PFieldList = (DT_FIELD **) List; 996 DT_FIELD *SubtableStart; 997 ACPI_SUBTABLE_HEADER *GtdtHeader; 998 ACPI_DMTABLE_INFO *InfoTable; 999 UINT32 GtCount; 1000 1001 1002 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 1003 &Subtable, TRUE); 1004 if (ACPI_FAILURE (Status)) 1005 { 1006 return (Status); 1007 } 1008 1009 ParentTable = DtPeekSubtable (); 1010 DtInsertSubtable (ParentTable, Subtable); 1011 1012 while (*PFieldList) 1013 { 1014 SubtableStart = *PFieldList; 1015 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 1016 &Subtable, TRUE); 1017 if (ACPI_FAILURE (Status)) 1018 { 1019 return (Status); 1020 } 1021 1022 ParentTable = DtPeekSubtable (); 1023 DtInsertSubtable (ParentTable, Subtable); 1024 DtPushSubtable (Subtable); 1025 1026 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1027 1028 switch (GtdtHeader->Type) 1029 { 1030 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1031 1032 InfoTable = AcpiDmTableInfoGtdt0; 1033 break; 1034 1035 case ACPI_GTDT_TYPE_WATCHDOG: 1036 1037 InfoTable = AcpiDmTableInfoGtdt1; 1038 break; 1039 1040 default: 1041 1042 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 1043 return (AE_ERROR); 1044 } 1045 1046 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1047 if (ACPI_FAILURE (Status)) 1048 { 1049 return (Status); 1050 } 1051 1052 ParentTable = DtPeekSubtable (); 1053 DtInsertSubtable (ParentTable, Subtable); 1054 1055 /* 1056 * Additional GT block subtable data 1057 */ 1058 1059 switch (GtdtHeader->Type) 1060 { 1061 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1062 1063 DtPushSubtable (Subtable); 1064 ParentTable = DtPeekSubtable (); 1065 1066 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 1067 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 1068 1069 while (GtCount) 1070 { 1071 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 1072 &Subtable, TRUE); 1073 if (ACPI_FAILURE (Status)) 1074 { 1075 return (Status); 1076 } 1077 1078 DtInsertSubtable (ParentTable, Subtable); 1079 GtCount--; 1080 } 1081 1082 DtPopSubtable (); 1083 break; 1084 1085 default: 1086 1087 break; 1088 } 1089 1090 DtPopSubtable (); 1091 } 1092 1093 return (AE_OK); 1094 } 1095 1096 1097 /****************************************************************************** 1098 * 1099 * FUNCTION: DtCompileFpdt 1100 * 1101 * PARAMETERS: List - Current field list pointer 1102 * 1103 * RETURN: Status 1104 * 1105 * DESCRIPTION: Compile FPDT. 1106 * 1107 *****************************************************************************/ 1108 1109 ACPI_STATUS 1110 DtCompileFpdt ( 1111 void **List) 1112 { 1113 ACPI_STATUS Status; 1114 ACPI_FPDT_HEADER *FpdtHeader; 1115 DT_SUBTABLE *Subtable; 1116 DT_SUBTABLE *ParentTable; 1117 ACPI_DMTABLE_INFO *InfoTable; 1118 DT_FIELD **PFieldList = (DT_FIELD **) List; 1119 DT_FIELD *SubtableStart; 1120 1121 1122 while (*PFieldList) 1123 { 1124 SubtableStart = *PFieldList; 1125 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1126 &Subtable, TRUE); 1127 if (ACPI_FAILURE (Status)) 1128 { 1129 return (Status); 1130 } 1131 1132 ParentTable = DtPeekSubtable (); 1133 DtInsertSubtable (ParentTable, Subtable); 1134 DtPushSubtable (Subtable); 1135 1136 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1137 1138 switch (FpdtHeader->Type) 1139 { 1140 case ACPI_FPDT_TYPE_BOOT: 1141 1142 InfoTable = AcpiDmTableInfoFpdt0; 1143 break; 1144 1145 case ACPI_FPDT_TYPE_S3PERF: 1146 1147 InfoTable = AcpiDmTableInfoFpdt1; 1148 break; 1149 1150 default: 1151 1152 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1153 return (AE_ERROR); 1154 break; 1155 } 1156 1157 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1158 if (ACPI_FAILURE (Status)) 1159 { 1160 return (Status); 1161 } 1162 1163 ParentTable = DtPeekSubtable (); 1164 DtInsertSubtable (ParentTable, Subtable); 1165 DtPopSubtable (); 1166 } 1167 1168 return (AE_OK); 1169 } 1170 1171 1172 /****************************************************************************** 1173 * 1174 * FUNCTION: DtCompileHest 1175 * 1176 * PARAMETERS: List - Current field list pointer 1177 * 1178 * RETURN: Status 1179 * 1180 * DESCRIPTION: Compile HEST. 1181 * 1182 *****************************************************************************/ 1183 1184 ACPI_STATUS 1185 DtCompileHest ( 1186 void **List) 1187 { 1188 ACPI_STATUS Status; 1189 DT_SUBTABLE *Subtable; 1190 DT_SUBTABLE *ParentTable; 1191 DT_FIELD **PFieldList = (DT_FIELD **) List; 1192 DT_FIELD *SubtableStart; 1193 ACPI_DMTABLE_INFO *InfoTable; 1194 UINT16 Type; 1195 UINT32 BankCount; 1196 1197 1198 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1199 &Subtable, TRUE); 1200 if (ACPI_FAILURE (Status)) 1201 { 1202 return (Status); 1203 } 1204 1205 ParentTable = DtPeekSubtable (); 1206 DtInsertSubtable (ParentTable, Subtable); 1207 1208 while (*PFieldList) 1209 { 1210 /* Get subtable type */ 1211 1212 SubtableStart = *PFieldList; 1213 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1214 1215 switch (Type) 1216 { 1217 case ACPI_HEST_TYPE_IA32_CHECK: 1218 1219 InfoTable = AcpiDmTableInfoHest0; 1220 break; 1221 1222 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1223 1224 InfoTable = AcpiDmTableInfoHest1; 1225 break; 1226 1227 case ACPI_HEST_TYPE_IA32_NMI: 1228 1229 InfoTable = AcpiDmTableInfoHest2; 1230 break; 1231 1232 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1233 1234 InfoTable = AcpiDmTableInfoHest6; 1235 break; 1236 1237 case ACPI_HEST_TYPE_AER_ENDPOINT: 1238 1239 InfoTable = AcpiDmTableInfoHest7; 1240 break; 1241 1242 case ACPI_HEST_TYPE_AER_BRIDGE: 1243 1244 InfoTable = AcpiDmTableInfoHest8; 1245 break; 1246 1247 case ACPI_HEST_TYPE_GENERIC_ERROR: 1248 1249 InfoTable = AcpiDmTableInfoHest9; 1250 break; 1251 1252 default: 1253 1254 /* Cannot continue on unknown type */ 1255 1256 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1257 return (AE_ERROR); 1258 } 1259 1260 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1261 if (ACPI_FAILURE (Status)) 1262 { 1263 return (Status); 1264 } 1265 1266 DtInsertSubtable (ParentTable, Subtable); 1267 1268 /* 1269 * Additional subtable data - IA32 Error Bank(s) 1270 */ 1271 BankCount = 0; 1272 switch (Type) 1273 { 1274 case ACPI_HEST_TYPE_IA32_CHECK: 1275 1276 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1277 Subtable->Buffer))->NumHardwareBanks; 1278 break; 1279 1280 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1281 1282 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1283 Subtable->Buffer))->NumHardwareBanks; 1284 break; 1285 1286 default: 1287 1288 break; 1289 } 1290 1291 while (BankCount) 1292 { 1293 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1294 &Subtable, TRUE); 1295 if (ACPI_FAILURE (Status)) 1296 { 1297 return (Status); 1298 } 1299 1300 DtInsertSubtable (ParentTable, Subtable); 1301 BankCount--; 1302 } 1303 } 1304 1305 return (AE_OK); 1306 } 1307 1308 1309 /****************************************************************************** 1310 * 1311 * FUNCTION: DtCompileIort 1312 * 1313 * PARAMETERS: List - Current field list pointer 1314 * 1315 * RETURN: Status 1316 * 1317 * DESCRIPTION: Compile IORT. 1318 * 1319 *****************************************************************************/ 1320 1321 ACPI_STATUS 1322 DtCompileIort ( 1323 void **List) 1324 { 1325 ACPI_STATUS Status; 1326 DT_SUBTABLE *Subtable; 1327 DT_SUBTABLE *ParentTable; 1328 DT_FIELD **PFieldList = (DT_FIELD **) List; 1329 DT_FIELD *SubtableStart; 1330 ACPI_TABLE_IORT *Iort; 1331 ACPI_IORT_NODE *IortNode; 1332 ACPI_IORT_ITS_GROUP *IortItsGroup; 1333 ACPI_IORT_SMMU *IortSmmu; 1334 UINT32 NodeNumber; 1335 UINT32 NodeLength; 1336 UINT32 IdMappingNumber; 1337 UINT32 ItsNumber; 1338 UINT32 ContextIrptNumber; 1339 UINT32 PmuIrptNumber; 1340 UINT32 PaddingLength; 1341 1342 1343 ParentTable = DtPeekSubtable (); 1344 1345 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 1346 &Subtable, TRUE); 1347 if (ACPI_FAILURE (Status)) 1348 { 1349 return (Status); 1350 } 1351 DtInsertSubtable (ParentTable, Subtable); 1352 1353 /* 1354 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1355 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 1356 */ 1357 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 1358 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1359 1360 /* 1361 * OptionalPadding - Variable-length data 1362 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 1363 * Optionally allows the generic data types to be used for filling 1364 * this field. 1365 */ 1366 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 1367 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 1368 &Subtable, TRUE); 1369 if (ACPI_FAILURE (Status)) 1370 { 1371 return (Status); 1372 } 1373 if (Subtable) 1374 { 1375 DtInsertSubtable (ParentTable, Subtable); 1376 Iort->NodeOffset += Subtable->Length; 1377 } 1378 else 1379 { 1380 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 1381 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 1382 if (ACPI_FAILURE (Status)) 1383 { 1384 return (Status); 1385 } 1386 Iort->NodeOffset += PaddingLength; 1387 } 1388 1389 NodeNumber = 0; 1390 while (*PFieldList) 1391 { 1392 SubtableStart = *PFieldList; 1393 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 1394 &Subtable, TRUE); 1395 if (ACPI_FAILURE (Status)) 1396 { 1397 return (Status); 1398 } 1399 1400 DtInsertSubtable (ParentTable, Subtable); 1401 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 1402 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 1403 1404 DtPushSubtable (Subtable); 1405 ParentTable = DtPeekSubtable (); 1406 1407 switch (IortNode->Type) 1408 { 1409 case ACPI_IORT_NODE_ITS_GROUP: 1410 1411 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 1412 &Subtable, TRUE); 1413 if (ACPI_FAILURE (Status)) 1414 { 1415 return (Status); 1416 } 1417 1418 DtInsertSubtable (ParentTable, Subtable); 1419 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 1420 NodeLength += Subtable->Length; 1421 1422 ItsNumber = 0; 1423 while (*PFieldList) 1424 { 1425 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 1426 &Subtable, TRUE); 1427 if (ACPI_FAILURE (Status)) 1428 { 1429 return (Status); 1430 } 1431 if (!Subtable) 1432 { 1433 break; 1434 } 1435 1436 DtInsertSubtable (ParentTable, Subtable); 1437 NodeLength += Subtable->Length; 1438 ItsNumber++; 1439 } 1440 1441 IortItsGroup->ItsCount = ItsNumber; 1442 break; 1443 1444 case ACPI_IORT_NODE_NAMED_COMPONENT: 1445 1446 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 1447 &Subtable, TRUE); 1448 if (ACPI_FAILURE (Status)) 1449 { 1450 return (Status); 1451 } 1452 1453 DtInsertSubtable (ParentTable, Subtable); 1454 NodeLength += Subtable->Length; 1455 1456 /* 1457 * Padding - Variable-length data 1458 * Optionally allows the offset of the ID mappings to be used 1459 * for filling this field. 1460 */ 1461 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 1462 &Subtable, TRUE); 1463 if (ACPI_FAILURE (Status)) 1464 { 1465 return (Status); 1466 } 1467 1468 if (Subtable) 1469 { 1470 DtInsertSubtable (ParentTable, Subtable); 1471 NodeLength += Subtable->Length; 1472 } 1473 else 1474 { 1475 if (NodeLength > IortNode->MappingOffset) 1476 { 1477 return (AE_BAD_DATA); 1478 } 1479 1480 if (NodeLength < IortNode->MappingOffset) 1481 { 1482 Status = DtCompilePadding ( 1483 IortNode->MappingOffset - NodeLength, 1484 &Subtable); 1485 if (ACPI_FAILURE (Status)) 1486 { 1487 return (Status); 1488 } 1489 1490 DtInsertSubtable (ParentTable, Subtable); 1491 NodeLength = IortNode->MappingOffset; 1492 } 1493 } 1494 break; 1495 1496 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 1497 1498 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 1499 &Subtable, TRUE); 1500 if (ACPI_FAILURE (Status)) 1501 { 1502 return (Status); 1503 } 1504 1505 DtInsertSubtable (ParentTable, Subtable); 1506 NodeLength += Subtable->Length; 1507 break; 1508 1509 case ACPI_IORT_NODE_SMMU: 1510 1511 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 1512 &Subtable, TRUE); 1513 if (ACPI_FAILURE (Status)) 1514 { 1515 return (Status); 1516 } 1517 1518 DtInsertSubtable (ParentTable, Subtable); 1519 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 1520 NodeLength += Subtable->Length; 1521 1522 /* Compile global interrupt array */ 1523 1524 IortSmmu->GlobalInterruptOffset = NodeLength; 1525 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 1526 &Subtable, TRUE); 1527 if (ACPI_FAILURE (Status)) 1528 { 1529 return (Status); 1530 } 1531 1532 DtInsertSubtable (ParentTable, Subtable); 1533 NodeLength += Subtable->Length; 1534 1535 /* Compile context interrupt array */ 1536 1537 ContextIrptNumber = 0; 1538 IortSmmu->ContextInterruptOffset = NodeLength; 1539 while (*PFieldList) 1540 { 1541 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 1542 &Subtable, TRUE); 1543 if (ACPI_FAILURE (Status)) 1544 { 1545 return (Status); 1546 } 1547 1548 if (!Subtable) 1549 { 1550 break; 1551 } 1552 1553 DtInsertSubtable (ParentTable, Subtable); 1554 NodeLength += Subtable->Length; 1555 ContextIrptNumber++; 1556 } 1557 1558 IortSmmu->ContextInterruptCount = ContextIrptNumber; 1559 1560 /* Compile PMU interrupt array */ 1561 1562 PmuIrptNumber = 0; 1563 IortSmmu->PmuInterruptOffset = NodeLength; 1564 while (*PFieldList) 1565 { 1566 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 1567 &Subtable, TRUE); 1568 if (ACPI_FAILURE (Status)) 1569 { 1570 return (Status); 1571 } 1572 1573 if (!Subtable) 1574 { 1575 break; 1576 } 1577 1578 DtInsertSubtable (ParentTable, Subtable); 1579 NodeLength += Subtable->Length; 1580 PmuIrptNumber++; 1581 } 1582 1583 IortSmmu->PmuInterruptCount = PmuIrptNumber; 1584 break; 1585 1586 case ACPI_IORT_NODE_SMMU_V3: 1587 1588 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 1589 &Subtable, TRUE); 1590 if (ACPI_FAILURE (Status)) 1591 { 1592 return (Status); 1593 } 1594 1595 DtInsertSubtable (ParentTable, Subtable); 1596 NodeLength += Subtable->Length; 1597 break; 1598 1599 default: 1600 1601 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 1602 return (AE_ERROR); 1603 } 1604 1605 /* Compile Array of ID mappings */ 1606 1607 IortNode->MappingOffset = NodeLength; 1608 IdMappingNumber = 0; 1609 while (*PFieldList) 1610 { 1611 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 1612 &Subtable, TRUE); 1613 if (ACPI_FAILURE (Status)) 1614 { 1615 return (Status); 1616 } 1617 1618 if (!Subtable) 1619 { 1620 break; 1621 } 1622 1623 DtInsertSubtable (ParentTable, Subtable); 1624 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 1625 IdMappingNumber++; 1626 } 1627 1628 IortNode->MappingCount = IdMappingNumber; 1629 if (!IdMappingNumber) 1630 { 1631 IortNode->MappingOffset = 0; 1632 } 1633 1634 /* 1635 * Node length can be determined by DT_LENGTH option 1636 * IortNode->Length = NodeLength; 1637 */ 1638 DtPopSubtable (); 1639 ParentTable = DtPeekSubtable (); 1640 NodeNumber++; 1641 } 1642 1643 Iort->NodeCount = NodeNumber; 1644 return (AE_OK); 1645 } 1646 1647 1648 /****************************************************************************** 1649 * 1650 * FUNCTION: DtCompileIvrs 1651 * 1652 * PARAMETERS: List - Current field list pointer 1653 * 1654 * RETURN: Status 1655 * 1656 * DESCRIPTION: Compile IVRS. 1657 * 1658 *****************************************************************************/ 1659 1660 ACPI_STATUS 1661 DtCompileIvrs ( 1662 void **List) 1663 { 1664 ACPI_STATUS Status; 1665 DT_SUBTABLE *Subtable; 1666 DT_SUBTABLE *ParentTable; 1667 DT_FIELD **PFieldList = (DT_FIELD **) List; 1668 DT_FIELD *SubtableStart; 1669 ACPI_DMTABLE_INFO *InfoTable; 1670 ACPI_IVRS_HEADER *IvrsHeader; 1671 UINT8 EntryType; 1672 1673 1674 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 1675 &Subtable, TRUE); 1676 if (ACPI_FAILURE (Status)) 1677 { 1678 return (Status); 1679 } 1680 1681 ParentTable = DtPeekSubtable (); 1682 DtInsertSubtable (ParentTable, Subtable); 1683 1684 while (*PFieldList) 1685 { 1686 SubtableStart = *PFieldList; 1687 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr, 1688 &Subtable, TRUE); 1689 if (ACPI_FAILURE (Status)) 1690 { 1691 return (Status); 1692 } 1693 1694 ParentTable = DtPeekSubtable (); 1695 DtInsertSubtable (ParentTable, Subtable); 1696 DtPushSubtable (Subtable); 1697 1698 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer); 1699 1700 switch (IvrsHeader->Type) 1701 { 1702 case ACPI_IVRS_TYPE_HARDWARE: 1703 1704 InfoTable = AcpiDmTableInfoIvrs0; 1705 break; 1706 1707 case ACPI_IVRS_TYPE_MEMORY1: 1708 case ACPI_IVRS_TYPE_MEMORY2: 1709 case ACPI_IVRS_TYPE_MEMORY3: 1710 1711 InfoTable = AcpiDmTableInfoIvrs1; 1712 break; 1713 1714 default: 1715 1716 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS"); 1717 return (AE_ERROR); 1718 } 1719 1720 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1721 if (ACPI_FAILURE (Status)) 1722 { 1723 return (Status); 1724 } 1725 1726 ParentTable = DtPeekSubtable (); 1727 DtInsertSubtable (ParentTable, Subtable); 1728 1729 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE) 1730 { 1731 while (*PFieldList && 1732 !strcmp ((*PFieldList)->Name, "Entry Type")) 1733 { 1734 SubtableStart = *PFieldList; 1735 DtCompileInteger (&EntryType, *PFieldList, 1, 0); 1736 1737 switch (EntryType) 1738 { 1739 /* 4-byte device entries */ 1740 1741 case ACPI_IVRS_TYPE_PAD4: 1742 case ACPI_IVRS_TYPE_ALL: 1743 case ACPI_IVRS_TYPE_SELECT: 1744 case ACPI_IVRS_TYPE_START: 1745 case ACPI_IVRS_TYPE_END: 1746 1747 InfoTable = AcpiDmTableInfoIvrs4; 1748 break; 1749 1750 /* 8-byte entries, type A */ 1751 1752 case ACPI_IVRS_TYPE_ALIAS_SELECT: 1753 case ACPI_IVRS_TYPE_ALIAS_START: 1754 1755 InfoTable = AcpiDmTableInfoIvrs8a; 1756 break; 1757 1758 /* 8-byte entries, type B */ 1759 1760 case ACPI_IVRS_TYPE_PAD8: 1761 case ACPI_IVRS_TYPE_EXT_SELECT: 1762 case ACPI_IVRS_TYPE_EXT_START: 1763 1764 InfoTable = AcpiDmTableInfoIvrs8b; 1765 break; 1766 1767 /* 8-byte entries, type C */ 1768 1769 case ACPI_IVRS_TYPE_SPECIAL: 1770 1771 InfoTable = AcpiDmTableInfoIvrs8c; 1772 break; 1773 1774 default: 1775 1776 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 1777 "IVRS Device Entry"); 1778 return (AE_ERROR); 1779 } 1780 1781 Status = DtCompileTable (PFieldList, InfoTable, 1782 &Subtable, TRUE); 1783 if (ACPI_FAILURE (Status)) 1784 { 1785 return (Status); 1786 } 1787 1788 DtInsertSubtable (ParentTable, Subtable); 1789 } 1790 } 1791 1792 DtPopSubtable (); 1793 } 1794 1795 return (AE_OK); 1796 } 1797