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 - 2022, 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: DtCompileApmt 393 * 394 * PARAMETERS: List - Current field list pointer 395 * 396 * RETURN: Status 397 * 398 * DESCRIPTION: Compile APMT. 399 * 400 *****************************************************************************/ 401 402 ACPI_STATUS 403 DtCompileApmt ( 404 void **List) 405 { 406 ACPI_STATUS Status; 407 ACPI_TABLE_HEADER *Header; 408 ACPI_APMT_NODE *ApmtNode; 409 ACPI_APMT_NODE *PeerApmtNode; 410 DT_SUBTABLE *Subtable; 411 DT_SUBTABLE *PeerSubtable; 412 DT_SUBTABLE *ParentTable; 413 DT_FIELD **PFieldList = (DT_FIELD**)List; 414 DT_FIELD *SubtableStart; 415 UINT32 CurLength; 416 char MsgBuffer[64] = ""; 417 418 ParentTable = DtPeekSubtable(); 419 420 Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer); 421 422 CurLength = sizeof(ACPI_TABLE_HEADER); 423 424 /* Walk the parse tree */ 425 426 while (*PFieldList) 427 { 428 /* APMT Node Subtable */ 429 430 SubtableStart = *PFieldList; 431 432 Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable); 433 434 if (ACPI_FAILURE(Status)) 435 { 436 return (Status); 437 } 438 439 ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer); 440 441 if (ApmtNode->Length != sizeof(ACPI_APMT_NODE)) 442 { 443 DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT"); 444 return (AE_ERROR); 445 } 446 447 if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT) 448 { 449 snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type); 450 DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer); 451 return (AE_ERROR); 452 } 453 454 PeerSubtable = DtGetNextSubtable(ParentTable, NULL); 455 456 /* Validate the node id needs to be unique. */ 457 while(PeerSubtable) 458 { 459 PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer); 460 if (PeerApmtNode->Id == ApmtNode->Id) 461 { 462 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id); 463 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer); 464 return (AE_ERROR); 465 } 466 467 PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable); 468 } 469 470 CurLength += ApmtNode->Length; 471 472 DtInsertSubtable(ParentTable, Subtable); 473 } 474 475 if (Header->Length != CurLength) 476 { 477 snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)", 478 Header->Length, CurLength); 479 DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer); 480 return (AE_ERROR); 481 } 482 483 return (AE_OK); 484 } 485 486 /****************************************************************************** 487 * 488 * FUNCTION: DtCompileAsf 489 * 490 * PARAMETERS: List - Current field list pointer 491 * 492 * RETURN: Status 493 * 494 * DESCRIPTION: Compile ASF!. 495 * 496 *****************************************************************************/ 497 498 ACPI_STATUS 499 DtCompileAsf ( 500 void **List) 501 { 502 ACPI_ASF_INFO *AsfTable; 503 DT_SUBTABLE *Subtable; 504 DT_SUBTABLE *ParentTable; 505 ACPI_DMTABLE_INFO *InfoTable; 506 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 507 UINT32 DataCount = 0; 508 ACPI_STATUS Status; 509 UINT32 i; 510 DT_FIELD **PFieldList = (DT_FIELD **) List; 511 DT_FIELD *SubtableStart; 512 513 514 while (*PFieldList) 515 { 516 SubtableStart = *PFieldList; 517 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 518 &Subtable); 519 if (ACPI_FAILURE (Status)) 520 { 521 return (Status); 522 } 523 524 ParentTable = DtPeekSubtable (); 525 DtInsertSubtable (ParentTable, Subtable); 526 DtPushSubtable (Subtable); 527 528 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 529 530 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 531 { 532 case ACPI_ASF_TYPE_INFO: 533 534 InfoTable = AcpiDmTableInfoAsf0; 535 break; 536 537 case ACPI_ASF_TYPE_ALERT: 538 539 InfoTable = AcpiDmTableInfoAsf1; 540 break; 541 542 case ACPI_ASF_TYPE_CONTROL: 543 544 InfoTable = AcpiDmTableInfoAsf2; 545 break; 546 547 case ACPI_ASF_TYPE_BOOT: 548 549 InfoTable = AcpiDmTableInfoAsf3; 550 break; 551 552 case ACPI_ASF_TYPE_ADDRESS: 553 554 InfoTable = AcpiDmTableInfoAsf4; 555 break; 556 557 default: 558 559 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 560 return (AE_ERROR); 561 } 562 563 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 564 if (ACPI_FAILURE (Status)) 565 { 566 return (Status); 567 } 568 569 ParentTable = DtPeekSubtable (); 570 DtInsertSubtable (ParentTable, Subtable); 571 572 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 573 { 574 case ACPI_ASF_TYPE_INFO: 575 576 DataInfoTable = NULL; 577 break; 578 579 case ACPI_ASF_TYPE_ALERT: 580 581 DataInfoTable = AcpiDmTableInfoAsf1a; 582 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 583 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 584 sizeof (ACPI_ASF_HEADER)))->Alerts; 585 break; 586 587 case ACPI_ASF_TYPE_CONTROL: 588 589 DataInfoTable = AcpiDmTableInfoAsf2a; 590 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 591 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 592 sizeof (ACPI_ASF_HEADER)))->Controls; 593 break; 594 595 case ACPI_ASF_TYPE_BOOT: 596 597 DataInfoTable = NULL; 598 break; 599 600 case ACPI_ASF_TYPE_ADDRESS: 601 602 DataInfoTable = TableInfoAsfAddress; 603 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 604 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 605 sizeof (ACPI_ASF_HEADER)))->Devices; 606 break; 607 608 default: 609 610 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 611 return (AE_ERROR); 612 } 613 614 if (DataInfoTable) 615 { 616 switch (AsfTable->Header.Type & 0x7F) 617 { 618 case ACPI_ASF_TYPE_ADDRESS: 619 620 while (DataCount > 0) 621 { 622 Status = DtCompileTable (PFieldList, DataInfoTable, 623 &Subtable); 624 if (ACPI_FAILURE (Status)) 625 { 626 return (Status); 627 } 628 629 DtInsertSubtable (ParentTable, Subtable); 630 DataCount = DataCount - Subtable->Length; 631 } 632 break; 633 634 default: 635 636 for (i = 0; i < DataCount; i++) 637 { 638 Status = DtCompileTable (PFieldList, DataInfoTable, 639 &Subtable); 640 if (ACPI_FAILURE (Status)) 641 { 642 return (Status); 643 } 644 645 DtInsertSubtable (ParentTable, Subtable); 646 } 647 break; 648 } 649 } 650 651 DtPopSubtable (); 652 } 653 654 return (AE_OK); 655 } 656 657 658 /****************************************************************************** 659 * 660 * FUNCTION: DtCompileCdat 661 * 662 * PARAMETERS: List - Current field list pointer 663 * 664 * RETURN: Status 665 * 666 * DESCRIPTION: Compile CDAT. 667 * 668 *****************************************************************************/ 669 670 ACPI_STATUS 671 DtCompileCdat ( 672 void **List) 673 { 674 ACPI_STATUS Status = AE_OK; 675 DT_SUBTABLE *Subtable; 676 DT_SUBTABLE *ParentTable; 677 DT_FIELD **PFieldList = (DT_FIELD **) List; 678 ACPI_CDAT_HEADER *CdatHeader; 679 ACPI_DMTABLE_INFO *InfoTable = NULL; 680 DT_FIELD *SubtableStart; 681 682 683 /* Walk the parse tree. 684 * 685 * Note: Main table consists of only the CDAT table header 686 * (This is not the standard ACPI table header, however)-- 687 * Followed by some number of subtables. 688 */ 689 while (*PFieldList) 690 { 691 SubtableStart = *PFieldList; 692 693 /* Compile the expected CDAT Subtable header */ 694 695 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader, 696 &Subtable); 697 if (ACPI_FAILURE (Status)) 698 { 699 return (Status); 700 } 701 702 ParentTable = DtPeekSubtable (); 703 DtInsertSubtable (ParentTable, Subtable); 704 DtPushSubtable (Subtable); 705 706 CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer); 707 708 /* Decode the subtable by type */ 709 710 switch (CdatHeader->Type) 711 { 712 case ACPI_CDAT_TYPE_DSMAS: 713 InfoTable = AcpiDmTableInfoCdat0; 714 break; 715 716 case ACPI_CDAT_TYPE_DSLBIS: 717 InfoTable = AcpiDmTableInfoCdat1; 718 break; 719 720 case ACPI_CDAT_TYPE_DSMSCIS: 721 InfoTable = AcpiDmTableInfoCdat2; 722 break; 723 724 case ACPI_CDAT_TYPE_DSIS: 725 InfoTable = AcpiDmTableInfoCdat3; 726 break; 727 728 case ACPI_CDAT_TYPE_DSEMTS: 729 InfoTable = AcpiDmTableInfoCdat4; 730 break; 731 732 case ACPI_CDAT_TYPE_SSLBIS: 733 InfoTable = AcpiDmTableInfoCdat5; 734 break; 735 736 default: 737 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT"); 738 } 739 740 /* Compile the CDAT subtable */ 741 742 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 743 if (ACPI_FAILURE (Status)) 744 { 745 return (Status); 746 } 747 748 ParentTable = DtPeekSubtable (); 749 DtInsertSubtable (ParentTable, Subtable); 750 751 switch (CdatHeader->Type) 752 { 753 /* Multiple entries supported for this type */ 754 755 case ACPI_CDAT_TYPE_SSLBIS: 756 757 /* 758 * Check for multiple SSLBEs 759 */ 760 while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID")) 761 { 762 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable); 763 if (ACPI_FAILURE (Status)) 764 { 765 return (Status); 766 } 767 ParentTable = DtPeekSubtable (); 768 DtInsertSubtable (ParentTable, Subtable); 769 } 770 break; 771 772 default: 773 break; 774 } 775 776 /* Pop off the CDAT Subtable header subtree */ 777 778 DtPopSubtable (); 779 } 780 781 return (AE_OK); 782 } 783 784 785 /****************************************************************************** 786 * 787 * FUNCTION: DtCompileCedt 788 * 789 * PARAMETERS: List - Current field list pointer 790 * 791 * RETURN: Status 792 * 793 * DESCRIPTION: Compile CEDT. 794 * 795 *****************************************************************************/ 796 797 ACPI_STATUS 798 DtCompileCedt ( 799 void **List) 800 { 801 ACPI_STATUS Status; 802 DT_SUBTABLE *Subtable; 803 DT_SUBTABLE *ParentTable; 804 DT_FIELD **PFieldList = (DT_FIELD **) List; 805 ACPI_CEDT_HEADER *CedtHeader; 806 DT_FIELD *SubtableStart; 807 808 809 /* Walk the parse tree */ 810 811 while (*PFieldList) 812 { 813 /* if CFMWS and has more than one target, then set to zero later */ 814 815 int InsertFlag = 1; 816 SubtableStart = *PFieldList; 817 818 /* CEDT Header */ 819 820 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr, 821 &Subtable); 822 if (ACPI_FAILURE (Status)) 823 { 824 return (Status); 825 } 826 827 ParentTable = DtPeekSubtable (); 828 DtInsertSubtable (ParentTable, Subtable); 829 DtPushSubtable (Subtable); 830 831 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer); 832 833 switch (CedtHeader->Type) 834 { 835 case ACPI_CEDT_TYPE_CHBS: 836 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable); 837 if (ACPI_FAILURE (Status)) 838 { 839 return (Status); 840 } 841 break; 842 case ACPI_CEDT_TYPE_CFMWS: { 843 unsigned char *dump; 844 unsigned int idx, offset, max = 0; 845 846 /* Compile table with first "Interleave target" */ 847 848 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable); 849 if (ACPI_FAILURE (Status)) 850 { 851 return (Status); 852 } 853 854 /* Look in buffer for the number of targets */ 855 offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays); 856 dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt1 */ 857 max = 0x01 << dump[offset]; /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */ 858 if (max > 8) max=1; /* Error in encoding Interleaving Ways. */ 859 if (max == 1) /* if only one target, then break here. */ 860 break; /* break if only one target. */ 861 862 /* We need to add more interleave targets, so write the current Subtable. */ 863 864 ParentTable = DtPeekSubtable (); 865 DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt1 table so we can put in */ 866 DtPushSubtable (Subtable); /* the targets > the first. */ 867 868 /* Now, find out all interleave targets beyond the first. */ 869 870 for (idx = 1; idx < max; idx++) { 871 ParentTable = DtPeekSubtable (); 872 873 if (*PFieldList) 874 { 875 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable); 876 if (ACPI_FAILURE (Status)) 877 { 878 return (Status); 879 } 880 if (Subtable) 881 { 882 DtInsertSubtable (ParentTable, Subtable); /* got a target, so insert table. */ 883 InsertFlag = 0; 884 } 885 } 886 } 887 888 DtPopSubtable (); 889 ParentTable = DtPeekSubtable (); 890 break; 891 } 892 893 default: 894 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT"); 895 return (AE_ERROR); 896 } 897 898 ParentTable = DtPeekSubtable (); 899 if (InsertFlag == 1) { 900 DtInsertSubtable (ParentTable, Subtable); 901 } 902 DtPopSubtable (); 903 } 904 905 return (AE_OK); 906 } 907 908 909 /****************************************************************************** 910 * 911 * FUNCTION: DtCompileCpep 912 * 913 * PARAMETERS: List - Current field list pointer 914 * 915 * RETURN: Status 916 * 917 * DESCRIPTION: Compile CPEP. 918 * 919 *****************************************************************************/ 920 921 ACPI_STATUS 922 DtCompileCpep ( 923 void **List) 924 { 925 ACPI_STATUS Status; 926 927 928 Status = DtCompileTwoSubtables (List, 929 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 930 return (Status); 931 } 932 933 934 /****************************************************************************** 935 * 936 * FUNCTION: DtCompileCsrt 937 * 938 * PARAMETERS: List - Current field list pointer 939 * 940 * RETURN: Status 941 * 942 * DESCRIPTION: Compile CSRT. 943 * 944 *****************************************************************************/ 945 946 ACPI_STATUS 947 DtCompileCsrt ( 948 void **List) 949 { 950 ACPI_STATUS Status = AE_OK; 951 DT_SUBTABLE *Subtable; 952 DT_SUBTABLE *ParentTable; 953 DT_FIELD **PFieldList = (DT_FIELD **) List; 954 UINT32 DescriptorCount; 955 UINT32 GroupLength; 956 957 958 /* Subtables (Resource Groups) */ 959 960 ParentTable = DtPeekSubtable (); 961 while (*PFieldList) 962 { 963 /* Resource group subtable */ 964 965 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 966 &Subtable); 967 if (ACPI_FAILURE (Status)) 968 { 969 return (Status); 970 } 971 972 /* Compute the number of resource descriptors */ 973 974 GroupLength = 975 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 976 Subtable->Buffer))->Length - 977 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 978 Subtable->Buffer))->SharedInfoLength - 979 sizeof (ACPI_CSRT_GROUP); 980 981 DescriptorCount = (GroupLength / 982 sizeof (ACPI_CSRT_DESCRIPTOR)); 983 984 DtInsertSubtable (ParentTable, Subtable); 985 DtPushSubtable (Subtable); 986 ParentTable = DtPeekSubtable (); 987 988 /* Shared info subtable (One per resource group) */ 989 990 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 991 &Subtable); 992 if (ACPI_FAILURE (Status)) 993 { 994 return (Status); 995 } 996 997 DtInsertSubtable (ParentTable, Subtable); 998 999 /* Sub-Subtables (Resource Descriptors) */ 1000 1001 while (*PFieldList && DescriptorCount) 1002 { 1003 1004 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 1005 &Subtable); 1006 if (ACPI_FAILURE (Status)) 1007 { 1008 return (Status); 1009 } 1010 1011 DtInsertSubtable (ParentTable, Subtable); 1012 1013 DtPushSubtable (Subtable); 1014 ParentTable = DtPeekSubtable (); 1015 if (*PFieldList) 1016 { 1017 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 1018 &Subtable); 1019 if (ACPI_FAILURE (Status)) 1020 { 1021 return (Status); 1022 } 1023 if (Subtable) 1024 { 1025 DtInsertSubtable (ParentTable, Subtable); 1026 } 1027 } 1028 1029 DtPopSubtable (); 1030 ParentTable = DtPeekSubtable (); 1031 DescriptorCount--; 1032 } 1033 1034 DtPopSubtable (); 1035 ParentTable = DtPeekSubtable (); 1036 } 1037 1038 return (Status); 1039 } 1040 1041 1042 /****************************************************************************** 1043 * 1044 * FUNCTION: DtCompileDbg2 1045 * 1046 * PARAMETERS: List - Current field list pointer 1047 * 1048 * RETURN: Status 1049 * 1050 * DESCRIPTION: Compile DBG2. 1051 * 1052 *****************************************************************************/ 1053 1054 ACPI_STATUS 1055 DtCompileDbg2 ( 1056 void **List) 1057 { 1058 ACPI_STATUS Status; 1059 DT_SUBTABLE *Subtable; 1060 DT_SUBTABLE *ParentTable; 1061 DT_FIELD **PFieldList = (DT_FIELD **) List; 1062 UINT32 SubtableCount; 1063 ACPI_DBG2_HEADER *Dbg2Header; 1064 ACPI_DBG2_DEVICE *DeviceInfo; 1065 UINT16 CurrentOffset; 1066 UINT32 i; 1067 1068 1069 /* Main table */ 1070 1071 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable); 1072 if (ACPI_FAILURE (Status)) 1073 { 1074 return (Status); 1075 } 1076 1077 ParentTable = DtPeekSubtable (); 1078 DtInsertSubtable (ParentTable, Subtable); 1079 1080 /* Main table fields */ 1081 1082 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 1083 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 1084 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 1085 1086 SubtableCount = Dbg2Header->InfoCount; 1087 DtPushSubtable (Subtable); 1088 1089 /* Process all Device Information subtables (Count = InfoCount) */ 1090 1091 while (*PFieldList && SubtableCount) 1092 { 1093 /* Subtable: Debug Device Information */ 1094 1095 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 1096 &Subtable); 1097 if (ACPI_FAILURE (Status)) 1098 { 1099 return (Status); 1100 } 1101 1102 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 1103 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 1104 1105 ParentTable = DtPeekSubtable (); 1106 DtInsertSubtable (ParentTable, Subtable); 1107 DtPushSubtable (Subtable); 1108 1109 ParentTable = DtPeekSubtable (); 1110 1111 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 1112 1113 DeviceInfo->BaseAddressOffset = CurrentOffset; 1114 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 1115 { 1116 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 1117 &Subtable); 1118 if (ACPI_FAILURE (Status)) 1119 { 1120 return (Status); 1121 } 1122 1123 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 1124 DtInsertSubtable (ParentTable, Subtable); 1125 } 1126 1127 /* AddressSize array (Required, size = RegisterCount) */ 1128 1129 DeviceInfo->AddressSizeOffset = CurrentOffset; 1130 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 1131 { 1132 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 1133 &Subtable); 1134 if (ACPI_FAILURE (Status)) 1135 { 1136 return (Status); 1137 } 1138 1139 CurrentOffset += (UINT16) sizeof (UINT32); 1140 DtInsertSubtable (ParentTable, Subtable); 1141 } 1142 1143 /* NamespaceString device identifier (Required, size = NamePathLength) */ 1144 1145 DeviceInfo->NamepathOffset = CurrentOffset; 1146 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 1147 &Subtable); 1148 if (ACPI_FAILURE (Status)) 1149 { 1150 return (Status); 1151 } 1152 1153 /* Update the device info header */ 1154 1155 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 1156 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 1157 DtInsertSubtable (ParentTable, Subtable); 1158 1159 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 1160 1161 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 1162 &Subtable); 1163 if (Status == AE_END_OF_TABLE) 1164 { 1165 /* optional field was not found and we're at the end of the file */ 1166 1167 goto subtableDone; 1168 } 1169 else if (ACPI_FAILURE (Status)) 1170 { 1171 return (Status); 1172 } 1173 1174 /* Update the device info header (zeros if no OEM data present) */ 1175 1176 DeviceInfo->OemDataOffset = 0; 1177 DeviceInfo->OemDataLength = 0; 1178 1179 /* Optional subtable (OemData) */ 1180 1181 if (Subtable && Subtable->Length) 1182 { 1183 DeviceInfo->OemDataOffset = CurrentOffset; 1184 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 1185 1186 DtInsertSubtable (ParentTable, Subtable); 1187 } 1188 subtableDone: 1189 SubtableCount--; 1190 DtPopSubtable (); /* Get next Device Information subtable */ 1191 } 1192 1193 DtPopSubtable (); 1194 return (AE_OK); 1195 } 1196 1197 1198 /****************************************************************************** 1199 * 1200 * FUNCTION: DtCompileDmar 1201 * 1202 * PARAMETERS: List - Current field list pointer 1203 * 1204 * RETURN: Status 1205 * 1206 * DESCRIPTION: Compile DMAR. 1207 * 1208 *****************************************************************************/ 1209 1210 ACPI_STATUS 1211 DtCompileDmar ( 1212 void **List) 1213 { 1214 ACPI_STATUS Status; 1215 DT_SUBTABLE *Subtable; 1216 DT_SUBTABLE *ParentTable; 1217 DT_FIELD **PFieldList = (DT_FIELD **) List; 1218 DT_FIELD *SubtableStart; 1219 ACPI_DMTABLE_INFO *InfoTable; 1220 ACPI_DMAR_HEADER *DmarHeader; 1221 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 1222 UINT32 DeviceScopeLength; 1223 UINT32 PciPathLength; 1224 1225 1226 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable); 1227 if (ACPI_FAILURE (Status)) 1228 { 1229 return (Status); 1230 } 1231 1232 ParentTable = DtPeekSubtable (); 1233 DtInsertSubtable (ParentTable, Subtable); 1234 DtPushSubtable (Subtable); 1235 1236 while (*PFieldList) 1237 { 1238 /* DMAR Header */ 1239 1240 SubtableStart = *PFieldList; 1241 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 1242 &Subtable); 1243 if (ACPI_FAILURE (Status)) 1244 { 1245 return (Status); 1246 } 1247 1248 ParentTable = DtPeekSubtable (); 1249 DtInsertSubtable (ParentTable, Subtable); 1250 DtPushSubtable (Subtable); 1251 1252 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 1253 1254 switch (DmarHeader->Type) 1255 { 1256 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 1257 1258 InfoTable = AcpiDmTableInfoDmar0; 1259 break; 1260 1261 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 1262 1263 InfoTable = AcpiDmTableInfoDmar1; 1264 break; 1265 1266 case ACPI_DMAR_TYPE_ROOT_ATS: 1267 1268 InfoTable = AcpiDmTableInfoDmar2; 1269 break; 1270 1271 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 1272 1273 InfoTable = AcpiDmTableInfoDmar3; 1274 break; 1275 1276 case ACPI_DMAR_TYPE_NAMESPACE: 1277 1278 InfoTable = AcpiDmTableInfoDmar4; 1279 break; 1280 1281 case ACPI_DMAR_TYPE_SATC: 1282 1283 InfoTable = AcpiDmTableInfoDmar5; 1284 break; 1285 1286 default: 1287 1288 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 1289 return (AE_ERROR); 1290 } 1291 1292 /* DMAR Subtable */ 1293 1294 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1295 if (ACPI_FAILURE (Status)) 1296 { 1297 return (Status); 1298 } 1299 1300 ParentTable = DtPeekSubtable (); 1301 DtInsertSubtable (ParentTable, Subtable); 1302 1303 /* 1304 * Optional Device Scope subtables 1305 */ 1306 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 1307 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 1308 { 1309 /* These types do not support device scopes */ 1310 1311 DtPopSubtable (); 1312 continue; 1313 } 1314 1315 DtPushSubtable (Subtable); 1316 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 1317 ParentTable->Length; 1318 while (DeviceScopeLength) 1319 { 1320 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 1321 &Subtable); 1322 if (Status == AE_NOT_FOUND) 1323 { 1324 break; 1325 } 1326 1327 ParentTable = DtPeekSubtable (); 1328 DtInsertSubtable (ParentTable, Subtable); 1329 DtPushSubtable (Subtable); 1330 1331 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 1332 1333 /* Optional PCI Paths */ 1334 1335 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 1336 while (PciPathLength) 1337 { 1338 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 1339 &Subtable); 1340 if (Status == AE_NOT_FOUND) 1341 { 1342 DtPopSubtable (); 1343 break; 1344 } 1345 1346 ParentTable = DtPeekSubtable (); 1347 DtInsertSubtable (ParentTable, Subtable); 1348 PciPathLength -= Subtable->Length; 1349 } 1350 1351 DtPopSubtable (); 1352 DeviceScopeLength -= DmarDeviceScope->Length; 1353 } 1354 1355 DtPopSubtable (); 1356 DtPopSubtable (); 1357 } 1358 1359 return (AE_OK); 1360 } 1361 1362 1363 /****************************************************************************** 1364 * 1365 * FUNCTION: DtCompileDrtm 1366 * 1367 * PARAMETERS: List - Current field list pointer 1368 * 1369 * RETURN: Status 1370 * 1371 * DESCRIPTION: Compile DRTM. 1372 * 1373 *****************************************************************************/ 1374 1375 ACPI_STATUS 1376 DtCompileDrtm ( 1377 void **List) 1378 { 1379 ACPI_STATUS Status; 1380 DT_SUBTABLE *Subtable; 1381 DT_SUBTABLE *ParentTable; 1382 DT_FIELD **PFieldList = (DT_FIELD **) List; 1383 UINT32 Count; 1384 /* ACPI_TABLE_DRTM *Drtm; */ 1385 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 1386 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 1387 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 1388 1389 1390 ParentTable = DtPeekSubtable (); 1391 1392 /* Compile DRTM header */ 1393 1394 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 1395 &Subtable); 1396 if (ACPI_FAILURE (Status)) 1397 { 1398 return (Status); 1399 } 1400 DtInsertSubtable (ParentTable, Subtable); 1401 1402 /* 1403 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1404 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 1405 */ 1406 #if 0 1407 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 1408 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1409 #endif 1410 /* Compile VTL */ 1411 1412 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 1413 &Subtable); 1414 if (ACPI_FAILURE (Status)) 1415 { 1416 return (Status); 1417 } 1418 1419 DtInsertSubtable (ParentTable, Subtable); 1420 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 1421 1422 DtPushSubtable (Subtable); 1423 ParentTable = DtPeekSubtable (); 1424 Count = 0; 1425 1426 while (*PFieldList) 1427 { 1428 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 1429 &Subtable); 1430 if (ACPI_FAILURE (Status)) 1431 { 1432 return (Status); 1433 } 1434 if (!Subtable) 1435 { 1436 break; 1437 } 1438 DtInsertSubtable (ParentTable, Subtable); 1439 Count++; 1440 } 1441 1442 DrtmVtl->ValidatedTableCount = Count; 1443 DtPopSubtable (); 1444 ParentTable = DtPeekSubtable (); 1445 1446 /* Compile RL */ 1447 1448 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 1449 &Subtable); 1450 if (ACPI_FAILURE (Status)) 1451 { 1452 return (Status); 1453 } 1454 1455 DtInsertSubtable (ParentTable, Subtable); 1456 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 1457 1458 DtPushSubtable (Subtable); 1459 ParentTable = DtPeekSubtable (); 1460 Count = 0; 1461 1462 while (*PFieldList) 1463 { 1464 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 1465 &Subtable); 1466 if (ACPI_FAILURE (Status)) 1467 { 1468 return (Status); 1469 } 1470 1471 if (!Subtable) 1472 { 1473 break; 1474 } 1475 1476 DtInsertSubtable (ParentTable, Subtable); 1477 Count++; 1478 } 1479 1480 DrtmRl->ResourceCount = Count; 1481 DtPopSubtable (); 1482 ParentTable = DtPeekSubtable (); 1483 1484 /* Compile DPS */ 1485 1486 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 1487 &Subtable); 1488 if (ACPI_FAILURE (Status)) 1489 { 1490 return (Status); 1491 } 1492 DtInsertSubtable (ParentTable, Subtable); 1493 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 1494 1495 1496 return (AE_OK); 1497 } 1498 1499 1500 /****************************************************************************** 1501 * 1502 * FUNCTION: DtCompileEinj 1503 * 1504 * PARAMETERS: List - Current field list pointer 1505 * 1506 * RETURN: Status 1507 * 1508 * DESCRIPTION: Compile EINJ. 1509 * 1510 *****************************************************************************/ 1511 1512 ACPI_STATUS 1513 DtCompileEinj ( 1514 void **List) 1515 { 1516 ACPI_STATUS Status; 1517 1518 1519 Status = DtCompileTwoSubtables (List, 1520 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 1521 return (Status); 1522 } 1523 1524 1525 /****************************************************************************** 1526 * 1527 * FUNCTION: DtCompileErst 1528 * 1529 * PARAMETERS: List - Current field list pointer 1530 * 1531 * RETURN: Status 1532 * 1533 * DESCRIPTION: Compile ERST. 1534 * 1535 *****************************************************************************/ 1536 1537 ACPI_STATUS 1538 DtCompileErst ( 1539 void **List) 1540 { 1541 ACPI_STATUS Status; 1542 1543 1544 Status = DtCompileTwoSubtables (List, 1545 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 1546 return (Status); 1547 } 1548 1549 1550 /****************************************************************************** 1551 * 1552 * FUNCTION: DtCompileGtdt 1553 * 1554 * PARAMETERS: List - Current field list pointer 1555 * 1556 * RETURN: Status 1557 * 1558 * DESCRIPTION: Compile GTDT. 1559 * 1560 *****************************************************************************/ 1561 1562 ACPI_STATUS 1563 DtCompileGtdt ( 1564 void **List) 1565 { 1566 ACPI_STATUS Status; 1567 DT_SUBTABLE *Subtable; 1568 DT_SUBTABLE *ParentTable; 1569 DT_FIELD **PFieldList = (DT_FIELD **) List; 1570 DT_FIELD *SubtableStart; 1571 ACPI_SUBTABLE_HEADER *GtdtHeader; 1572 ACPI_DMTABLE_INFO *InfoTable; 1573 UINT32 GtCount; 1574 ACPI_TABLE_HEADER *Header; 1575 1576 1577 ParentTable = DtPeekSubtable (); 1578 1579 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1580 1581 /* Compile the main table */ 1582 1583 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 1584 &Subtable); 1585 if (ACPI_FAILURE (Status)) 1586 { 1587 return (Status); 1588 } 1589 1590 /* GTDT revision 3 later contains 2 extra fields before subtables */ 1591 1592 if (Header->Revision > 2) 1593 { 1594 ParentTable = DtPeekSubtable (); 1595 DtInsertSubtable (ParentTable, Subtable); 1596 1597 Status = DtCompileTable (PFieldList, 1598 AcpiDmTableInfoGtdtEl2, &Subtable); 1599 if (ACPI_FAILURE (Status)) 1600 { 1601 return (Status); 1602 } 1603 } 1604 1605 ParentTable = DtPeekSubtable (); 1606 DtInsertSubtable (ParentTable, Subtable); 1607 1608 while (*PFieldList) 1609 { 1610 SubtableStart = *PFieldList; 1611 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 1612 &Subtable); 1613 if (ACPI_FAILURE (Status)) 1614 { 1615 return (Status); 1616 } 1617 1618 ParentTable = DtPeekSubtable (); 1619 DtInsertSubtable (ParentTable, Subtable); 1620 DtPushSubtable (Subtable); 1621 1622 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1623 1624 switch (GtdtHeader->Type) 1625 { 1626 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1627 1628 InfoTable = AcpiDmTableInfoGtdt0; 1629 break; 1630 1631 case ACPI_GTDT_TYPE_WATCHDOG: 1632 1633 InfoTable = AcpiDmTableInfoGtdt1; 1634 break; 1635 1636 default: 1637 1638 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 1639 return (AE_ERROR); 1640 } 1641 1642 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1643 if (ACPI_FAILURE (Status)) 1644 { 1645 return (Status); 1646 } 1647 1648 ParentTable = DtPeekSubtable (); 1649 DtInsertSubtable (ParentTable, Subtable); 1650 1651 /* 1652 * Additional GT block subtable data 1653 */ 1654 1655 switch (GtdtHeader->Type) 1656 { 1657 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1658 1659 DtPushSubtable (Subtable); 1660 ParentTable = DtPeekSubtable (); 1661 1662 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 1663 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 1664 1665 while (GtCount) 1666 { 1667 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 1668 &Subtable); 1669 if (ACPI_FAILURE (Status)) 1670 { 1671 return (Status); 1672 } 1673 1674 DtInsertSubtable (ParentTable, Subtable); 1675 GtCount--; 1676 } 1677 1678 DtPopSubtable (); 1679 break; 1680 1681 default: 1682 1683 break; 1684 } 1685 1686 DtPopSubtable (); 1687 } 1688 1689 return (AE_OK); 1690 } 1691 1692 1693 /****************************************************************************** 1694 * 1695 * FUNCTION: DtCompileFpdt 1696 * 1697 * PARAMETERS: List - Current field list pointer 1698 * 1699 * RETURN: Status 1700 * 1701 * DESCRIPTION: Compile FPDT. 1702 * 1703 *****************************************************************************/ 1704 1705 ACPI_STATUS 1706 DtCompileFpdt ( 1707 void **List) 1708 { 1709 ACPI_STATUS Status; 1710 ACPI_FPDT_HEADER *FpdtHeader; 1711 DT_SUBTABLE *Subtable; 1712 DT_SUBTABLE *ParentTable; 1713 ACPI_DMTABLE_INFO *InfoTable; 1714 DT_FIELD **PFieldList = (DT_FIELD **) List; 1715 DT_FIELD *SubtableStart; 1716 1717 1718 while (*PFieldList) 1719 { 1720 SubtableStart = *PFieldList; 1721 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1722 &Subtable); 1723 if (ACPI_FAILURE (Status)) 1724 { 1725 return (Status); 1726 } 1727 1728 ParentTable = DtPeekSubtable (); 1729 DtInsertSubtable (ParentTable, Subtable); 1730 DtPushSubtable (Subtable); 1731 1732 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1733 1734 switch (FpdtHeader->Type) 1735 { 1736 case ACPI_FPDT_TYPE_BOOT: 1737 1738 InfoTable = AcpiDmTableInfoFpdt0; 1739 break; 1740 1741 case ACPI_FPDT_TYPE_S3PERF: 1742 1743 InfoTable = AcpiDmTableInfoFpdt1; 1744 break; 1745 1746 default: 1747 1748 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1749 return (AE_ERROR); 1750 break; 1751 } 1752 1753 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1754 if (ACPI_FAILURE (Status)) 1755 { 1756 return (Status); 1757 } 1758 1759 ParentTable = DtPeekSubtable (); 1760 DtInsertSubtable (ParentTable, Subtable); 1761 DtPopSubtable (); 1762 } 1763 1764 return (AE_OK); 1765 } 1766 1767 1768 /****************************************************************************** 1769 * 1770 * FUNCTION: DtCompileHest 1771 * 1772 * PARAMETERS: List - Current field list pointer 1773 * 1774 * RETURN: Status 1775 * 1776 * DESCRIPTION: Compile HEST. 1777 * 1778 *****************************************************************************/ 1779 1780 ACPI_STATUS 1781 DtCompileHest ( 1782 void **List) 1783 { 1784 ACPI_STATUS Status; 1785 DT_SUBTABLE *Subtable; 1786 DT_SUBTABLE *ParentTable; 1787 DT_FIELD **PFieldList = (DT_FIELD **) List; 1788 DT_FIELD *SubtableStart; 1789 ACPI_DMTABLE_INFO *InfoTable; 1790 UINT16 Type; 1791 UINT32 BankCount; 1792 1793 1794 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1795 &Subtable); 1796 if (ACPI_FAILURE (Status)) 1797 { 1798 return (Status); 1799 } 1800 1801 ParentTable = DtPeekSubtable (); 1802 DtInsertSubtable (ParentTable, Subtable); 1803 1804 while (*PFieldList) 1805 { 1806 /* Get subtable type */ 1807 1808 SubtableStart = *PFieldList; 1809 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1810 1811 switch (Type) 1812 { 1813 case ACPI_HEST_TYPE_IA32_CHECK: 1814 1815 InfoTable = AcpiDmTableInfoHest0; 1816 break; 1817 1818 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1819 1820 InfoTable = AcpiDmTableInfoHest1; 1821 break; 1822 1823 case ACPI_HEST_TYPE_IA32_NMI: 1824 1825 InfoTable = AcpiDmTableInfoHest2; 1826 break; 1827 1828 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1829 1830 InfoTable = AcpiDmTableInfoHest6; 1831 break; 1832 1833 case ACPI_HEST_TYPE_AER_ENDPOINT: 1834 1835 InfoTable = AcpiDmTableInfoHest7; 1836 break; 1837 1838 case ACPI_HEST_TYPE_AER_BRIDGE: 1839 1840 InfoTable = AcpiDmTableInfoHest8; 1841 break; 1842 1843 case ACPI_HEST_TYPE_GENERIC_ERROR: 1844 1845 InfoTable = AcpiDmTableInfoHest9; 1846 break; 1847 1848 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 1849 1850 InfoTable = AcpiDmTableInfoHest10; 1851 break; 1852 1853 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1854 1855 InfoTable = AcpiDmTableInfoHest11; 1856 break; 1857 1858 default: 1859 1860 /* Cannot continue on unknown type */ 1861 1862 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1863 return (AE_ERROR); 1864 } 1865 1866 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1867 if (ACPI_FAILURE (Status)) 1868 { 1869 return (Status); 1870 } 1871 1872 DtInsertSubtable (ParentTable, Subtable); 1873 1874 /* 1875 * Additional subtable data - IA32 Error Bank(s) 1876 */ 1877 BankCount = 0; 1878 switch (Type) 1879 { 1880 case ACPI_HEST_TYPE_IA32_CHECK: 1881 1882 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1883 Subtable->Buffer))->NumHardwareBanks; 1884 break; 1885 1886 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1887 1888 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1889 Subtable->Buffer))->NumHardwareBanks; 1890 break; 1891 1892 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1893 1894 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 1895 Subtable->Buffer))->NumHardwareBanks; 1896 break; 1897 1898 default: 1899 1900 break; 1901 } 1902 1903 while (BankCount) 1904 { 1905 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1906 &Subtable); 1907 if (ACPI_FAILURE (Status)) 1908 { 1909 return (Status); 1910 } 1911 1912 DtInsertSubtable (ParentTable, Subtable); 1913 BankCount--; 1914 } 1915 } 1916 1917 return (AE_OK); 1918 } 1919 1920 1921 /****************************************************************************** 1922 * 1923 * FUNCTION: DtCompileHmat 1924 * 1925 * PARAMETERS: List - Current field list pointer 1926 * 1927 * RETURN: Status 1928 * 1929 * DESCRIPTION: Compile HMAT. 1930 * 1931 *****************************************************************************/ 1932 1933 ACPI_STATUS 1934 DtCompileHmat ( 1935 void **List) 1936 { 1937 ACPI_STATUS Status; 1938 DT_SUBTABLE *Subtable; 1939 DT_SUBTABLE *ParentTable; 1940 DT_FIELD **PFieldList = (DT_FIELD **) List; 1941 DT_FIELD *SubtableStart; 1942 DT_FIELD *EntryStart; 1943 ACPI_HMAT_STRUCTURE *HmatStruct; 1944 ACPI_HMAT_LOCALITY *HmatLocality; 1945 ACPI_HMAT_CACHE *HmatCache; 1946 ACPI_DMTABLE_INFO *InfoTable; 1947 UINT32 IntPDNumber; 1948 UINT32 TgtPDNumber; 1949 UINT64 EntryNumber; 1950 UINT16 SMBIOSHandleNumber; 1951 1952 1953 ParentTable = DtPeekSubtable (); 1954 1955 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 1956 &Subtable); 1957 if (ACPI_FAILURE (Status)) 1958 { 1959 return (Status); 1960 } 1961 DtInsertSubtable (ParentTable, Subtable); 1962 1963 while (*PFieldList) 1964 { 1965 /* Compile HMAT structure header */ 1966 1967 SubtableStart = *PFieldList; 1968 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 1969 &Subtable); 1970 if (ACPI_FAILURE (Status)) 1971 { 1972 return (Status); 1973 } 1974 DtInsertSubtable (ParentTable, Subtable); 1975 1976 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 1977 HmatStruct->Length = Subtable->Length; 1978 1979 /* Compile HMAT structure body */ 1980 1981 switch (HmatStruct->Type) 1982 { 1983 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 1984 1985 InfoTable = AcpiDmTableInfoHmat0; 1986 break; 1987 1988 case ACPI_HMAT_TYPE_LOCALITY: 1989 1990 InfoTable = AcpiDmTableInfoHmat1; 1991 break; 1992 1993 case ACPI_HMAT_TYPE_CACHE: 1994 1995 InfoTable = AcpiDmTableInfoHmat2; 1996 break; 1997 1998 default: 1999 2000 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 2001 return (AE_ERROR); 2002 } 2003 2004 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2005 if (ACPI_FAILURE (Status)) 2006 { 2007 return (Status); 2008 } 2009 DtInsertSubtable (ParentTable, Subtable); 2010 HmatStruct->Length += Subtable->Length; 2011 2012 /* Compile HMAT structure additionals */ 2013 2014 switch (HmatStruct->Type) 2015 { 2016 case ACPI_HMAT_TYPE_LOCALITY: 2017 2018 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 2019 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 2020 2021 /* Compile initiator proximity domain list */ 2022 2023 IntPDNumber = 0; 2024 while (*PFieldList) 2025 { 2026 Status = DtCompileTable (PFieldList, 2027 AcpiDmTableInfoHmat1a, &Subtable); 2028 if (ACPI_FAILURE (Status)) 2029 { 2030 return (Status); 2031 } 2032 if (!Subtable) 2033 { 2034 break; 2035 } 2036 DtInsertSubtable (ParentTable, Subtable); 2037 HmatStruct->Length += Subtable->Length; 2038 IntPDNumber++; 2039 } 2040 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 2041 2042 /* Compile target proximity domain list */ 2043 2044 TgtPDNumber = 0; 2045 while (*PFieldList) 2046 { 2047 Status = DtCompileTable (PFieldList, 2048 AcpiDmTableInfoHmat1b, &Subtable); 2049 if (ACPI_FAILURE (Status)) 2050 { 2051 return (Status); 2052 } 2053 if (!Subtable) 2054 { 2055 break; 2056 } 2057 DtInsertSubtable (ParentTable, Subtable); 2058 HmatStruct->Length += Subtable->Length; 2059 TgtPDNumber++; 2060 } 2061 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 2062 2063 /* Save start of the entries for reporting errors */ 2064 2065 EntryStart = *PFieldList; 2066 2067 /* Compile latency/bandwidth entries */ 2068 2069 EntryNumber = 0; 2070 while (*PFieldList) 2071 { 2072 Status = DtCompileTable (PFieldList, 2073 AcpiDmTableInfoHmat1c, &Subtable); 2074 if (ACPI_FAILURE (Status)) 2075 { 2076 return (Status); 2077 } 2078 if (!Subtable) 2079 { 2080 break; 2081 } 2082 DtInsertSubtable (ParentTable, Subtable); 2083 HmatStruct->Length += Subtable->Length; 2084 EntryNumber++; 2085 } 2086 2087 /* Validate number of entries */ 2088 2089 if (EntryNumber != 2090 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 2091 { 2092 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 2093 return (AE_ERROR); 2094 } 2095 break; 2096 2097 case ACPI_HMAT_TYPE_CACHE: 2098 2099 /* Compile SMBIOS handles */ 2100 2101 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 2102 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 2103 SMBIOSHandleNumber = 0; 2104 while (*PFieldList) 2105 { 2106 Status = DtCompileTable (PFieldList, 2107 AcpiDmTableInfoHmat2a, &Subtable); 2108 if (ACPI_FAILURE (Status)) 2109 { 2110 return (Status); 2111 } 2112 if (!Subtable) 2113 { 2114 break; 2115 } 2116 DtInsertSubtable (ParentTable, Subtable); 2117 HmatStruct->Length += Subtable->Length; 2118 SMBIOSHandleNumber++; 2119 } 2120 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 2121 break; 2122 2123 default: 2124 2125 break; 2126 } 2127 } 2128 2129 return (AE_OK); 2130 } 2131 2132 2133 /****************************************************************************** 2134 * 2135 * FUNCTION: DtCompileIort 2136 * 2137 * PARAMETERS: List - Current field list pointer 2138 * 2139 * RETURN: Status 2140 * 2141 * DESCRIPTION: Compile IORT. 2142 * 2143 *****************************************************************************/ 2144 2145 ACPI_STATUS 2146 DtCompileIort ( 2147 void **List) 2148 { 2149 ACPI_STATUS Status; 2150 DT_SUBTABLE *Subtable; 2151 DT_SUBTABLE *ParentTable; 2152 DT_FIELD **PFieldList = (DT_FIELD **) List; 2153 DT_FIELD *SubtableStart; 2154 ACPI_TABLE_HEADER *Table; 2155 ACPI_TABLE_IORT *Iort; 2156 ACPI_IORT_NODE *IortNode; 2157 ACPI_IORT_ITS_GROUP *IortItsGroup; 2158 ACPI_IORT_SMMU *IortSmmu; 2159 ACPI_IORT_RMR *IortRmr; 2160 UINT32 NodeNumber; 2161 UINT32 NodeLength; 2162 UINT32 IdMappingNumber; 2163 UINT32 ItsNumber; 2164 UINT32 ContextIrptNumber; 2165 UINT32 PmuIrptNumber; 2166 UINT32 PaddingLength; 2167 UINT8 Revision; 2168 UINT32 RmrCount; 2169 2170 2171 ParentTable = DtPeekSubtable (); 2172 2173 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 2174 &Subtable); 2175 if (ACPI_FAILURE (Status)) 2176 { 2177 return (Status); 2178 } 2179 DtInsertSubtable (ParentTable, Subtable); 2180 2181 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2182 Revision = Table->Revision; 2183 2184 /* IORT Revisions E, E.a & E.c have known issues and are not supported */ 2185 2186 if (Revision == 1 || Revision == 2 || Revision == 4) 2187 { 2188 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision"); 2189 return (AE_ERROR); 2190 } 2191 2192 /* 2193 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 2194 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 2195 */ 2196 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 2197 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 2198 2199 /* 2200 * OptionalPadding - Variable-length data 2201 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 2202 * Optionally allows the generic data types to be used for filling 2203 * this field. 2204 */ 2205 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 2206 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 2207 &Subtable); 2208 if (ACPI_FAILURE (Status)) 2209 { 2210 return (Status); 2211 } 2212 if (Subtable) 2213 { 2214 DtInsertSubtable (ParentTable, Subtable); 2215 Iort->NodeOffset += Subtable->Length; 2216 } 2217 else 2218 { 2219 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 2220 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 2221 if (ACPI_FAILURE (Status)) 2222 { 2223 return (Status); 2224 } 2225 Iort->NodeOffset += PaddingLength; 2226 } 2227 2228 NodeNumber = 0; 2229 while (*PFieldList) 2230 { 2231 SubtableStart = *PFieldList; 2232 if (Revision == 0) 2233 { 2234 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 2235 &Subtable); 2236 } 2237 else if (Revision >= 3) 2238 { 2239 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3, 2240 &Subtable); 2241 } 2242 2243 if (ACPI_FAILURE (Status)) 2244 { 2245 return (Status); 2246 } 2247 2248 DtInsertSubtable (ParentTable, Subtable); 2249 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 2250 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 2251 2252 DtPushSubtable (Subtable); 2253 ParentTable = DtPeekSubtable (); 2254 2255 switch (IortNode->Type) 2256 { 2257 case ACPI_IORT_NODE_ITS_GROUP: 2258 2259 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 2260 &Subtable); 2261 if (ACPI_FAILURE (Status)) 2262 { 2263 return (Status); 2264 } 2265 2266 DtInsertSubtable (ParentTable, Subtable); 2267 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 2268 NodeLength += Subtable->Length; 2269 2270 ItsNumber = 0; 2271 while (*PFieldList) 2272 { 2273 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 2274 &Subtable); 2275 if (ACPI_FAILURE (Status)) 2276 { 2277 return (Status); 2278 } 2279 if (!Subtable) 2280 { 2281 break; 2282 } 2283 2284 DtInsertSubtable (ParentTable, Subtable); 2285 NodeLength += Subtable->Length; 2286 ItsNumber++; 2287 } 2288 2289 IortItsGroup->ItsCount = ItsNumber; 2290 break; 2291 2292 case ACPI_IORT_NODE_NAMED_COMPONENT: 2293 2294 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 2295 &Subtable); 2296 if (ACPI_FAILURE (Status)) 2297 { 2298 return (Status); 2299 } 2300 2301 DtInsertSubtable (ParentTable, Subtable); 2302 NodeLength += Subtable->Length; 2303 2304 /* 2305 * Padding - Variable-length data 2306 * Optionally allows the offset of the ID mappings to be used 2307 * for filling this field. 2308 */ 2309 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 2310 &Subtable); 2311 if (ACPI_FAILURE (Status)) 2312 { 2313 return (Status); 2314 } 2315 2316 if (Subtable) 2317 { 2318 DtInsertSubtable (ParentTable, Subtable); 2319 NodeLength += Subtable->Length; 2320 } 2321 else 2322 { 2323 if (NodeLength > IortNode->MappingOffset) 2324 { 2325 return (AE_BAD_DATA); 2326 } 2327 2328 if (NodeLength < IortNode->MappingOffset) 2329 { 2330 Status = DtCompilePadding ( 2331 IortNode->MappingOffset - NodeLength, 2332 &Subtable); 2333 if (ACPI_FAILURE (Status)) 2334 { 2335 return (Status); 2336 } 2337 2338 DtInsertSubtable (ParentTable, Subtable); 2339 NodeLength = IortNode->MappingOffset; 2340 } 2341 } 2342 break; 2343 2344 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 2345 2346 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 2347 &Subtable); 2348 if (ACPI_FAILURE (Status)) 2349 { 2350 return (Status); 2351 } 2352 2353 DtInsertSubtable (ParentTable, Subtable); 2354 NodeLength += Subtable->Length; 2355 break; 2356 2357 case ACPI_IORT_NODE_SMMU: 2358 2359 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 2360 &Subtable); 2361 if (ACPI_FAILURE (Status)) 2362 { 2363 return (Status); 2364 } 2365 2366 DtInsertSubtable (ParentTable, Subtable); 2367 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 2368 NodeLength += Subtable->Length; 2369 2370 /* Compile global interrupt array */ 2371 2372 IortSmmu->GlobalInterruptOffset = NodeLength; 2373 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 2374 &Subtable); 2375 if (ACPI_FAILURE (Status)) 2376 { 2377 return (Status); 2378 } 2379 2380 DtInsertSubtable (ParentTable, Subtable); 2381 NodeLength += Subtable->Length; 2382 2383 /* Compile context interrupt array */ 2384 2385 ContextIrptNumber = 0; 2386 IortSmmu->ContextInterruptOffset = NodeLength; 2387 while (*PFieldList) 2388 { 2389 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 2390 &Subtable); 2391 if (ACPI_FAILURE (Status)) 2392 { 2393 return (Status); 2394 } 2395 2396 if (!Subtable) 2397 { 2398 break; 2399 } 2400 2401 DtInsertSubtable (ParentTable, Subtable); 2402 NodeLength += Subtable->Length; 2403 ContextIrptNumber++; 2404 } 2405 2406 IortSmmu->ContextInterruptCount = ContextIrptNumber; 2407 2408 /* Compile PMU interrupt array */ 2409 2410 PmuIrptNumber = 0; 2411 IortSmmu->PmuInterruptOffset = NodeLength; 2412 while (*PFieldList) 2413 { 2414 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 2415 &Subtable); 2416 if (ACPI_FAILURE (Status)) 2417 { 2418 return (Status); 2419 } 2420 2421 if (!Subtable) 2422 { 2423 break; 2424 } 2425 2426 DtInsertSubtable (ParentTable, Subtable); 2427 NodeLength += Subtable->Length; 2428 PmuIrptNumber++; 2429 } 2430 2431 IortSmmu->PmuInterruptCount = PmuIrptNumber; 2432 break; 2433 2434 case ACPI_IORT_NODE_SMMU_V3: 2435 2436 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 2437 &Subtable); 2438 if (ACPI_FAILURE (Status)) 2439 { 2440 return (Status); 2441 } 2442 2443 DtInsertSubtable (ParentTable, Subtable); 2444 NodeLength += Subtable->Length; 2445 break; 2446 2447 case ACPI_IORT_NODE_PMCG: 2448 2449 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5, 2450 &Subtable); 2451 if (ACPI_FAILURE (Status)) 2452 { 2453 return (Status); 2454 } 2455 2456 DtInsertSubtable (ParentTable, Subtable); 2457 NodeLength += Subtable->Length; 2458 break; 2459 2460 case ACPI_IORT_NODE_RMR: 2461 2462 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6, 2463 &Subtable); 2464 if (ACPI_FAILURE (Status)) 2465 { 2466 return (Status); 2467 } 2468 2469 DtInsertSubtable (ParentTable, Subtable); 2470 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer); 2471 NodeLength += Subtable->Length; 2472 2473 /* Compile RMR Descriptors */ 2474 2475 RmrCount = 0; 2476 IortRmr->RmrOffset = NodeLength; 2477 while (*PFieldList) 2478 { 2479 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a, 2480 &Subtable); 2481 if (ACPI_FAILURE (Status)) 2482 { 2483 return (Status); 2484 } 2485 2486 if (!Subtable) 2487 { 2488 break; 2489 } 2490 2491 DtInsertSubtable (ParentTable, Subtable); 2492 NodeLength += sizeof (ACPI_IORT_RMR_DESC); 2493 RmrCount++; 2494 } 2495 2496 IortRmr->RmrCount = RmrCount; 2497 break; 2498 2499 default: 2500 2501 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 2502 return (AE_ERROR); 2503 } 2504 2505 /* Compile Array of ID mappings */ 2506 2507 IortNode->MappingOffset = NodeLength; 2508 IdMappingNumber = 0; 2509 while (*PFieldList) 2510 { 2511 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 2512 &Subtable); 2513 if (ACPI_FAILURE (Status)) 2514 { 2515 return (Status); 2516 } 2517 2518 if (!Subtable) 2519 { 2520 break; 2521 } 2522 2523 DtInsertSubtable (ParentTable, Subtable); 2524 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 2525 IdMappingNumber++; 2526 } 2527 2528 IortNode->MappingCount = IdMappingNumber; 2529 if (!IdMappingNumber) 2530 { 2531 IortNode->MappingOffset = 0; 2532 } 2533 2534 /* 2535 * Node length can be determined by DT_LENGTH option 2536 * IortNode->Length = NodeLength; 2537 */ 2538 DtPopSubtable (); 2539 ParentTable = DtPeekSubtable (); 2540 NodeNumber++; 2541 } 2542 2543 Iort->NodeCount = NodeNumber; 2544 return (AE_OK); 2545 } 2546 2547 2548 /****************************************************************************** 2549 * 2550 * FUNCTION: DtCompileIvrs 2551 * 2552 * PARAMETERS: List - Current field list pointer 2553 * 2554 * RETURN: Status 2555 * 2556 * DESCRIPTION: Compile IVRS. Notes: 2557 * The IVRS is essentially a flat table, with the following 2558 * structure: 2559 * <Main ACPI Table Header> 2560 * <Main subtable - virtualization info> 2561 * <IVHD> 2562 * <Device Entries> 2563 * ... 2564 * <IVHD> 2565 * <Device Entries> 2566 * <IVMD> 2567 * ... 2568 * 2569 *****************************************************************************/ 2570 2571 ACPI_STATUS 2572 DtCompileIvrs ( 2573 void **List) 2574 { 2575 ACPI_STATUS Status; 2576 DT_SUBTABLE *Subtable; 2577 DT_SUBTABLE *ParentTable; 2578 DT_SUBTABLE *MainSubtable; 2579 DT_FIELD **PFieldList = (DT_FIELD **) List; 2580 DT_FIELD *SubtableStart; 2581 ACPI_DMTABLE_INFO *InfoTable = NULL; 2582 UINT8 SubtableType; 2583 UINT8 Temp64[16]; 2584 UINT8 Temp8; 2585 2586 2587 /* Main table */ 2588 2589 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 2590 &Subtable); 2591 if (ACPI_FAILURE (Status)) 2592 { 2593 return (Status); 2594 } 2595 2596 ParentTable = DtPeekSubtable (); 2597 DtInsertSubtable (ParentTable, Subtable); 2598 DtPushSubtable (Subtable); 2599 2600 /* Save a pointer to the main subtable */ 2601 2602 MainSubtable = Subtable; 2603 2604 while (*PFieldList) 2605 { 2606 SubtableStart = *PFieldList; 2607 2608 /* Compile the SubtableType integer */ 2609 2610 DtCompileInteger (&SubtableType, *PFieldList, 1, 0); 2611 2612 switch (SubtableType) 2613 { 2614 2615 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */ 2616 2617 case ACPI_IVRS_TYPE_HARDWARE1: 2618 2619 InfoTable = AcpiDmTableInfoIvrsHware1; 2620 break; 2621 2622 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */ 2623 2624 case ACPI_IVRS_TYPE_HARDWARE2: 2625 case ACPI_IVRS_TYPE_HARDWARE3: 2626 2627 InfoTable = AcpiDmTableInfoIvrsHware23; 2628 break; 2629 2630 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */ 2631 2632 case ACPI_IVRS_TYPE_MEMORY1: 2633 case ACPI_IVRS_TYPE_MEMORY2: 2634 case ACPI_IVRS_TYPE_MEMORY3: 2635 2636 InfoTable = AcpiDmTableInfoIvrsMemory; 2637 break; 2638 2639 /* 4-byte device entries */ 2640 2641 case ACPI_IVRS_TYPE_PAD4: 2642 case ACPI_IVRS_TYPE_ALL: 2643 case ACPI_IVRS_TYPE_SELECT: 2644 case ACPI_IVRS_TYPE_START: 2645 case ACPI_IVRS_TYPE_END: 2646 2647 InfoTable = AcpiDmTableInfoIvrs4; 2648 break; 2649 2650 /* 8-byte device entries, type A */ 2651 2652 case ACPI_IVRS_TYPE_ALIAS_SELECT: 2653 case ACPI_IVRS_TYPE_ALIAS_START: 2654 2655 InfoTable = AcpiDmTableInfoIvrs8a; 2656 break; 2657 2658 /* 8-byte device entries, type B */ 2659 2660 case ACPI_IVRS_TYPE_EXT_SELECT: 2661 case ACPI_IVRS_TYPE_EXT_START: 2662 2663 InfoTable = AcpiDmTableInfoIvrs8b; 2664 break; 2665 2666 /* 8-byte device entries, type C */ 2667 2668 case ACPI_IVRS_TYPE_SPECIAL: 2669 2670 InfoTable = AcpiDmTableInfoIvrs8c; 2671 break; 2672 2673 /* Variable device entries, type F0h */ 2674 2675 case ACPI_IVRS_TYPE_HID: 2676 2677 InfoTable = AcpiDmTableInfoIvrsHid; 2678 break; 2679 2680 default: 2681 2682 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 2683 "IVRS Device Entry"); 2684 return (AE_ERROR); 2685 } 2686 2687 /* Compile the InfoTable from above */ 2688 2689 Status = DtCompileTable (PFieldList, InfoTable, 2690 &Subtable); 2691 if (ACPI_FAILURE (Status)) 2692 { 2693 return (Status); 2694 } 2695 2696 ParentTable = DtPeekSubtable (); 2697 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 && 2698 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 && 2699 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 && 2700 SubtableType != ACPI_IVRS_TYPE_HID && 2701 SubtableType != ACPI_IVRS_TYPE_MEMORY1 && 2702 SubtableType != ACPI_IVRS_TYPE_MEMORY2 && 2703 SubtableType != ACPI_IVRS_TYPE_MEMORY3) 2704 { 2705 if (ParentTable) 2706 DtInsertSubtable (ParentTable, Subtable); 2707 } 2708 2709 switch (SubtableType) 2710 { 2711 case ACPI_IVRS_TYPE_HARDWARE1: 2712 case ACPI_IVRS_TYPE_HARDWARE2: 2713 case ACPI_IVRS_TYPE_HARDWARE3: 2714 case ACPI_IVRS_TYPE_MEMORY1: 2715 case ACPI_IVRS_TYPE_MEMORY2: 2716 case ACPI_IVRS_TYPE_MEMORY3: 2717 2718 /* Insert these IVHDs/IVMDs at the root subtable */ 2719 2720 DtInsertSubtable (MainSubtable, Subtable); 2721 DtPushSubtable (Subtable); 2722 break; 2723 2724 case ACPI_IVRS_TYPE_HID: 2725 2726 /* Special handling for the HID named device entry (0xF0) */ 2727 2728 if (ParentTable) 2729 { 2730 DtInsertSubtable (ParentTable, Subtable); 2731 } 2732 2733 /* 2734 * Process the HID value. First, get the HID value as a string. 2735 */ 2736 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 2737 2738 /* 2739 * Determine if the HID is an integer or a string. 2740 * An integer is defined to be 32 bits, with the upper 32 bits 2741 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit 2742 * integer or a character string. If an integer, the lower 2743 * 4 bytes of the field contain the integer and the upper 2744 * 4 bytes are padded with 0". 2745 */ 2746 if (UtIsIdInteger ((UINT8 *) &Temp64)) 2747 { 2748 /* Compile the HID value as an integer */ 2749 2750 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 2751 2752 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger, 2753 &Subtable); 2754 if (ACPI_FAILURE (Status)) 2755 { 2756 return (Status); 2757 } 2758 } 2759 else 2760 { 2761 /* Compile the HID value as a string */ 2762 2763 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString, 2764 &Subtable); 2765 if (ACPI_FAILURE (Status)) 2766 { 2767 return (Status); 2768 } 2769 } 2770 2771 DtInsertSubtable (ParentTable, Subtable); 2772 2773 /* 2774 * Process the CID value. First, get the CID value as a string. 2775 */ 2776 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 2777 2778 if (UtIsIdInteger ((UINT8 *) &Temp64)) 2779 { 2780 /* Compile the CID value as an integer */ 2781 2782 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 2783 2784 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger, 2785 &Subtable); 2786 if (ACPI_FAILURE (Status)) 2787 { 2788 return (Status); 2789 } 2790 } 2791 else 2792 { 2793 /* Compile the CID value as a string */ 2794 2795 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString, 2796 &Subtable); 2797 if (ACPI_FAILURE (Status)) 2798 { 2799 return (Status); 2800 } 2801 } 2802 2803 DtInsertSubtable (ParentTable, Subtable); 2804 2805 /* 2806 * Process the UID value. First, get and decode the "UID Format" field (Integer). 2807 */ 2808 if (!*PFieldList) 2809 { 2810 return (AE_OK); 2811 } 2812 2813 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0); 2814 2815 switch (Temp8) 2816 { 2817 case ACPI_IVRS_UID_NOT_PRESENT: 2818 break; 2819 2820 case ACPI_IVRS_UID_IS_INTEGER: 2821 2822 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger, 2823 &Subtable); 2824 if (ACPI_FAILURE (Status)) 2825 { 2826 return (Status); 2827 } 2828 DtInsertSubtable (ParentTable, Subtable); 2829 break; 2830 2831 case ACPI_IVRS_UID_IS_STRING: 2832 2833 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString, 2834 &Subtable); 2835 if (ACPI_FAILURE (Status)) 2836 { 2837 return (Status); 2838 } 2839 DtInsertSubtable (ParentTable, Subtable); 2840 break; 2841 2842 default: 2843 2844 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart, 2845 "IVRS Device Entry"); 2846 return (AE_ERROR); 2847 } 2848 2849 default: 2850 2851 /* All other subtable types come through here */ 2852 break; 2853 } 2854 } 2855 2856 return (AE_OK); 2857 } 2858