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 - 2021, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 /* Compile all complex data tables, signatures starting with A-I */ 153 154 #include <contrib/dev/acpica/compiler/aslcompiler.h> 155 156 #define _COMPONENT DT_COMPILER 157 ACPI_MODULE_NAME ("dttable1") 158 159 160 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] = 161 { 162 {ACPI_DMT_BUFFER, 0, "Addresses", 0}, 163 {ACPI_DMT_EXIT, 0, NULL, 0} 164 }; 165 166 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] = 167 { 168 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0}, 169 {ACPI_DMT_EXIT, 0, NULL, 0} 170 }; 171 172 173 /****************************************************************************** 174 * 175 * FUNCTION: DtCompileAest 176 * 177 * PARAMETERS: List - Current field list pointer 178 * 179 * RETURN: Status 180 * 181 * DESCRIPTION: Compile AEST. 182 * 183 * NOTE: Assumes the following table structure: 184 * For all AEST Error Nodes: 185 * 1) An AEST Error Node, followed immediately by: 186 * 2) Any node-specific data 187 * 3) An Interface Structure (one) 188 * 4) A list (array) of Interrupt Structures, the count as specified 189 * in the NodeInterruptCount field of the Error Node header. 190 * 191 * AEST - ARM Error Source table. Conforms to: 192 * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020 193 * 194 *****************************************************************************/ 195 196 ACPI_STATUS 197 DtCompileAest ( 198 void **List) 199 { 200 ACPI_AEST_HEADER *ErrorNodeHeader; 201 ACPI_AEST_PROCESSOR *AestProcessor; 202 DT_SUBTABLE *Subtable; 203 DT_SUBTABLE *ParentTable; 204 ACPI_DMTABLE_INFO *InfoTable; 205 ACPI_STATUS Status; 206 UINT32 i; 207 UINT32 Offset; 208 DT_FIELD **PFieldList = (DT_FIELD **) List; 209 210 211 while (*PFieldList) 212 { 213 /* Compile the common error node header */ 214 215 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr, 216 &Subtable); 217 if (ACPI_FAILURE (Status)) 218 { 219 return (Status); 220 } 221 222 ParentTable = DtPeekSubtable (); 223 DtInsertSubtable (ParentTable, Subtable); 224 225 /* Everything past the error node header will be a subtable */ 226 227 DtPushSubtable (Subtable); 228 229 /* 230 * Compile the node-specific structure (Based on the error 231 * node header Type field) 232 */ 233 ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer); 234 235 /* Point past the common error node header */ 236 237 Offset = sizeof (ACPI_AEST_HEADER); 238 ErrorNodeHeader->NodeSpecificOffset = Offset; 239 240 /* Decode the error node type */ 241 242 switch (ErrorNodeHeader->Type) 243 { 244 case ACPI_AEST_PROCESSOR_ERROR_NODE: 245 246 InfoTable = AcpiDmTableInfoAestProcError; 247 break; 248 249 case ACPI_AEST_MEMORY_ERROR_NODE: 250 251 InfoTable = AcpiDmTableInfoAestMemError; 252 break; 253 254 case ACPI_AEST_SMMU_ERROR_NODE: 255 256 InfoTable = AcpiDmTableInfoAestSmmuError; 257 break; 258 259 case ACPI_AEST_VENDOR_ERROR_NODE: 260 261 InfoTable = AcpiDmTableInfoAestVendorError; 262 break; 263 264 case ACPI_AEST_GIC_ERROR_NODE: 265 266 InfoTable = AcpiDmTableInfoAestGicError; 267 break; 268 269 /* Error case below */ 270 default: 271 AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n", 272 ErrorNodeHeader->Type); 273 return (AE_ERROR); 274 } 275 276 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 277 if (ACPI_FAILURE (Status)) 278 { 279 return (Status); 280 } 281 282 /* Point past the node-specific structure */ 283 284 Offset += Subtable->Length; 285 ErrorNodeHeader->NodeInterfaceOffset = Offset; 286 287 ParentTable = DtPeekSubtable (); 288 DtInsertSubtable (ParentTable, Subtable); 289 290 /* Compile any additional node-specific substructures */ 291 292 if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE) 293 { 294 /* 295 * Special handling for PROCESSOR_ERROR_NODE subtables 296 * (to handle the Resource Substructure via the ResourceType 297 * field). 298 */ 299 AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR, 300 Subtable->Buffer); 301 302 switch (AestProcessor->ResourceType) 303 { 304 case ACPI_AEST_CACHE_RESOURCE: 305 306 InfoTable = AcpiDmTableInfoAestCacheRsrc; 307 break; 308 309 case ACPI_AEST_TLB_RESOURCE: 310 311 InfoTable = AcpiDmTableInfoAestTlbRsrc; 312 break; 313 314 case ACPI_AEST_GENERIC_RESOURCE: 315 316 InfoTable = AcpiDmTableInfoAestGenRsrc; 317 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n", 318 AestProcessor->ResourceType); 319 return (AE_ERROR); 320 321 /* Error case below */ 322 default: 323 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n", 324 AestProcessor->ResourceType); 325 return (AE_ERROR); 326 } 327 328 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 329 if (ACPI_FAILURE (Status)) 330 { 331 return (Status); 332 } 333 334 /* Point past the resource substructure subtable */ 335 336 Offset += Subtable->Length; 337 ErrorNodeHeader->NodeInterfaceOffset = Offset; 338 339 ParentTable = DtPeekSubtable (); 340 DtInsertSubtable (ParentTable, Subtable); 341 } 342 343 /* Compile the (required) node interface structure */ 344 345 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXface, 346 &Subtable); 347 if (ACPI_FAILURE (Status)) 348 { 349 return (Status); 350 } 351 352 ErrorNodeHeader->NodeInterruptOffset = 0; 353 ParentTable = DtPeekSubtable (); 354 DtInsertSubtable (ParentTable, Subtable); 355 356 /* Compile each of the node interrupt structures */ 357 358 if (ErrorNodeHeader->NodeInterruptCount) 359 { 360 /* Point to the first interrupt structure */ 361 362 Offset += Subtable->Length; 363 ErrorNodeHeader->NodeInterruptOffset = Offset; 364 } 365 366 /* Compile each of the interrupt structures */ 367 368 for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++) 369 { 370 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXrupt, 371 &Subtable); 372 if (ACPI_FAILURE (Status)) 373 { 374 return (Status); 375 } 376 377 ParentTable = DtPeekSubtable (); 378 DtInsertSubtable (ParentTable, Subtable); 379 } 380 381 /* Prepare for the next AEST Error node */ 382 383 DtPopSubtable (); 384 } 385 386 return (AE_OK); 387 } 388 389 390 /****************************************************************************** 391 * 392 * FUNCTION: DtCompileAsf 393 * 394 * PARAMETERS: List - Current field list pointer 395 * 396 * RETURN: Status 397 * 398 * DESCRIPTION: Compile ASF!. 399 * 400 *****************************************************************************/ 401 402 ACPI_STATUS 403 DtCompileAsf ( 404 void **List) 405 { 406 ACPI_ASF_INFO *AsfTable; 407 DT_SUBTABLE *Subtable; 408 DT_SUBTABLE *ParentTable; 409 ACPI_DMTABLE_INFO *InfoTable; 410 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 411 UINT32 DataCount = 0; 412 ACPI_STATUS Status; 413 UINT32 i; 414 DT_FIELD **PFieldList = (DT_FIELD **) List; 415 DT_FIELD *SubtableStart; 416 417 418 while (*PFieldList) 419 { 420 SubtableStart = *PFieldList; 421 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 422 &Subtable); 423 if (ACPI_FAILURE (Status)) 424 { 425 return (Status); 426 } 427 428 ParentTable = DtPeekSubtable (); 429 DtInsertSubtable (ParentTable, Subtable); 430 DtPushSubtable (Subtable); 431 432 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 433 434 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 435 { 436 case ACPI_ASF_TYPE_INFO: 437 438 InfoTable = AcpiDmTableInfoAsf0; 439 break; 440 441 case ACPI_ASF_TYPE_ALERT: 442 443 InfoTable = AcpiDmTableInfoAsf1; 444 break; 445 446 case ACPI_ASF_TYPE_CONTROL: 447 448 InfoTable = AcpiDmTableInfoAsf2; 449 break; 450 451 case ACPI_ASF_TYPE_BOOT: 452 453 InfoTable = AcpiDmTableInfoAsf3; 454 break; 455 456 case ACPI_ASF_TYPE_ADDRESS: 457 458 InfoTable = AcpiDmTableInfoAsf4; 459 break; 460 461 default: 462 463 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 464 return (AE_ERROR); 465 } 466 467 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 468 if (ACPI_FAILURE (Status)) 469 { 470 return (Status); 471 } 472 473 ParentTable = DtPeekSubtable (); 474 DtInsertSubtable (ParentTable, Subtable); 475 476 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 477 { 478 case ACPI_ASF_TYPE_INFO: 479 480 DataInfoTable = NULL; 481 break; 482 483 case ACPI_ASF_TYPE_ALERT: 484 485 DataInfoTable = AcpiDmTableInfoAsf1a; 486 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 487 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 488 sizeof (ACPI_ASF_HEADER)))->Alerts; 489 break; 490 491 case ACPI_ASF_TYPE_CONTROL: 492 493 DataInfoTable = AcpiDmTableInfoAsf2a; 494 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 495 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 496 sizeof (ACPI_ASF_HEADER)))->Controls; 497 break; 498 499 case ACPI_ASF_TYPE_BOOT: 500 501 DataInfoTable = NULL; 502 break; 503 504 case ACPI_ASF_TYPE_ADDRESS: 505 506 DataInfoTable = TableInfoAsfAddress; 507 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 508 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 509 sizeof (ACPI_ASF_HEADER)))->Devices; 510 break; 511 512 default: 513 514 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 515 return (AE_ERROR); 516 } 517 518 if (DataInfoTable) 519 { 520 switch (AsfTable->Header.Type & 0x7F) 521 { 522 case ACPI_ASF_TYPE_ADDRESS: 523 524 while (DataCount > 0) 525 { 526 Status = DtCompileTable (PFieldList, DataInfoTable, 527 &Subtable); 528 if (ACPI_FAILURE (Status)) 529 { 530 return (Status); 531 } 532 533 DtInsertSubtable (ParentTable, Subtable); 534 DataCount = DataCount - Subtable->Length; 535 } 536 break; 537 538 default: 539 540 for (i = 0; i < DataCount; i++) 541 { 542 Status = DtCompileTable (PFieldList, DataInfoTable, 543 &Subtable); 544 if (ACPI_FAILURE (Status)) 545 { 546 return (Status); 547 } 548 549 DtInsertSubtable (ParentTable, Subtable); 550 } 551 break; 552 } 553 } 554 555 DtPopSubtable (); 556 } 557 558 return (AE_OK); 559 } 560 561 562 /****************************************************************************** 563 * 564 * FUNCTION: DtCompileCedt 565 * 566 * PARAMETERS: List - Current field list pointer 567 * 568 * RETURN: Status 569 * 570 * DESCRIPTION: Compile CEDT. 571 * 572 *****************************************************************************/ 573 574 ACPI_STATUS 575 DtCompileCedt ( 576 void **List) 577 { 578 ACPI_STATUS Status; 579 DT_SUBTABLE *Subtable; 580 DT_SUBTABLE *ParentTable; 581 DT_FIELD **PFieldList = (DT_FIELD **) List; 582 ACPI_CEDT_HEADER *CedtHeader; 583 DT_FIELD *SubtableStart; 584 585 586 /* Walk the parse tree */ 587 588 while (*PFieldList) 589 { 590 SubtableStart = *PFieldList; 591 592 /* CEDT Header */ 593 594 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr, 595 &Subtable); 596 if (ACPI_FAILURE (Status)) 597 { 598 return (Status); 599 } 600 601 ParentTable = DtPeekSubtable (); 602 DtInsertSubtable (ParentTable, Subtable); 603 DtPushSubtable (Subtable); 604 605 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer); 606 607 switch (CedtHeader->Type) 608 { 609 case ACPI_CEDT_TYPE_CHBS: 610 611 break; 612 613 default: 614 615 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT"); 616 return (AE_ERROR); 617 } 618 619 /* CEDT Subtable */ 620 621 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable); 622 if (ACPI_FAILURE (Status)) 623 { 624 return (Status); 625 } 626 627 ParentTable = DtPeekSubtable (); 628 DtInsertSubtable (ParentTable, Subtable); 629 DtPopSubtable (); 630 } 631 632 return (AE_OK); 633 } 634 635 636 /****************************************************************************** 637 * 638 * FUNCTION: DtCompileCpep 639 * 640 * PARAMETERS: List - Current field list pointer 641 * 642 * RETURN: Status 643 * 644 * DESCRIPTION: Compile CPEP. 645 * 646 *****************************************************************************/ 647 648 ACPI_STATUS 649 DtCompileCpep ( 650 void **List) 651 { 652 ACPI_STATUS Status; 653 654 655 Status = DtCompileTwoSubtables (List, 656 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 657 return (Status); 658 } 659 660 661 /****************************************************************************** 662 * 663 * FUNCTION: DtCompileCsrt 664 * 665 * PARAMETERS: List - Current field list pointer 666 * 667 * RETURN: Status 668 * 669 * DESCRIPTION: Compile CSRT. 670 * 671 *****************************************************************************/ 672 673 ACPI_STATUS 674 DtCompileCsrt ( 675 void **List) 676 { 677 ACPI_STATUS Status = AE_OK; 678 DT_SUBTABLE *Subtable; 679 DT_SUBTABLE *ParentTable; 680 DT_FIELD **PFieldList = (DT_FIELD **) List; 681 UINT32 DescriptorCount; 682 UINT32 GroupLength; 683 684 685 /* Subtables (Resource Groups) */ 686 687 ParentTable = DtPeekSubtable (); 688 while (*PFieldList) 689 { 690 /* Resource group subtable */ 691 692 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 693 &Subtable); 694 if (ACPI_FAILURE (Status)) 695 { 696 return (Status); 697 } 698 699 /* Compute the number of resource descriptors */ 700 701 GroupLength = 702 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 703 Subtable->Buffer))->Length - 704 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 705 Subtable->Buffer))->SharedInfoLength - 706 sizeof (ACPI_CSRT_GROUP); 707 708 DescriptorCount = (GroupLength / 709 sizeof (ACPI_CSRT_DESCRIPTOR)); 710 711 DtInsertSubtable (ParentTable, Subtable); 712 DtPushSubtable (Subtable); 713 ParentTable = DtPeekSubtable (); 714 715 /* Shared info subtable (One per resource group) */ 716 717 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 718 &Subtable); 719 if (ACPI_FAILURE (Status)) 720 { 721 return (Status); 722 } 723 724 DtInsertSubtable (ParentTable, Subtable); 725 726 /* Sub-Subtables (Resource Descriptors) */ 727 728 while (*PFieldList && DescriptorCount) 729 { 730 731 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 732 &Subtable); 733 if (ACPI_FAILURE (Status)) 734 { 735 return (Status); 736 } 737 738 DtInsertSubtable (ParentTable, Subtable); 739 740 DtPushSubtable (Subtable); 741 ParentTable = DtPeekSubtable (); 742 if (*PFieldList) 743 { 744 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 745 &Subtable); 746 if (ACPI_FAILURE (Status)) 747 { 748 return (Status); 749 } 750 if (Subtable) 751 { 752 DtInsertSubtable (ParentTable, Subtable); 753 } 754 } 755 756 DtPopSubtable (); 757 ParentTable = DtPeekSubtable (); 758 DescriptorCount--; 759 } 760 761 DtPopSubtable (); 762 ParentTable = DtPeekSubtable (); 763 } 764 765 return (Status); 766 } 767 768 769 /****************************************************************************** 770 * 771 * FUNCTION: DtCompileDbg2 772 * 773 * PARAMETERS: List - Current field list pointer 774 * 775 * RETURN: Status 776 * 777 * DESCRIPTION: Compile DBG2. 778 * 779 *****************************************************************************/ 780 781 ACPI_STATUS 782 DtCompileDbg2 ( 783 void **List) 784 { 785 ACPI_STATUS Status; 786 DT_SUBTABLE *Subtable; 787 DT_SUBTABLE *ParentTable; 788 DT_FIELD **PFieldList = (DT_FIELD **) List; 789 UINT32 SubtableCount; 790 ACPI_DBG2_HEADER *Dbg2Header; 791 ACPI_DBG2_DEVICE *DeviceInfo; 792 UINT16 CurrentOffset; 793 UINT32 i; 794 795 796 /* Main table */ 797 798 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable); 799 if (ACPI_FAILURE (Status)) 800 { 801 return (Status); 802 } 803 804 ParentTable = DtPeekSubtable (); 805 DtInsertSubtable (ParentTable, Subtable); 806 807 /* Main table fields */ 808 809 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 810 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 811 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 812 813 SubtableCount = Dbg2Header->InfoCount; 814 DtPushSubtable (Subtable); 815 816 /* Process all Device Information subtables (Count = InfoCount) */ 817 818 while (*PFieldList && SubtableCount) 819 { 820 /* Subtable: Debug Device Information */ 821 822 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 823 &Subtable); 824 if (ACPI_FAILURE (Status)) 825 { 826 return (Status); 827 } 828 829 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 830 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 831 832 ParentTable = DtPeekSubtable (); 833 DtInsertSubtable (ParentTable, Subtable); 834 DtPushSubtable (Subtable); 835 836 ParentTable = DtPeekSubtable (); 837 838 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 839 840 DeviceInfo->BaseAddressOffset = CurrentOffset; 841 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 842 { 843 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 844 &Subtable); 845 if (ACPI_FAILURE (Status)) 846 { 847 return (Status); 848 } 849 850 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 851 DtInsertSubtable (ParentTable, Subtable); 852 } 853 854 /* AddressSize array (Required, size = RegisterCount) */ 855 856 DeviceInfo->AddressSizeOffset = CurrentOffset; 857 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 858 { 859 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 860 &Subtable); 861 if (ACPI_FAILURE (Status)) 862 { 863 return (Status); 864 } 865 866 CurrentOffset += (UINT16) sizeof (UINT32); 867 DtInsertSubtable (ParentTable, Subtable); 868 } 869 870 /* NamespaceString device identifier (Required, size = NamePathLength) */ 871 872 DeviceInfo->NamepathOffset = CurrentOffset; 873 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 874 &Subtable); 875 if (ACPI_FAILURE (Status)) 876 { 877 return (Status); 878 } 879 880 /* Update the device info header */ 881 882 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 883 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 884 DtInsertSubtable (ParentTable, Subtable); 885 886 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 887 888 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 889 &Subtable); 890 if (Status == AE_END_OF_TABLE) 891 { 892 /* optional field was not found and we're at the end of the file */ 893 894 goto subtableDone; 895 } 896 else if (ACPI_FAILURE (Status)) 897 { 898 return (Status); 899 } 900 901 /* Update the device info header (zeros if no OEM data present) */ 902 903 DeviceInfo->OemDataOffset = 0; 904 DeviceInfo->OemDataLength = 0; 905 906 /* Optional subtable (OemData) */ 907 908 if (Subtable && Subtable->Length) 909 { 910 DeviceInfo->OemDataOffset = CurrentOffset; 911 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 912 913 DtInsertSubtable (ParentTable, Subtable); 914 } 915 subtableDone: 916 SubtableCount--; 917 DtPopSubtable (); /* Get next Device Information subtable */ 918 } 919 920 DtPopSubtable (); 921 return (AE_OK); 922 } 923 924 925 /****************************************************************************** 926 * 927 * FUNCTION: DtCompileDmar 928 * 929 * PARAMETERS: List - Current field list pointer 930 * 931 * RETURN: Status 932 * 933 * DESCRIPTION: Compile DMAR. 934 * 935 *****************************************************************************/ 936 937 ACPI_STATUS 938 DtCompileDmar ( 939 void **List) 940 { 941 ACPI_STATUS Status; 942 DT_SUBTABLE *Subtable; 943 DT_SUBTABLE *ParentTable; 944 DT_FIELD **PFieldList = (DT_FIELD **) List; 945 DT_FIELD *SubtableStart; 946 ACPI_DMTABLE_INFO *InfoTable; 947 ACPI_DMAR_HEADER *DmarHeader; 948 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 949 UINT32 DeviceScopeLength; 950 UINT32 PciPathLength; 951 952 953 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable); 954 if (ACPI_FAILURE (Status)) 955 { 956 return (Status); 957 } 958 959 ParentTable = DtPeekSubtable (); 960 DtInsertSubtable (ParentTable, Subtable); 961 DtPushSubtable (Subtable); 962 963 while (*PFieldList) 964 { 965 /* DMAR Header */ 966 967 SubtableStart = *PFieldList; 968 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 969 &Subtable); 970 if (ACPI_FAILURE (Status)) 971 { 972 return (Status); 973 } 974 975 ParentTable = DtPeekSubtable (); 976 DtInsertSubtable (ParentTable, Subtable); 977 DtPushSubtable (Subtable); 978 979 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 980 981 switch (DmarHeader->Type) 982 { 983 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 984 985 InfoTable = AcpiDmTableInfoDmar0; 986 break; 987 988 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 989 990 InfoTable = AcpiDmTableInfoDmar1; 991 break; 992 993 case ACPI_DMAR_TYPE_ROOT_ATS: 994 995 InfoTable = AcpiDmTableInfoDmar2; 996 break; 997 998 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 999 1000 InfoTable = AcpiDmTableInfoDmar3; 1001 break; 1002 1003 case ACPI_DMAR_TYPE_NAMESPACE: 1004 1005 InfoTable = AcpiDmTableInfoDmar4; 1006 break; 1007 1008 default: 1009 1010 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 1011 return (AE_ERROR); 1012 } 1013 1014 /* DMAR Subtable */ 1015 1016 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1017 if (ACPI_FAILURE (Status)) 1018 { 1019 return (Status); 1020 } 1021 1022 ParentTable = DtPeekSubtable (); 1023 DtInsertSubtable (ParentTable, Subtable); 1024 1025 /* 1026 * Optional Device Scope subtables 1027 */ 1028 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 1029 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 1030 { 1031 /* These types do not support device scopes */ 1032 1033 DtPopSubtable (); 1034 continue; 1035 } 1036 1037 DtPushSubtable (Subtable); 1038 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 1039 ParentTable->Length; 1040 while (DeviceScopeLength) 1041 { 1042 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 1043 &Subtable); 1044 if (Status == AE_NOT_FOUND) 1045 { 1046 break; 1047 } 1048 1049 ParentTable = DtPeekSubtable (); 1050 DtInsertSubtable (ParentTable, Subtable); 1051 DtPushSubtable (Subtable); 1052 1053 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 1054 1055 /* Optional PCI Paths */ 1056 1057 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 1058 while (PciPathLength) 1059 { 1060 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 1061 &Subtable); 1062 if (Status == AE_NOT_FOUND) 1063 { 1064 DtPopSubtable (); 1065 break; 1066 } 1067 1068 ParentTable = DtPeekSubtable (); 1069 DtInsertSubtable (ParentTable, Subtable); 1070 PciPathLength -= Subtable->Length; 1071 } 1072 1073 DtPopSubtable (); 1074 DeviceScopeLength -= DmarDeviceScope->Length; 1075 } 1076 1077 DtPopSubtable (); 1078 DtPopSubtable (); 1079 } 1080 1081 return (AE_OK); 1082 } 1083 1084 1085 /****************************************************************************** 1086 * 1087 * FUNCTION: DtCompileDrtm 1088 * 1089 * PARAMETERS: List - Current field list pointer 1090 * 1091 * RETURN: Status 1092 * 1093 * DESCRIPTION: Compile DRTM. 1094 * 1095 *****************************************************************************/ 1096 1097 ACPI_STATUS 1098 DtCompileDrtm ( 1099 void **List) 1100 { 1101 ACPI_STATUS Status; 1102 DT_SUBTABLE *Subtable; 1103 DT_SUBTABLE *ParentTable; 1104 DT_FIELD **PFieldList = (DT_FIELD **) List; 1105 UINT32 Count; 1106 /* ACPI_TABLE_DRTM *Drtm; */ 1107 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 1108 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 1109 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 1110 1111 1112 ParentTable = DtPeekSubtable (); 1113 1114 /* Compile DRTM header */ 1115 1116 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 1117 &Subtable); 1118 if (ACPI_FAILURE (Status)) 1119 { 1120 return (Status); 1121 } 1122 DtInsertSubtable (ParentTable, Subtable); 1123 1124 /* 1125 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1126 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 1127 */ 1128 #if 0 1129 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 1130 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1131 #endif 1132 /* Compile VTL */ 1133 1134 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 1135 &Subtable); 1136 if (ACPI_FAILURE (Status)) 1137 { 1138 return (Status); 1139 } 1140 1141 DtInsertSubtable (ParentTable, Subtable); 1142 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 1143 1144 DtPushSubtable (Subtable); 1145 ParentTable = DtPeekSubtable (); 1146 Count = 0; 1147 1148 while (*PFieldList) 1149 { 1150 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 1151 &Subtable); 1152 if (ACPI_FAILURE (Status)) 1153 { 1154 return (Status); 1155 } 1156 if (!Subtable) 1157 { 1158 break; 1159 } 1160 DtInsertSubtable (ParentTable, Subtable); 1161 Count++; 1162 } 1163 1164 DrtmVtl->ValidatedTableCount = Count; 1165 DtPopSubtable (); 1166 ParentTable = DtPeekSubtable (); 1167 1168 /* Compile RL */ 1169 1170 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 1171 &Subtable); 1172 if (ACPI_FAILURE (Status)) 1173 { 1174 return (Status); 1175 } 1176 1177 DtInsertSubtable (ParentTable, Subtable); 1178 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 1179 1180 DtPushSubtable (Subtable); 1181 ParentTable = DtPeekSubtable (); 1182 Count = 0; 1183 1184 while (*PFieldList) 1185 { 1186 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 1187 &Subtable); 1188 if (ACPI_FAILURE (Status)) 1189 { 1190 return (Status); 1191 } 1192 1193 if (!Subtable) 1194 { 1195 break; 1196 } 1197 1198 DtInsertSubtable (ParentTable, Subtable); 1199 Count++; 1200 } 1201 1202 DrtmRl->ResourceCount = Count; 1203 DtPopSubtable (); 1204 ParentTable = DtPeekSubtable (); 1205 1206 /* Compile DPS */ 1207 1208 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 1209 &Subtable); 1210 if (ACPI_FAILURE (Status)) 1211 { 1212 return (Status); 1213 } 1214 DtInsertSubtable (ParentTable, Subtable); 1215 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 1216 1217 1218 return (AE_OK); 1219 } 1220 1221 1222 /****************************************************************************** 1223 * 1224 * FUNCTION: DtCompileEinj 1225 * 1226 * PARAMETERS: List - Current field list pointer 1227 * 1228 * RETURN: Status 1229 * 1230 * DESCRIPTION: Compile EINJ. 1231 * 1232 *****************************************************************************/ 1233 1234 ACPI_STATUS 1235 DtCompileEinj ( 1236 void **List) 1237 { 1238 ACPI_STATUS Status; 1239 1240 1241 Status = DtCompileTwoSubtables (List, 1242 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 1243 return (Status); 1244 } 1245 1246 1247 /****************************************************************************** 1248 * 1249 * FUNCTION: DtCompileErst 1250 * 1251 * PARAMETERS: List - Current field list pointer 1252 * 1253 * RETURN: Status 1254 * 1255 * DESCRIPTION: Compile ERST. 1256 * 1257 *****************************************************************************/ 1258 1259 ACPI_STATUS 1260 DtCompileErst ( 1261 void **List) 1262 { 1263 ACPI_STATUS Status; 1264 1265 1266 Status = DtCompileTwoSubtables (List, 1267 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 1268 return (Status); 1269 } 1270 1271 1272 /****************************************************************************** 1273 * 1274 * FUNCTION: DtCompileGtdt 1275 * 1276 * PARAMETERS: List - Current field list pointer 1277 * 1278 * RETURN: Status 1279 * 1280 * DESCRIPTION: Compile GTDT. 1281 * 1282 *****************************************************************************/ 1283 1284 ACPI_STATUS 1285 DtCompileGtdt ( 1286 void **List) 1287 { 1288 ACPI_STATUS Status; 1289 DT_SUBTABLE *Subtable; 1290 DT_SUBTABLE *ParentTable; 1291 DT_FIELD **PFieldList = (DT_FIELD **) List; 1292 DT_FIELD *SubtableStart; 1293 ACPI_SUBTABLE_HEADER *GtdtHeader; 1294 ACPI_DMTABLE_INFO *InfoTable; 1295 UINT32 GtCount; 1296 ACPI_TABLE_HEADER *Header; 1297 1298 1299 ParentTable = DtPeekSubtable (); 1300 1301 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1302 1303 /* Compile the main table */ 1304 1305 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 1306 &Subtable); 1307 if (ACPI_FAILURE (Status)) 1308 { 1309 return (Status); 1310 } 1311 1312 /* GTDT revision 3 later contains 2 extra fields before subtables */ 1313 1314 if (Header->Revision > 2) 1315 { 1316 ParentTable = DtPeekSubtable (); 1317 DtInsertSubtable (ParentTable, Subtable); 1318 1319 Status = DtCompileTable (PFieldList, 1320 AcpiDmTableInfoGtdtEl2, &Subtable); 1321 if (ACPI_FAILURE (Status)) 1322 { 1323 return (Status); 1324 } 1325 } 1326 1327 ParentTable = DtPeekSubtable (); 1328 DtInsertSubtable (ParentTable, Subtable); 1329 1330 while (*PFieldList) 1331 { 1332 SubtableStart = *PFieldList; 1333 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 1334 &Subtable); 1335 if (ACPI_FAILURE (Status)) 1336 { 1337 return (Status); 1338 } 1339 1340 ParentTable = DtPeekSubtable (); 1341 DtInsertSubtable (ParentTable, Subtable); 1342 DtPushSubtable (Subtable); 1343 1344 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1345 1346 switch (GtdtHeader->Type) 1347 { 1348 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1349 1350 InfoTable = AcpiDmTableInfoGtdt0; 1351 break; 1352 1353 case ACPI_GTDT_TYPE_WATCHDOG: 1354 1355 InfoTable = AcpiDmTableInfoGtdt1; 1356 break; 1357 1358 default: 1359 1360 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 1361 return (AE_ERROR); 1362 } 1363 1364 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1365 if (ACPI_FAILURE (Status)) 1366 { 1367 return (Status); 1368 } 1369 1370 ParentTable = DtPeekSubtable (); 1371 DtInsertSubtable (ParentTable, Subtable); 1372 1373 /* 1374 * Additional GT block subtable data 1375 */ 1376 1377 switch (GtdtHeader->Type) 1378 { 1379 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1380 1381 DtPushSubtable (Subtable); 1382 ParentTable = DtPeekSubtable (); 1383 1384 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 1385 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 1386 1387 while (GtCount) 1388 { 1389 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 1390 &Subtable); 1391 if (ACPI_FAILURE (Status)) 1392 { 1393 return (Status); 1394 } 1395 1396 DtInsertSubtable (ParentTable, Subtable); 1397 GtCount--; 1398 } 1399 1400 DtPopSubtable (); 1401 break; 1402 1403 default: 1404 1405 break; 1406 } 1407 1408 DtPopSubtable (); 1409 } 1410 1411 return (AE_OK); 1412 } 1413 1414 1415 /****************************************************************************** 1416 * 1417 * FUNCTION: DtCompileFpdt 1418 * 1419 * PARAMETERS: List - Current field list pointer 1420 * 1421 * RETURN: Status 1422 * 1423 * DESCRIPTION: Compile FPDT. 1424 * 1425 *****************************************************************************/ 1426 1427 ACPI_STATUS 1428 DtCompileFpdt ( 1429 void **List) 1430 { 1431 ACPI_STATUS Status; 1432 ACPI_FPDT_HEADER *FpdtHeader; 1433 DT_SUBTABLE *Subtable; 1434 DT_SUBTABLE *ParentTable; 1435 ACPI_DMTABLE_INFO *InfoTable; 1436 DT_FIELD **PFieldList = (DT_FIELD **) List; 1437 DT_FIELD *SubtableStart; 1438 1439 1440 while (*PFieldList) 1441 { 1442 SubtableStart = *PFieldList; 1443 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1444 &Subtable); 1445 if (ACPI_FAILURE (Status)) 1446 { 1447 return (Status); 1448 } 1449 1450 ParentTable = DtPeekSubtable (); 1451 DtInsertSubtable (ParentTable, Subtable); 1452 DtPushSubtable (Subtable); 1453 1454 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1455 1456 switch (FpdtHeader->Type) 1457 { 1458 case ACPI_FPDT_TYPE_BOOT: 1459 1460 InfoTable = AcpiDmTableInfoFpdt0; 1461 break; 1462 1463 case ACPI_FPDT_TYPE_S3PERF: 1464 1465 InfoTable = AcpiDmTableInfoFpdt1; 1466 break; 1467 1468 default: 1469 1470 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1471 return (AE_ERROR); 1472 break; 1473 } 1474 1475 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1476 if (ACPI_FAILURE (Status)) 1477 { 1478 return (Status); 1479 } 1480 1481 ParentTable = DtPeekSubtable (); 1482 DtInsertSubtable (ParentTable, Subtable); 1483 DtPopSubtable (); 1484 } 1485 1486 return (AE_OK); 1487 } 1488 1489 1490 /****************************************************************************** 1491 * 1492 * FUNCTION: DtCompileHest 1493 * 1494 * PARAMETERS: List - Current field list pointer 1495 * 1496 * RETURN: Status 1497 * 1498 * DESCRIPTION: Compile HEST. 1499 * 1500 *****************************************************************************/ 1501 1502 ACPI_STATUS 1503 DtCompileHest ( 1504 void **List) 1505 { 1506 ACPI_STATUS Status; 1507 DT_SUBTABLE *Subtable; 1508 DT_SUBTABLE *ParentTable; 1509 DT_FIELD **PFieldList = (DT_FIELD **) List; 1510 DT_FIELD *SubtableStart; 1511 ACPI_DMTABLE_INFO *InfoTable; 1512 UINT16 Type; 1513 UINT32 BankCount; 1514 1515 1516 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1517 &Subtable); 1518 if (ACPI_FAILURE (Status)) 1519 { 1520 return (Status); 1521 } 1522 1523 ParentTable = DtPeekSubtable (); 1524 DtInsertSubtable (ParentTable, Subtable); 1525 1526 while (*PFieldList) 1527 { 1528 /* Get subtable type */ 1529 1530 SubtableStart = *PFieldList; 1531 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1532 1533 switch (Type) 1534 { 1535 case ACPI_HEST_TYPE_IA32_CHECK: 1536 1537 InfoTable = AcpiDmTableInfoHest0; 1538 break; 1539 1540 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1541 1542 InfoTable = AcpiDmTableInfoHest1; 1543 break; 1544 1545 case ACPI_HEST_TYPE_IA32_NMI: 1546 1547 InfoTable = AcpiDmTableInfoHest2; 1548 break; 1549 1550 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1551 1552 InfoTable = AcpiDmTableInfoHest6; 1553 break; 1554 1555 case ACPI_HEST_TYPE_AER_ENDPOINT: 1556 1557 InfoTable = AcpiDmTableInfoHest7; 1558 break; 1559 1560 case ACPI_HEST_TYPE_AER_BRIDGE: 1561 1562 InfoTable = AcpiDmTableInfoHest8; 1563 break; 1564 1565 case ACPI_HEST_TYPE_GENERIC_ERROR: 1566 1567 InfoTable = AcpiDmTableInfoHest9; 1568 break; 1569 1570 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 1571 1572 InfoTable = AcpiDmTableInfoHest10; 1573 break; 1574 1575 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1576 1577 InfoTable = AcpiDmTableInfoHest11; 1578 break; 1579 1580 default: 1581 1582 /* Cannot continue on unknown type */ 1583 1584 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1585 return (AE_ERROR); 1586 } 1587 1588 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1589 if (ACPI_FAILURE (Status)) 1590 { 1591 return (Status); 1592 } 1593 1594 DtInsertSubtable (ParentTable, Subtable); 1595 1596 /* 1597 * Additional subtable data - IA32 Error Bank(s) 1598 */ 1599 BankCount = 0; 1600 switch (Type) 1601 { 1602 case ACPI_HEST_TYPE_IA32_CHECK: 1603 1604 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1605 Subtable->Buffer))->NumHardwareBanks; 1606 break; 1607 1608 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1609 1610 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1611 Subtable->Buffer))->NumHardwareBanks; 1612 break; 1613 1614 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1615 1616 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 1617 Subtable->Buffer))->NumHardwareBanks; 1618 break; 1619 1620 default: 1621 1622 break; 1623 } 1624 1625 while (BankCount) 1626 { 1627 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1628 &Subtable); 1629 if (ACPI_FAILURE (Status)) 1630 { 1631 return (Status); 1632 } 1633 1634 DtInsertSubtable (ParentTable, Subtable); 1635 BankCount--; 1636 } 1637 } 1638 1639 return (AE_OK); 1640 } 1641 1642 1643 /****************************************************************************** 1644 * 1645 * FUNCTION: DtCompileHmat 1646 * 1647 * PARAMETERS: List - Current field list pointer 1648 * 1649 * RETURN: Status 1650 * 1651 * DESCRIPTION: Compile HMAT. 1652 * 1653 *****************************************************************************/ 1654 1655 ACPI_STATUS 1656 DtCompileHmat ( 1657 void **List) 1658 { 1659 ACPI_STATUS Status; 1660 DT_SUBTABLE *Subtable; 1661 DT_SUBTABLE *ParentTable; 1662 DT_FIELD **PFieldList = (DT_FIELD **) List; 1663 DT_FIELD *SubtableStart; 1664 DT_FIELD *EntryStart; 1665 ACPI_HMAT_STRUCTURE *HmatStruct; 1666 ACPI_HMAT_LOCALITY *HmatLocality; 1667 ACPI_HMAT_CACHE *HmatCache; 1668 ACPI_DMTABLE_INFO *InfoTable; 1669 UINT32 IntPDNumber; 1670 UINT32 TgtPDNumber; 1671 UINT64 EntryNumber; 1672 UINT16 SMBIOSHandleNumber; 1673 1674 1675 ParentTable = DtPeekSubtable (); 1676 1677 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 1678 &Subtable); 1679 if (ACPI_FAILURE (Status)) 1680 { 1681 return (Status); 1682 } 1683 DtInsertSubtable (ParentTable, Subtable); 1684 1685 while (*PFieldList) 1686 { 1687 /* Compile HMAT structure header */ 1688 1689 SubtableStart = *PFieldList; 1690 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 1691 &Subtable); 1692 if (ACPI_FAILURE (Status)) 1693 { 1694 return (Status); 1695 } 1696 DtInsertSubtable (ParentTable, Subtable); 1697 1698 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 1699 HmatStruct->Length = Subtable->Length; 1700 1701 /* Compile HMAT structure body */ 1702 1703 switch (HmatStruct->Type) 1704 { 1705 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 1706 1707 InfoTable = AcpiDmTableInfoHmat0; 1708 break; 1709 1710 case ACPI_HMAT_TYPE_LOCALITY: 1711 1712 InfoTable = AcpiDmTableInfoHmat1; 1713 break; 1714 1715 case ACPI_HMAT_TYPE_CACHE: 1716 1717 InfoTable = AcpiDmTableInfoHmat2; 1718 break; 1719 1720 default: 1721 1722 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 1723 return (AE_ERROR); 1724 } 1725 1726 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1727 if (ACPI_FAILURE (Status)) 1728 { 1729 return (Status); 1730 } 1731 DtInsertSubtable (ParentTable, Subtable); 1732 HmatStruct->Length += Subtable->Length; 1733 1734 /* Compile HMAT structure additionals */ 1735 1736 switch (HmatStruct->Type) 1737 { 1738 case ACPI_HMAT_TYPE_LOCALITY: 1739 1740 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 1741 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1742 1743 /* Compile initiator proximity domain list */ 1744 1745 IntPDNumber = 0; 1746 while (*PFieldList) 1747 { 1748 Status = DtCompileTable (PFieldList, 1749 AcpiDmTableInfoHmat1a, &Subtable); 1750 if (ACPI_FAILURE (Status)) 1751 { 1752 return (Status); 1753 } 1754 if (!Subtable) 1755 { 1756 break; 1757 } 1758 DtInsertSubtable (ParentTable, Subtable); 1759 HmatStruct->Length += Subtable->Length; 1760 IntPDNumber++; 1761 } 1762 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 1763 1764 /* Compile target proximity domain list */ 1765 1766 TgtPDNumber = 0; 1767 while (*PFieldList) 1768 { 1769 Status = DtCompileTable (PFieldList, 1770 AcpiDmTableInfoHmat1b, &Subtable); 1771 if (ACPI_FAILURE (Status)) 1772 { 1773 return (Status); 1774 } 1775 if (!Subtable) 1776 { 1777 break; 1778 } 1779 DtInsertSubtable (ParentTable, Subtable); 1780 HmatStruct->Length += Subtable->Length; 1781 TgtPDNumber++; 1782 } 1783 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 1784 1785 /* Save start of the entries for reporting errors */ 1786 1787 EntryStart = *PFieldList; 1788 1789 /* Compile latency/bandwidth entries */ 1790 1791 EntryNumber = 0; 1792 while (*PFieldList) 1793 { 1794 Status = DtCompileTable (PFieldList, 1795 AcpiDmTableInfoHmat1c, &Subtable); 1796 if (ACPI_FAILURE (Status)) 1797 { 1798 return (Status); 1799 } 1800 if (!Subtable) 1801 { 1802 break; 1803 } 1804 DtInsertSubtable (ParentTable, Subtable); 1805 HmatStruct->Length += Subtable->Length; 1806 EntryNumber++; 1807 } 1808 1809 /* Validate number of entries */ 1810 1811 if (EntryNumber != 1812 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 1813 { 1814 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 1815 return (AE_ERROR); 1816 } 1817 break; 1818 1819 case ACPI_HMAT_TYPE_CACHE: 1820 1821 /* Compile SMBIOS handles */ 1822 1823 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 1824 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1825 SMBIOSHandleNumber = 0; 1826 while (*PFieldList) 1827 { 1828 Status = DtCompileTable (PFieldList, 1829 AcpiDmTableInfoHmat2a, &Subtable); 1830 if (ACPI_FAILURE (Status)) 1831 { 1832 return (Status); 1833 } 1834 if (!Subtable) 1835 { 1836 break; 1837 } 1838 DtInsertSubtable (ParentTable, Subtable); 1839 HmatStruct->Length += Subtable->Length; 1840 SMBIOSHandleNumber++; 1841 } 1842 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 1843 break; 1844 1845 default: 1846 1847 break; 1848 } 1849 } 1850 1851 return (AE_OK); 1852 } 1853 1854 1855 /****************************************************************************** 1856 * 1857 * FUNCTION: DtCompileIort 1858 * 1859 * PARAMETERS: List - Current field list pointer 1860 * 1861 * RETURN: Status 1862 * 1863 * DESCRIPTION: Compile IORT. 1864 * 1865 *****************************************************************************/ 1866 1867 ACPI_STATUS 1868 DtCompileIort ( 1869 void **List) 1870 { 1871 ACPI_STATUS Status; 1872 DT_SUBTABLE *Subtable; 1873 DT_SUBTABLE *ParentTable; 1874 DT_FIELD **PFieldList = (DT_FIELD **) List; 1875 DT_FIELD *SubtableStart; 1876 ACPI_TABLE_HEADER *Table; 1877 ACPI_TABLE_IORT *Iort; 1878 ACPI_IORT_NODE *IortNode; 1879 ACPI_IORT_ITS_GROUP *IortItsGroup; 1880 ACPI_IORT_SMMU *IortSmmu; 1881 ACPI_IORT_RMR *IortRmr; 1882 UINT32 NodeNumber; 1883 UINT32 NodeLength; 1884 UINT32 IdMappingNumber; 1885 UINT32 ItsNumber; 1886 UINT32 ContextIrptNumber; 1887 UINT32 PmuIrptNumber; 1888 UINT32 PaddingLength; 1889 UINT8 Revision; 1890 UINT32 RmrCount; 1891 1892 1893 ParentTable = DtPeekSubtable (); 1894 1895 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 1896 &Subtable); 1897 if (ACPI_FAILURE (Status)) 1898 { 1899 return (Status); 1900 } 1901 DtInsertSubtable (ParentTable, Subtable); 1902 1903 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1904 Revision = Table->Revision; 1905 1906 /* Both IORT Rev E and E.a have known issues and are not supported */ 1907 1908 if (Revision == 1 || Revision == 2) 1909 { 1910 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision"); 1911 return (AE_ERROR); 1912 } 1913 1914 /* 1915 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1916 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 1917 */ 1918 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 1919 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1920 1921 /* 1922 * OptionalPadding - Variable-length data 1923 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 1924 * Optionally allows the generic data types to be used for filling 1925 * this field. 1926 */ 1927 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 1928 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 1929 &Subtable); 1930 if (ACPI_FAILURE (Status)) 1931 { 1932 return (Status); 1933 } 1934 if (Subtable) 1935 { 1936 DtInsertSubtable (ParentTable, Subtable); 1937 Iort->NodeOffset += Subtable->Length; 1938 } 1939 else 1940 { 1941 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 1942 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 1943 if (ACPI_FAILURE (Status)) 1944 { 1945 return (Status); 1946 } 1947 Iort->NodeOffset += PaddingLength; 1948 } 1949 1950 NodeNumber = 0; 1951 while (*PFieldList) 1952 { 1953 SubtableStart = *PFieldList; 1954 if (Revision == 0) 1955 { 1956 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 1957 &Subtable); 1958 } 1959 else if (Revision >= 3) 1960 { 1961 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3, 1962 &Subtable); 1963 } 1964 1965 if (ACPI_FAILURE (Status)) 1966 { 1967 return (Status); 1968 } 1969 1970 DtInsertSubtable (ParentTable, Subtable); 1971 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 1972 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 1973 1974 DtPushSubtable (Subtable); 1975 ParentTable = DtPeekSubtable (); 1976 1977 switch (IortNode->Type) 1978 { 1979 case ACPI_IORT_NODE_ITS_GROUP: 1980 1981 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 1982 &Subtable); 1983 if (ACPI_FAILURE (Status)) 1984 { 1985 return (Status); 1986 } 1987 1988 DtInsertSubtable (ParentTable, Subtable); 1989 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 1990 NodeLength += Subtable->Length; 1991 1992 ItsNumber = 0; 1993 while (*PFieldList) 1994 { 1995 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 1996 &Subtable); 1997 if (ACPI_FAILURE (Status)) 1998 { 1999 return (Status); 2000 } 2001 if (!Subtable) 2002 { 2003 break; 2004 } 2005 2006 DtInsertSubtable (ParentTable, Subtable); 2007 NodeLength += Subtable->Length; 2008 ItsNumber++; 2009 } 2010 2011 IortItsGroup->ItsCount = ItsNumber; 2012 break; 2013 2014 case ACPI_IORT_NODE_NAMED_COMPONENT: 2015 2016 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 2017 &Subtable); 2018 if (ACPI_FAILURE (Status)) 2019 { 2020 return (Status); 2021 } 2022 2023 DtInsertSubtable (ParentTable, Subtable); 2024 NodeLength += Subtable->Length; 2025 2026 /* 2027 * Padding - Variable-length data 2028 * Optionally allows the offset of the ID mappings to be used 2029 * for filling this field. 2030 */ 2031 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 2032 &Subtable); 2033 if (ACPI_FAILURE (Status)) 2034 { 2035 return (Status); 2036 } 2037 2038 if (Subtable) 2039 { 2040 DtInsertSubtable (ParentTable, Subtable); 2041 NodeLength += Subtable->Length; 2042 } 2043 else 2044 { 2045 if (NodeLength > IortNode->MappingOffset) 2046 { 2047 return (AE_BAD_DATA); 2048 } 2049 2050 if (NodeLength < IortNode->MappingOffset) 2051 { 2052 Status = DtCompilePadding ( 2053 IortNode->MappingOffset - NodeLength, 2054 &Subtable); 2055 if (ACPI_FAILURE (Status)) 2056 { 2057 return (Status); 2058 } 2059 2060 DtInsertSubtable (ParentTable, Subtable); 2061 NodeLength = IortNode->MappingOffset; 2062 } 2063 } 2064 break; 2065 2066 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 2067 2068 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 2069 &Subtable); 2070 if (ACPI_FAILURE (Status)) 2071 { 2072 return (Status); 2073 } 2074 2075 DtInsertSubtable (ParentTable, Subtable); 2076 NodeLength += Subtable->Length; 2077 break; 2078 2079 case ACPI_IORT_NODE_SMMU: 2080 2081 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 2082 &Subtable); 2083 if (ACPI_FAILURE (Status)) 2084 { 2085 return (Status); 2086 } 2087 2088 DtInsertSubtable (ParentTable, Subtable); 2089 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 2090 NodeLength += Subtable->Length; 2091 2092 /* Compile global interrupt array */ 2093 2094 IortSmmu->GlobalInterruptOffset = NodeLength; 2095 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 2096 &Subtable); 2097 if (ACPI_FAILURE (Status)) 2098 { 2099 return (Status); 2100 } 2101 2102 DtInsertSubtable (ParentTable, Subtable); 2103 NodeLength += Subtable->Length; 2104 2105 /* Compile context interrupt array */ 2106 2107 ContextIrptNumber = 0; 2108 IortSmmu->ContextInterruptOffset = NodeLength; 2109 while (*PFieldList) 2110 { 2111 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 2112 &Subtable); 2113 if (ACPI_FAILURE (Status)) 2114 { 2115 return (Status); 2116 } 2117 2118 if (!Subtable) 2119 { 2120 break; 2121 } 2122 2123 DtInsertSubtable (ParentTable, Subtable); 2124 NodeLength += Subtable->Length; 2125 ContextIrptNumber++; 2126 } 2127 2128 IortSmmu->ContextInterruptCount = ContextIrptNumber; 2129 2130 /* Compile PMU interrupt array */ 2131 2132 PmuIrptNumber = 0; 2133 IortSmmu->PmuInterruptOffset = NodeLength; 2134 while (*PFieldList) 2135 { 2136 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 2137 &Subtable); 2138 if (ACPI_FAILURE (Status)) 2139 { 2140 return (Status); 2141 } 2142 2143 if (!Subtable) 2144 { 2145 break; 2146 } 2147 2148 DtInsertSubtable (ParentTable, Subtable); 2149 NodeLength += Subtable->Length; 2150 PmuIrptNumber++; 2151 } 2152 2153 IortSmmu->PmuInterruptCount = PmuIrptNumber; 2154 break; 2155 2156 case ACPI_IORT_NODE_SMMU_V3: 2157 2158 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 2159 &Subtable); 2160 if (ACPI_FAILURE (Status)) 2161 { 2162 return (Status); 2163 } 2164 2165 DtInsertSubtable (ParentTable, Subtable); 2166 NodeLength += Subtable->Length; 2167 break; 2168 2169 case ACPI_IORT_NODE_PMCG: 2170 2171 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5, 2172 &Subtable); 2173 if (ACPI_FAILURE (Status)) 2174 { 2175 return (Status); 2176 } 2177 2178 DtInsertSubtable (ParentTable, Subtable); 2179 NodeLength += Subtable->Length; 2180 break; 2181 2182 case ACPI_IORT_NODE_RMR: 2183 2184 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6, 2185 &Subtable); 2186 if (ACPI_FAILURE (Status)) 2187 { 2188 return (Status); 2189 } 2190 2191 DtInsertSubtable (ParentTable, Subtable); 2192 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer); 2193 NodeLength += Subtable->Length; 2194 2195 /* Compile RMR Descriptors */ 2196 2197 RmrCount = 0; 2198 IortRmr->RmrOffset = NodeLength; 2199 while (*PFieldList) 2200 { 2201 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a, 2202 &Subtable); 2203 if (ACPI_FAILURE (Status)) 2204 { 2205 return (Status); 2206 } 2207 2208 if (!Subtable) 2209 { 2210 break; 2211 } 2212 2213 DtInsertSubtable (ParentTable, Subtable); 2214 NodeLength += sizeof (ACPI_IORT_RMR_DESC); 2215 RmrCount++; 2216 } 2217 2218 IortRmr->RmrCount = RmrCount; 2219 break; 2220 2221 default: 2222 2223 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 2224 return (AE_ERROR); 2225 } 2226 2227 /* Compile Array of ID mappings */ 2228 2229 IortNode->MappingOffset = NodeLength; 2230 IdMappingNumber = 0; 2231 while (*PFieldList) 2232 { 2233 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 2234 &Subtable); 2235 if (ACPI_FAILURE (Status)) 2236 { 2237 return (Status); 2238 } 2239 2240 if (!Subtable) 2241 { 2242 break; 2243 } 2244 2245 DtInsertSubtable (ParentTable, Subtable); 2246 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 2247 IdMappingNumber++; 2248 } 2249 2250 IortNode->MappingCount = IdMappingNumber; 2251 if (!IdMappingNumber) 2252 { 2253 IortNode->MappingOffset = 0; 2254 } 2255 2256 /* 2257 * Node length can be determined by DT_LENGTH option 2258 * IortNode->Length = NodeLength; 2259 */ 2260 DtPopSubtable (); 2261 ParentTable = DtPeekSubtable (); 2262 NodeNumber++; 2263 } 2264 2265 Iort->NodeCount = NodeNumber; 2266 return (AE_OK); 2267 } 2268 2269 2270 /****************************************************************************** 2271 * 2272 * FUNCTION: DtCompileIvrs 2273 * 2274 * PARAMETERS: List - Current field list pointer 2275 * 2276 * RETURN: Status 2277 * 2278 * DESCRIPTION: Compile IVRS. Notes: 2279 * The IVRS is essentially a flat table, with the following 2280 * structure: 2281 * <Main ACPI Table Header> 2282 * <Main subtable - virtualization info> 2283 * <IVHD> 2284 * <Device Entries> 2285 * ... 2286 * <IVHD> 2287 * <Device Entries> 2288 * <IVMD> 2289 * ... 2290 * 2291 *****************************************************************************/ 2292 2293 ACPI_STATUS 2294 DtCompileIvrs ( 2295 void **List) 2296 { 2297 ACPI_STATUS Status; 2298 DT_SUBTABLE *Subtable; 2299 DT_SUBTABLE *ParentTable; 2300 DT_SUBTABLE *MainSubtable; 2301 DT_FIELD **PFieldList = (DT_FIELD **) List; 2302 DT_FIELD *SubtableStart; 2303 ACPI_DMTABLE_INFO *InfoTable = NULL; 2304 UINT8 SubtableType; 2305 UINT8 Temp64[16]; 2306 UINT8 Temp8; 2307 2308 2309 /* Main table */ 2310 2311 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 2312 &Subtable); 2313 if (ACPI_FAILURE (Status)) 2314 { 2315 return (Status); 2316 } 2317 2318 ParentTable = DtPeekSubtable (); 2319 DtInsertSubtable (ParentTable, Subtable); 2320 DtPushSubtable (Subtable); 2321 2322 /* Save a pointer to the main subtable */ 2323 2324 MainSubtable = Subtable; 2325 2326 while (*PFieldList) 2327 { 2328 SubtableStart = *PFieldList; 2329 2330 /* Compile the SubtableType integer */ 2331 2332 DtCompileInteger (&SubtableType, *PFieldList, 1, 0); 2333 2334 switch (SubtableType) 2335 { 2336 2337 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */ 2338 2339 case ACPI_IVRS_TYPE_HARDWARE1: 2340 2341 InfoTable = AcpiDmTableInfoIvrsHware1; 2342 break; 2343 2344 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */ 2345 2346 case ACPI_IVRS_TYPE_HARDWARE2: 2347 case ACPI_IVRS_TYPE_HARDWARE3: 2348 2349 InfoTable = AcpiDmTableInfoIvrsHware23; 2350 break; 2351 2352 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */ 2353 2354 case ACPI_IVRS_TYPE_MEMORY1: 2355 case ACPI_IVRS_TYPE_MEMORY2: 2356 case ACPI_IVRS_TYPE_MEMORY3: 2357 2358 InfoTable = AcpiDmTableInfoIvrsMemory; 2359 break; 2360 2361 /* 4-byte device entries */ 2362 2363 case ACPI_IVRS_TYPE_PAD4: 2364 case ACPI_IVRS_TYPE_ALL: 2365 case ACPI_IVRS_TYPE_SELECT: 2366 case ACPI_IVRS_TYPE_START: 2367 case ACPI_IVRS_TYPE_END: 2368 2369 InfoTable = AcpiDmTableInfoIvrs4; 2370 break; 2371 2372 /* 8-byte device entries, type A */ 2373 2374 case ACPI_IVRS_TYPE_ALIAS_SELECT: 2375 case ACPI_IVRS_TYPE_ALIAS_START: 2376 2377 InfoTable = AcpiDmTableInfoIvrs8a; 2378 break; 2379 2380 /* 8-byte device entries, type B */ 2381 2382 case ACPI_IVRS_TYPE_EXT_SELECT: 2383 case ACPI_IVRS_TYPE_EXT_START: 2384 2385 InfoTable = AcpiDmTableInfoIvrs8b; 2386 break; 2387 2388 /* 8-byte device entries, type C */ 2389 2390 case ACPI_IVRS_TYPE_SPECIAL: 2391 2392 InfoTable = AcpiDmTableInfoIvrs8c; 2393 break; 2394 2395 /* Variable device entries, type F0h */ 2396 2397 case ACPI_IVRS_TYPE_HID: 2398 2399 InfoTable = AcpiDmTableInfoIvrsHid; 2400 break; 2401 2402 default: 2403 2404 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 2405 "IVRS Device Entry"); 2406 return (AE_ERROR); 2407 } 2408 2409 /* Compile the InfoTable from above */ 2410 2411 Status = DtCompileTable (PFieldList, InfoTable, 2412 &Subtable); 2413 if (ACPI_FAILURE (Status)) 2414 { 2415 return (Status); 2416 } 2417 2418 ParentTable = DtPeekSubtable (); 2419 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 && 2420 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 && 2421 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 && 2422 SubtableType != ACPI_IVRS_TYPE_HID && 2423 SubtableType != ACPI_IVRS_TYPE_MEMORY1 && 2424 SubtableType != ACPI_IVRS_TYPE_MEMORY2 && 2425 SubtableType != ACPI_IVRS_TYPE_MEMORY3) 2426 { 2427 if (ParentTable) 2428 DtInsertSubtable (ParentTable, Subtable); 2429 } 2430 2431 switch (SubtableType) 2432 { 2433 case ACPI_IVRS_TYPE_HARDWARE1: 2434 case ACPI_IVRS_TYPE_HARDWARE2: 2435 case ACPI_IVRS_TYPE_HARDWARE3: 2436 case ACPI_IVRS_TYPE_MEMORY1: 2437 case ACPI_IVRS_TYPE_MEMORY2: 2438 case ACPI_IVRS_TYPE_MEMORY3: 2439 2440 /* Insert these IVHDs/IVMDs at the root subtable */ 2441 2442 DtInsertSubtable (MainSubtable, Subtable); 2443 DtPushSubtable (Subtable); 2444 ParentTable = MainSubtable; 2445 break; 2446 2447 case ACPI_IVRS_TYPE_HID: 2448 2449 /* Special handling for the HID named device entry (0xF0) */ 2450 2451 if (ParentTable) 2452 { 2453 DtInsertSubtable (ParentTable, Subtable); 2454 } 2455 2456 /* 2457 * Process the HID value. First, get the HID value as a string. 2458 */ 2459 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 2460 2461 /* 2462 * Determine if the HID is an integer or a string. 2463 * An integer is defined to be 32 bits, with the upper 32 bits 2464 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit 2465 * integer or a character string. If an integer, the lower 2466 * 4 bytes of the field contain the integer and the upper 2467 * 4 bytes are padded with 0". 2468 */ 2469 if (UtIsIdInteger ((UINT8 *) &Temp64)) 2470 { 2471 /* Compile the HID value as an integer */ 2472 2473 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 2474 2475 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger, 2476 &Subtable); 2477 if (ACPI_FAILURE (Status)) 2478 { 2479 return (Status); 2480 } 2481 } 2482 else 2483 { 2484 /* Compile the HID value as a string */ 2485 2486 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString, 2487 &Subtable); 2488 if (ACPI_FAILURE (Status)) 2489 { 2490 return (Status); 2491 } 2492 } 2493 2494 DtInsertSubtable (ParentTable, Subtable); 2495 2496 /* 2497 * Process the CID value. First, get the CID value as a string. 2498 */ 2499 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 2500 2501 if (UtIsIdInteger ((UINT8 *) &Temp64)) 2502 { 2503 /* Compile the CID value as an integer */ 2504 2505 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 2506 2507 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger, 2508 &Subtable); 2509 if (ACPI_FAILURE (Status)) 2510 { 2511 return (Status); 2512 } 2513 } 2514 else 2515 { 2516 /* Compile the CID value as a string */ 2517 2518 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString, 2519 &Subtable); 2520 if (ACPI_FAILURE (Status)) 2521 { 2522 return (Status); 2523 } 2524 } 2525 2526 DtInsertSubtable (ParentTable, Subtable); 2527 2528 /* 2529 * Process the UID value. First, get and decode the "UID Format" field (Integer). 2530 */ 2531 if (!*PFieldList) 2532 { 2533 return (AE_OK); 2534 } 2535 2536 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0); 2537 2538 switch (Temp8) 2539 { 2540 case ACPI_IVRS_UID_NOT_PRESENT: 2541 break; 2542 2543 case ACPI_IVRS_UID_IS_INTEGER: 2544 2545 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger, 2546 &Subtable); 2547 if (ACPI_FAILURE (Status)) 2548 { 2549 return (Status); 2550 } 2551 DtInsertSubtable (ParentTable, Subtable); 2552 break; 2553 2554 case ACPI_IVRS_UID_IS_STRING: 2555 2556 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString, 2557 &Subtable); 2558 if (ACPI_FAILURE (Status)) 2559 { 2560 return (Status); 2561 } 2562 DtInsertSubtable (ParentTable, Subtable); 2563 break; 2564 2565 default: 2566 2567 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart, 2568 "IVRS Device Entry"); 2569 return (AE_ERROR); 2570 } 2571 2572 default: 2573 2574 /* All other subtable types come through here */ 2575 break; 2576 } 2577 } 2578 2579 return (AE_OK); 2580 } 2581