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 - 2025, 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 ACPI_AEST_NODE_INTERFACE_HEADER *AestNodeHeader; 210 UINT8 Revision; 211 ACPI_TABLE_HEADER *Header; 212 213 ParentTable = DtPeekSubtable (); 214 215 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 216 Revision = Header->Revision; 217 218 while (*PFieldList) 219 { 220 /* Compile the common error node header */ 221 222 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr, 223 &Subtable); 224 if (ACPI_FAILURE (Status)) 225 { 226 return (Status); 227 } 228 229 ParentTable = DtPeekSubtable (); 230 DtInsertSubtable (ParentTable, Subtable); 231 232 /* Everything past the error node header will be a subtable */ 233 234 DtPushSubtable (Subtable); 235 236 /* 237 * Compile the node-specific structure (Based on the error 238 * node header Type field) 239 */ 240 ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer); 241 242 /* Point past the common error node header */ 243 244 Offset = sizeof (ACPI_AEST_HEADER); 245 ErrorNodeHeader->NodeSpecificOffset = Offset; 246 247 /* Decode the error node type */ 248 249 switch (ErrorNodeHeader->Type) 250 { 251 case ACPI_AEST_PROCESSOR_ERROR_NODE: 252 253 InfoTable = AcpiDmTableInfoAestProcError; 254 break; 255 256 case ACPI_AEST_MEMORY_ERROR_NODE: 257 258 InfoTable = AcpiDmTableInfoAestMemError; 259 break; 260 261 case ACPI_AEST_SMMU_ERROR_NODE: 262 263 InfoTable = AcpiDmTableInfoAestSmmuError; 264 break; 265 266 case ACPI_AEST_VENDOR_ERROR_NODE: 267 switch (Revision) 268 { 269 case 1: 270 InfoTable = AcpiDmTableInfoAestVendorError; 271 break; 272 273 case 2: 274 InfoTable = AcpiDmTableInfoAestVendorV2Error; 275 break; 276 277 default: 278 AcpiOsPrintf ("Unknown AEST Vendor Error Revision: %X\n", 279 Revision); 280 return (AE_ERROR); 281 } 282 break; 283 284 case ACPI_AEST_GIC_ERROR_NODE: 285 286 InfoTable = AcpiDmTableInfoAestGicError; 287 break; 288 289 case ACPI_AEST_PCIE_ERROR_NODE: 290 291 InfoTable = AcpiDmTableInfoAestPCIeError; 292 break; 293 294 case ACPI_AEST_PROXY_ERROR_NODE: 295 296 InfoTable = AcpiDmTableInfoAestProxyError; 297 break; 298 299 /* Error case below */ 300 default: 301 AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n", 302 ErrorNodeHeader->Type); 303 return (AE_ERROR); 304 } 305 306 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 307 if (ACPI_FAILURE (Status)) 308 { 309 return (Status); 310 } 311 312 /* Point past the node-specific structure */ 313 314 Offset += Subtable->Length; 315 ErrorNodeHeader->NodeInterfaceOffset = Offset; 316 317 ParentTable = DtPeekSubtable (); 318 DtInsertSubtable (ParentTable, Subtable); 319 320 /* Compile any additional node-specific substructures */ 321 322 if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE) 323 { 324 /* 325 * Special handling for PROCESSOR_ERROR_NODE subtables 326 * (to handle the Resource Substructure via the ResourceType 327 * field). 328 */ 329 AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR, 330 Subtable->Buffer); 331 332 switch (AestProcessor->ResourceType) 333 { 334 case ACPI_AEST_CACHE_RESOURCE: 335 336 InfoTable = AcpiDmTableInfoAestCacheRsrc; 337 break; 338 339 case ACPI_AEST_TLB_RESOURCE: 340 341 InfoTable = AcpiDmTableInfoAestTlbRsrc; 342 break; 343 344 case ACPI_AEST_GENERIC_RESOURCE: 345 346 InfoTable = AcpiDmTableInfoAestGenRsrc; 347 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n", 348 AestProcessor->ResourceType); 349 return (AE_ERROR); 350 351 /* Error case below */ 352 default: 353 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n", 354 AestProcessor->ResourceType); 355 return (AE_ERROR); 356 } 357 358 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 359 if (ACPI_FAILURE (Status)) 360 { 361 return (Status); 362 } 363 364 /* Point past the resource substructure subtable */ 365 366 Offset += Subtable->Length; 367 ErrorNodeHeader->NodeInterfaceOffset = Offset; 368 369 ParentTable = DtPeekSubtable (); 370 DtInsertSubtable (ParentTable, Subtable); 371 } 372 373 /* Compile the (required) node interface structure */ 374 if (Revision == 1) 375 { 376 InfoTable = AcpiDmTableInfoAestXface; 377 } 378 else if (Revision == 2) 379 { 380 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXfaceHeader, 381 &Subtable); 382 if (ACPI_FAILURE (Status)) 383 { 384 return (Status); 385 } 386 387 ParentTable = DtPeekSubtable (); 388 DtInsertSubtable (ParentTable, Subtable); 389 390 Offset += Subtable->Length; 391 392 AestNodeHeader = ACPI_CAST_PTR (ACPI_AEST_NODE_INTERFACE_HEADER, 393 Subtable->Buffer); 394 395 switch (AestNodeHeader->GroupFormat) 396 { 397 case ACPI_AEST_NODE_GROUP_FORMAT_4K: 398 399 InfoTable = AcpiDmTableInfoAestXface4k; 400 break; 401 402 case ACPI_AEST_NODE_GROUP_FORMAT_16K: 403 404 InfoTable = AcpiDmTableInfoAestXface16k; 405 break; 406 407 case ACPI_AEST_NODE_GROUP_FORMAT_64K: 408 409 InfoTable = AcpiDmTableInfoAestXface64k; 410 break; 411 412 /* Error case below */ 413 default: 414 AcpiOsPrintf ("Unknown AEST Interface Group Format: %X\n", 415 AestNodeHeader->GroupFormat); 416 return (AE_ERROR); 417 } 418 } 419 else 420 { 421 AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision); 422 } 423 424 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 425 if (ACPI_FAILURE (Status)) 426 { 427 return (Status); 428 } 429 430 ErrorNodeHeader->NodeInterruptOffset = 0; 431 ParentTable = DtPeekSubtable (); 432 DtInsertSubtable (ParentTable, Subtable); 433 434 /* Compile each of the node interrupt structures */ 435 436 if (ErrorNodeHeader->NodeInterruptCount) 437 { 438 /* Point to the first interrupt structure */ 439 440 Offset += Subtable->Length; 441 ErrorNodeHeader->NodeInterruptOffset = Offset; 442 } 443 444 /* Compile each of the interrupt structures */ 445 446 for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++) 447 { 448 switch (Revision) { 449 case 1: 450 451 InfoTable = AcpiDmTableInfoAestXrupt; 452 break; 453 454 case 2: 455 456 InfoTable = AcpiDmTableInfoAestXruptV2; 457 break; 458 459 default: 460 AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision); 461 return (AE_ERROR); 462 } 463 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 464 if (ACPI_FAILURE (Status)) 465 { 466 return (Status); 467 } 468 469 ParentTable = DtPeekSubtable (); 470 DtInsertSubtable (ParentTable, Subtable); 471 } 472 473 /* Prepare for the next AEST Error node */ 474 475 DtPopSubtable (); 476 } 477 478 return (AE_OK); 479 } 480 481 482 /****************************************************************************** 483 * 484 * FUNCTION: DtCompileApmt 485 * 486 * PARAMETERS: List - Current field list pointer 487 * 488 * RETURN: Status 489 * 490 * DESCRIPTION: Compile APMT. 491 * 492 *****************************************************************************/ 493 494 ACPI_STATUS 495 DtCompileApmt ( 496 void **List) 497 { 498 ACPI_STATUS Status; 499 ACPI_TABLE_HEADER *Header; 500 ACPI_APMT_NODE *ApmtNode; 501 ACPI_APMT_NODE *PeerApmtNode; 502 DT_SUBTABLE *Subtable; 503 DT_SUBTABLE *PeerSubtable; 504 DT_SUBTABLE *ParentTable; 505 DT_FIELD **PFieldList = (DT_FIELD**)List; 506 DT_FIELD *SubtableStart; 507 UINT32 CurLength; 508 char MsgBuffer[64] = ""; 509 510 ParentTable = DtPeekSubtable(); 511 512 Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer); 513 514 CurLength = sizeof(ACPI_TABLE_HEADER); 515 516 /* Walk the parse tree */ 517 518 while (*PFieldList) 519 { 520 /* APMT Node Subtable */ 521 522 SubtableStart = *PFieldList; 523 524 Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable); 525 526 if (ACPI_FAILURE(Status)) 527 { 528 return (Status); 529 } 530 531 ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer); 532 533 if (ApmtNode->Length != sizeof(ACPI_APMT_NODE)) 534 { 535 DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT"); 536 return (AE_ERROR); 537 } 538 539 if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT) 540 { 541 snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type); 542 DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer); 543 return (AE_ERROR); 544 } 545 546 PeerSubtable = DtGetNextSubtable(ParentTable, NULL); 547 548 /* Validate the node id needs to be unique. */ 549 while(PeerSubtable) 550 { 551 PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer); 552 if (PeerApmtNode->Id == ApmtNode->Id) 553 { 554 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id); 555 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer); 556 return (AE_ERROR); 557 } 558 559 PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable); 560 } 561 562 CurLength += ApmtNode->Length; 563 564 DtInsertSubtable(ParentTable, Subtable); 565 } 566 567 if (Header->Length != CurLength) 568 { 569 snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)", 570 Header->Length, CurLength); 571 DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer); 572 return (AE_ERROR); 573 } 574 575 return (AE_OK); 576 } 577 578 /****************************************************************************** 579 * 580 * FUNCTION: DtCompileAsf 581 * 582 * PARAMETERS: List - Current field list pointer 583 * 584 * RETURN: Status 585 * 586 * DESCRIPTION: Compile ASF!. 587 * 588 *****************************************************************************/ 589 590 ACPI_STATUS 591 DtCompileAsf ( 592 void **List) 593 { 594 ACPI_ASF_INFO *AsfTable; 595 DT_SUBTABLE *Subtable; 596 DT_SUBTABLE *ParentTable; 597 ACPI_DMTABLE_INFO *InfoTable; 598 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 599 UINT32 DataCount = 0; 600 ACPI_STATUS Status; 601 UINT32 i; 602 DT_FIELD **PFieldList = (DT_FIELD **) List; 603 DT_FIELD *SubtableStart; 604 605 606 while (*PFieldList) 607 { 608 SubtableStart = *PFieldList; 609 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 610 &Subtable); 611 if (ACPI_FAILURE (Status)) 612 { 613 return (Status); 614 } 615 616 ParentTable = DtPeekSubtable (); 617 DtInsertSubtable (ParentTable, Subtable); 618 DtPushSubtable (Subtable); 619 620 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 621 622 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 623 { 624 case ACPI_ASF_TYPE_INFO: 625 626 InfoTable = AcpiDmTableInfoAsf0; 627 break; 628 629 case ACPI_ASF_TYPE_ALERT: 630 631 InfoTable = AcpiDmTableInfoAsf1; 632 break; 633 634 case ACPI_ASF_TYPE_CONTROL: 635 636 InfoTable = AcpiDmTableInfoAsf2; 637 break; 638 639 case ACPI_ASF_TYPE_BOOT: 640 641 InfoTable = AcpiDmTableInfoAsf3; 642 break; 643 644 case ACPI_ASF_TYPE_ADDRESS: 645 646 InfoTable = AcpiDmTableInfoAsf4; 647 break; 648 649 default: 650 651 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 652 return (AE_ERROR); 653 } 654 655 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 656 if (ACPI_FAILURE (Status)) 657 { 658 return (Status); 659 } 660 661 ParentTable = DtPeekSubtable (); 662 DtInsertSubtable (ParentTable, Subtable); 663 664 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 665 { 666 case ACPI_ASF_TYPE_INFO: 667 668 DataInfoTable = NULL; 669 break; 670 671 case ACPI_ASF_TYPE_ALERT: 672 673 DataInfoTable = AcpiDmTableInfoAsf1a; 674 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 675 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 676 sizeof (ACPI_ASF_HEADER)))->Alerts; 677 break; 678 679 case ACPI_ASF_TYPE_CONTROL: 680 681 DataInfoTable = AcpiDmTableInfoAsf2a; 682 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 683 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 684 sizeof (ACPI_ASF_HEADER)))->Controls; 685 break; 686 687 case ACPI_ASF_TYPE_BOOT: 688 689 DataInfoTable = NULL; 690 break; 691 692 case ACPI_ASF_TYPE_ADDRESS: 693 694 DataInfoTable = TableInfoAsfAddress; 695 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 696 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 697 sizeof (ACPI_ASF_HEADER)))->Devices; 698 break; 699 700 default: 701 702 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 703 return (AE_ERROR); 704 } 705 706 if (DataInfoTable) 707 { 708 switch (AsfTable->Header.Type & 0x7F) 709 { 710 case ACPI_ASF_TYPE_ADDRESS: 711 712 while (DataCount > 0) 713 { 714 Status = DtCompileTable (PFieldList, DataInfoTable, 715 &Subtable); 716 if (ACPI_FAILURE (Status)) 717 { 718 return (Status); 719 } 720 721 DtInsertSubtable (ParentTable, Subtable); 722 DataCount = DataCount - Subtable->Length; 723 } 724 break; 725 726 default: 727 728 for (i = 0; i < DataCount; i++) 729 { 730 Status = DtCompileTable (PFieldList, DataInfoTable, 731 &Subtable); 732 if (ACPI_FAILURE (Status)) 733 { 734 return (Status); 735 } 736 737 DtInsertSubtable (ParentTable, Subtable); 738 } 739 break; 740 } 741 } 742 743 DtPopSubtable (); 744 } 745 746 return (AE_OK); 747 } 748 749 /****************************************************************************** 750 * 751 * FUNCTION: DtCompileAspt 752 * 753 * PARAMETERS: List - Current field list pointer 754 * 755 * RETURN: Status 756 * 757 * DESCRIPTION: Compile ASPT. 758 * 759 *****************************************************************************/ 760 761 ACPI_STATUS 762 DtCompileAspt ( 763 void **List) 764 { 765 ACPI_ASPT_HEADER *AsptTable; 766 DT_SUBTABLE *Subtable; 767 DT_SUBTABLE *ParentTable; 768 ACPI_DMTABLE_INFO *InfoTable; 769 ACPI_STATUS Status; 770 DT_FIELD **PFieldList = (DT_FIELD **) List; 771 DT_FIELD *SubtableStart; 772 773 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAspt, &Subtable); 774 if (ACPI_FAILURE (Status)) 775 { 776 return (Status); 777 } 778 779 ParentTable = DtPeekSubtable (); 780 DtInsertSubtable (ParentTable, Subtable); 781 782 while (*PFieldList) 783 { 784 SubtableStart = *PFieldList; 785 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsptHdr, 786 &Subtable); 787 if (ACPI_FAILURE (Status)) 788 { 789 return (Status); 790 } 791 792 ParentTable = DtPeekSubtable (); 793 DtInsertSubtable (ParentTable, Subtable); 794 DtPushSubtable (Subtable); 795 796 AsptTable = ACPI_CAST_PTR (ACPI_ASPT_HEADER, Subtable->Buffer); 797 798 switch (AsptTable->Type) /* Mask off top bit */ 799 { 800 case ACPI_ASPT_TYPE_GLOBAL_REGS: 801 802 InfoTable = AcpiDmTableInfoAspt0; 803 break; 804 805 case ACPI_ASPT_TYPE_SEV_MBOX_REGS: 806 807 InfoTable = AcpiDmTableInfoAspt1; 808 break; 809 810 case ACPI_ASPT_TYPE_ACPI_MBOX_REGS: 811 812 InfoTable = AcpiDmTableInfoAspt2; 813 break; 814 815 default: 816 817 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASPT"); 818 return (AE_ERROR); 819 } 820 821 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 822 if (ACPI_FAILURE (Status)) 823 { 824 return (Status); 825 } 826 ParentTable = DtPeekSubtable (); 827 DtInsertSubtable (ParentTable, Subtable); 828 DtPopSubtable (); 829 } 830 831 return (AE_OK); 832 } 833 834 835 /****************************************************************************** 836 * 837 * FUNCTION: DtCompileCdat 838 * 839 * PARAMETERS: List - Current field list pointer 840 * 841 * RETURN: Status 842 * 843 * DESCRIPTION: Compile CDAT. 844 * 845 *****************************************************************************/ 846 847 ACPI_STATUS 848 DtCompileCdat ( 849 void **List) 850 { 851 ACPI_STATUS Status = AE_OK; 852 DT_SUBTABLE *Subtable; 853 DT_SUBTABLE *ParentTable; 854 DT_FIELD **PFieldList = (DT_FIELD **) List; 855 ACPI_CDAT_HEADER *CdatHeader; 856 ACPI_DMTABLE_INFO *InfoTable = NULL; 857 DT_FIELD *SubtableStart; 858 859 860 /* Walk the parse tree. 861 * 862 * Note: Main table consists of only the CDAT table header 863 * (This is not the standard ACPI table header, however)-- 864 * Followed by some number of subtables. 865 */ 866 while (*PFieldList) 867 { 868 SubtableStart = *PFieldList; 869 870 /* Compile the expected CDAT Subtable header */ 871 872 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader, 873 &Subtable); 874 if (ACPI_FAILURE (Status)) 875 { 876 return (Status); 877 } 878 879 ParentTable = DtPeekSubtable (); 880 DtInsertSubtable (ParentTable, Subtable); 881 DtPushSubtable (Subtable); 882 883 CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer); 884 885 /* Decode the subtable by type */ 886 887 switch (CdatHeader->Type) 888 { 889 case ACPI_CDAT_TYPE_DSMAS: 890 InfoTable = AcpiDmTableInfoCdat0; 891 break; 892 893 case ACPI_CDAT_TYPE_DSLBIS: 894 InfoTable = AcpiDmTableInfoCdat1; 895 break; 896 897 case ACPI_CDAT_TYPE_DSMSCIS: 898 InfoTable = AcpiDmTableInfoCdat2; 899 break; 900 901 case ACPI_CDAT_TYPE_DSIS: 902 InfoTable = AcpiDmTableInfoCdat3; 903 break; 904 905 case ACPI_CDAT_TYPE_DSEMTS: 906 InfoTable = AcpiDmTableInfoCdat4; 907 break; 908 909 case ACPI_CDAT_TYPE_SSLBIS: 910 InfoTable = AcpiDmTableInfoCdat5; 911 break; 912 913 default: 914 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT"); 915 } 916 917 /* Compile the CDAT subtable */ 918 919 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 920 if (ACPI_FAILURE (Status)) 921 { 922 return (Status); 923 } 924 925 ParentTable = DtPeekSubtable (); 926 DtInsertSubtable (ParentTable, Subtable); 927 928 switch (CdatHeader->Type) 929 { 930 /* Multiple entries supported for this type */ 931 932 case ACPI_CDAT_TYPE_SSLBIS: 933 934 /* 935 * Check for multiple SSLBEs 936 */ 937 while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID")) 938 { 939 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable); 940 if (ACPI_FAILURE (Status)) 941 { 942 return (Status); 943 } 944 ParentTable = DtPeekSubtable (); 945 DtInsertSubtable (ParentTable, Subtable); 946 } 947 break; 948 949 default: 950 break; 951 } 952 953 /* Pop off the CDAT Subtable header subtree */ 954 955 DtPopSubtable (); 956 } 957 958 return (AE_OK); 959 } 960 961 962 /****************************************************************************** 963 * 964 * FUNCTION: DtCompileCedt 965 * 966 * PARAMETERS: List - Current field list pointer 967 * 968 * RETURN: Status 969 * 970 * DESCRIPTION: Compile CEDT. 971 * 972 *****************************************************************************/ 973 974 ACPI_STATUS 975 DtCompileCedt ( 976 void **List) 977 { 978 ACPI_STATUS Status; 979 DT_SUBTABLE *Subtable; 980 DT_SUBTABLE *ParentTable; 981 DT_FIELD **PFieldList = (DT_FIELD **) List; 982 ACPI_CEDT_HEADER *CedtHeader; 983 DT_FIELD *SubtableStart; 984 985 986 /* Walk the parse tree */ 987 988 while (*PFieldList) 989 { 990 /* if CFMWS and has more than one target, then set to zero later */ 991 992 int InsertFlag = 1; 993 SubtableStart = *PFieldList; 994 995 /* CEDT Header */ 996 997 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr, 998 &Subtable); 999 if (ACPI_FAILURE (Status)) 1000 { 1001 return (Status); 1002 } 1003 1004 ParentTable = DtPeekSubtable (); 1005 DtInsertSubtable (ParentTable, Subtable); 1006 DtPushSubtable (Subtable); 1007 1008 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer); 1009 1010 switch (CedtHeader->Type) 1011 { 1012 case ACPI_CEDT_TYPE_CHBS: 1013 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable); 1014 if (ACPI_FAILURE (Status)) 1015 { 1016 return (Status); 1017 } 1018 break; 1019 case ACPI_CEDT_TYPE_CFMWS: { 1020 unsigned char *dump; 1021 unsigned int idx, offset, max = 0; 1022 1023 /* Compile table with first "Interleave target" */ 1024 1025 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable); 1026 if (ACPI_FAILURE (Status)) 1027 { 1028 return (Status); 1029 } 1030 1031 /* Look in buffer for the number of targets */ 1032 offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays); 1033 dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt1 */ 1034 max = 0x01 << dump[offset]; /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */ 1035 if (max > 8) max=1; /* Error in encoding Interleaving Ways. */ 1036 if (max == 1) /* if only one target, then break here. */ 1037 break; /* break if only one target. */ 1038 1039 /* We need to add more interleave targets, so write the current Subtable. */ 1040 1041 ParentTable = DtPeekSubtable (); 1042 DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt1 table so we can put in */ 1043 DtPushSubtable (Subtable); /* the targets > the first. */ 1044 1045 /* Now, find out all interleave targets beyond the first. */ 1046 1047 for (idx = 1; idx < max; idx++) { 1048 ParentTable = DtPeekSubtable (); 1049 1050 if (*PFieldList) 1051 { 1052 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable); 1053 if (ACPI_FAILURE (Status)) 1054 { 1055 return (Status); 1056 } 1057 if (Subtable) 1058 { 1059 DtInsertSubtable (ParentTable, Subtable); /* got a target, so insert table. */ 1060 InsertFlag = 0; 1061 } 1062 } 1063 } 1064 1065 DtPopSubtable (); 1066 ParentTable = DtPeekSubtable (); 1067 break; 1068 } 1069 case ACPI_CEDT_TYPE_CXIMS: { 1070 unsigned char *dump; 1071 unsigned int idx, offset, max = 0; 1072 1073 /* Compile table with first "Xor map" */ 1074 1075 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2, &Subtable); 1076 if (ACPI_FAILURE (Status)) 1077 { 1078 return (Status); 1079 } 1080 1081 /* Look in buffer for the number of Xor maps */ 1082 offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CXIMS, NrXormaps); 1083 dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt2 */ 1084 max = dump[offset]; 1085 1086 /* We need to add more XOR maps, so write the current Subtable. */ 1087 1088 ParentTable = DtPeekSubtable (); 1089 DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt2 table so we can put in */ 1090 DtPushSubtable (Subtable); 1091 1092 /* Now, find out all Xor maps beyond the first. */ 1093 1094 for (idx = 1; idx < max; idx++) { 1095 ParentTable = DtPeekSubtable (); 1096 1097 if (*PFieldList) 1098 { 1099 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2_te, &Subtable); 1100 if (ACPI_FAILURE (Status)) 1101 { 1102 return (Status); 1103 } 1104 if (Subtable) 1105 { 1106 DtInsertSubtable (ParentTable, Subtable); /* got an Xor map, so insert table. */ 1107 InsertFlag = 0; 1108 } 1109 } 1110 } 1111 1112 DtPopSubtable (); 1113 ParentTable = DtPeekSubtable (); 1114 break; 1115 } 1116 1117 default: 1118 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT"); 1119 return (AE_ERROR); 1120 } 1121 1122 ParentTable = DtPeekSubtable (); 1123 if (InsertFlag == 1) { 1124 DtInsertSubtable (ParentTable, Subtable); 1125 } 1126 DtPopSubtable (); 1127 } 1128 1129 return (AE_OK); 1130 } 1131 1132 1133 /****************************************************************************** 1134 * 1135 * FUNCTION: DtCompileCpep 1136 * 1137 * PARAMETERS: List - Current field list pointer 1138 * 1139 * RETURN: Status 1140 * 1141 * DESCRIPTION: Compile CPEP. 1142 * 1143 *****************************************************************************/ 1144 1145 ACPI_STATUS 1146 DtCompileCpep ( 1147 void **List) 1148 { 1149 ACPI_STATUS Status; 1150 1151 1152 Status = DtCompileTwoSubtables (List, 1153 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 1154 return (Status); 1155 } 1156 1157 1158 /****************************************************************************** 1159 * 1160 * FUNCTION: DtCompileCsrt 1161 * 1162 * PARAMETERS: List - Current field list pointer 1163 * 1164 * RETURN: Status 1165 * 1166 * DESCRIPTION: Compile CSRT. 1167 * 1168 *****************************************************************************/ 1169 1170 ACPI_STATUS 1171 DtCompileCsrt ( 1172 void **List) 1173 { 1174 ACPI_STATUS Status = AE_OK; 1175 DT_SUBTABLE *Subtable; 1176 DT_SUBTABLE *ParentTable; 1177 DT_FIELD **PFieldList = (DT_FIELD **) List; 1178 UINT32 DescriptorCount; 1179 UINT32 GroupLength; 1180 1181 1182 /* Subtables (Resource Groups) */ 1183 1184 ParentTable = DtPeekSubtable (); 1185 while (*PFieldList) 1186 { 1187 /* Resource group subtable */ 1188 1189 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 1190 &Subtable); 1191 if (ACPI_FAILURE (Status)) 1192 { 1193 return (Status); 1194 } 1195 1196 /* Compute the number of resource descriptors */ 1197 1198 GroupLength = 1199 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 1200 Subtable->Buffer))->Length - 1201 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 1202 Subtable->Buffer))->SharedInfoLength - 1203 sizeof (ACPI_CSRT_GROUP); 1204 1205 DescriptorCount = (GroupLength / 1206 sizeof (ACPI_CSRT_DESCRIPTOR)); 1207 1208 DtInsertSubtable (ParentTable, Subtable); 1209 DtPushSubtable (Subtable); 1210 ParentTable = DtPeekSubtable (); 1211 1212 /* Shared info subtable (One per resource group) */ 1213 1214 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 1215 &Subtable); 1216 if (ACPI_FAILURE (Status)) 1217 { 1218 return (Status); 1219 } 1220 1221 DtInsertSubtable (ParentTable, Subtable); 1222 1223 /* Sub-Subtables (Resource Descriptors) */ 1224 1225 while (*PFieldList && DescriptorCount) 1226 { 1227 1228 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 1229 &Subtable); 1230 if (ACPI_FAILURE (Status)) 1231 { 1232 return (Status); 1233 } 1234 1235 DtInsertSubtable (ParentTable, Subtable); 1236 1237 DtPushSubtable (Subtable); 1238 ParentTable = DtPeekSubtable (); 1239 if (*PFieldList) 1240 { 1241 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 1242 &Subtable); 1243 if (ACPI_FAILURE (Status)) 1244 { 1245 return (Status); 1246 } 1247 if (Subtable) 1248 { 1249 DtInsertSubtable (ParentTable, Subtable); 1250 } 1251 } 1252 1253 DtPopSubtable (); 1254 ParentTable = DtPeekSubtable (); 1255 DescriptorCount--; 1256 } 1257 1258 DtPopSubtable (); 1259 ParentTable = DtPeekSubtable (); 1260 } 1261 1262 return (Status); 1263 } 1264 1265 1266 /****************************************************************************** 1267 * 1268 * FUNCTION: DtCompileDbg2 1269 * 1270 * PARAMETERS: List - Current field list pointer 1271 * 1272 * RETURN: Status 1273 * 1274 * DESCRIPTION: Compile DBG2. 1275 * 1276 *****************************************************************************/ 1277 1278 ACPI_STATUS 1279 DtCompileDbg2 ( 1280 void **List) 1281 { 1282 ACPI_STATUS Status; 1283 DT_SUBTABLE *Subtable; 1284 DT_SUBTABLE *ParentTable; 1285 DT_FIELD **PFieldList = (DT_FIELD **) List; 1286 UINT32 SubtableCount; 1287 ACPI_DBG2_HEADER *Dbg2Header; 1288 ACPI_DBG2_DEVICE *DeviceInfo; 1289 UINT16 CurrentOffset; 1290 UINT32 i; 1291 1292 1293 /* Main table */ 1294 1295 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable); 1296 if (ACPI_FAILURE (Status)) 1297 { 1298 return (Status); 1299 } 1300 1301 ParentTable = DtPeekSubtable (); 1302 DtInsertSubtable (ParentTable, Subtable); 1303 1304 /* Main table fields */ 1305 1306 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 1307 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 1308 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 1309 1310 SubtableCount = Dbg2Header->InfoCount; 1311 DtPushSubtable (Subtable); 1312 1313 /* Process all Device Information subtables (Count = InfoCount) */ 1314 1315 while (*PFieldList && SubtableCount) 1316 { 1317 /* Subtable: Debug Device Information */ 1318 1319 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 1320 &Subtable); 1321 if (ACPI_FAILURE (Status)) 1322 { 1323 return (Status); 1324 } 1325 1326 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 1327 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 1328 1329 ParentTable = DtPeekSubtable (); 1330 DtInsertSubtable (ParentTable, Subtable); 1331 DtPushSubtable (Subtable); 1332 1333 ParentTable = DtPeekSubtable (); 1334 1335 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 1336 1337 DeviceInfo->BaseAddressOffset = CurrentOffset; 1338 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 1339 { 1340 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 1341 &Subtable); 1342 if (ACPI_FAILURE (Status)) 1343 { 1344 return (Status); 1345 } 1346 1347 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 1348 DtInsertSubtable (ParentTable, Subtable); 1349 } 1350 1351 /* AddressSize array (Required, size = RegisterCount) */ 1352 1353 DeviceInfo->AddressSizeOffset = CurrentOffset; 1354 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 1355 { 1356 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 1357 &Subtable); 1358 if (ACPI_FAILURE (Status)) 1359 { 1360 return (Status); 1361 } 1362 1363 CurrentOffset += (UINT16) sizeof (UINT32); 1364 DtInsertSubtable (ParentTable, Subtable); 1365 } 1366 1367 /* NamespaceString device identifier (Required, size = NamePathLength) */ 1368 1369 DeviceInfo->NamepathOffset = CurrentOffset; 1370 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 1371 &Subtable); 1372 if (ACPI_FAILURE (Status)) 1373 { 1374 return (Status); 1375 } 1376 1377 /* Update the device info header */ 1378 1379 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 1380 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 1381 DtInsertSubtable (ParentTable, Subtable); 1382 1383 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 1384 1385 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 1386 &Subtable); 1387 if (Status == AE_END_OF_TABLE) 1388 { 1389 /* optional field was not found and we're at the end of the file */ 1390 1391 goto subtableDone; 1392 } 1393 else if (ACPI_FAILURE (Status)) 1394 { 1395 return (Status); 1396 } 1397 1398 /* Update the device info header (zeros if no OEM data present) */ 1399 1400 DeviceInfo->OemDataOffset = 0; 1401 DeviceInfo->OemDataLength = 0; 1402 1403 /* Optional subtable (OemData) */ 1404 1405 if (Subtable && Subtable->Length) 1406 { 1407 DeviceInfo->OemDataOffset = CurrentOffset; 1408 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 1409 1410 DtInsertSubtable (ParentTable, Subtable); 1411 } 1412 subtableDone: 1413 SubtableCount--; 1414 DtPopSubtable (); /* Get next Device Information subtable */ 1415 } 1416 1417 DtPopSubtable (); 1418 return (AE_OK); 1419 } 1420 1421 1422 /****************************************************************************** 1423 * 1424 * FUNCTION: DtCompileDmar 1425 * 1426 * PARAMETERS: List - Current field list pointer 1427 * 1428 * RETURN: Status 1429 * 1430 * DESCRIPTION: Compile DMAR. 1431 * 1432 *****************************************************************************/ 1433 1434 ACPI_STATUS 1435 DtCompileDmar ( 1436 void **List) 1437 { 1438 ACPI_STATUS Status; 1439 DT_SUBTABLE *Subtable; 1440 DT_SUBTABLE *ParentTable; 1441 DT_FIELD **PFieldList = (DT_FIELD **) List; 1442 DT_FIELD *SubtableStart; 1443 ACPI_DMTABLE_INFO *InfoTable; 1444 ACPI_DMAR_HEADER *DmarHeader; 1445 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 1446 UINT32 DeviceScopeLength; 1447 UINT32 PciPathLength; 1448 1449 1450 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable); 1451 if (ACPI_FAILURE (Status)) 1452 { 1453 return (Status); 1454 } 1455 1456 ParentTable = DtPeekSubtable (); 1457 DtInsertSubtable (ParentTable, Subtable); 1458 DtPushSubtable (Subtable); 1459 1460 while (*PFieldList) 1461 { 1462 /* DMAR Header */ 1463 1464 SubtableStart = *PFieldList; 1465 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 1466 &Subtable); 1467 if (ACPI_FAILURE (Status)) 1468 { 1469 return (Status); 1470 } 1471 1472 ParentTable = DtPeekSubtable (); 1473 DtInsertSubtable (ParentTable, Subtable); 1474 DtPushSubtable (Subtable); 1475 1476 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 1477 1478 switch (DmarHeader->Type) 1479 { 1480 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 1481 1482 InfoTable = AcpiDmTableInfoDmar0; 1483 break; 1484 1485 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 1486 1487 InfoTable = AcpiDmTableInfoDmar1; 1488 break; 1489 1490 case ACPI_DMAR_TYPE_ROOT_ATS: 1491 1492 InfoTable = AcpiDmTableInfoDmar2; 1493 break; 1494 1495 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 1496 1497 InfoTable = AcpiDmTableInfoDmar3; 1498 break; 1499 1500 case ACPI_DMAR_TYPE_NAMESPACE: 1501 1502 InfoTable = AcpiDmTableInfoDmar4; 1503 break; 1504 1505 case ACPI_DMAR_TYPE_SATC: 1506 1507 InfoTable = AcpiDmTableInfoDmar5; 1508 break; 1509 1510 case ACPI_DMAR_TYPE_SIDP: 1511 1512 InfoTable = AcpiDmTableInfoDmar6; 1513 break; 1514 1515 default: 1516 1517 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 1518 return (AE_ERROR); 1519 } 1520 1521 /* DMAR Subtable */ 1522 1523 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1524 if (ACPI_FAILURE (Status)) 1525 { 1526 return (Status); 1527 } 1528 1529 ParentTable = DtPeekSubtable (); 1530 DtInsertSubtable (ParentTable, Subtable); 1531 1532 /* 1533 * Optional Device Scope subtables 1534 */ 1535 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 1536 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 1537 { 1538 /* These types do not support device scopes */ 1539 1540 DtPopSubtable (); 1541 continue; 1542 } 1543 1544 DtPushSubtable (Subtable); 1545 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 1546 ParentTable->Length; 1547 while (DeviceScopeLength) 1548 { 1549 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 1550 &Subtable); 1551 if (Status == AE_NOT_FOUND) 1552 { 1553 break; 1554 } 1555 1556 ParentTable = DtPeekSubtable (); 1557 DtInsertSubtable (ParentTable, Subtable); 1558 DtPushSubtable (Subtable); 1559 1560 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 1561 1562 /* Optional PCI Paths */ 1563 1564 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 1565 while (PciPathLength) 1566 { 1567 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 1568 &Subtable); 1569 if (Status == AE_NOT_FOUND) 1570 { 1571 DtPopSubtable (); 1572 break; 1573 } 1574 1575 ParentTable = DtPeekSubtable (); 1576 DtInsertSubtable (ParentTable, Subtable); 1577 PciPathLength -= Subtable->Length; 1578 } 1579 1580 DtPopSubtable (); 1581 DeviceScopeLength -= DmarDeviceScope->Length; 1582 } 1583 1584 DtPopSubtable (); 1585 DtPopSubtable (); 1586 } 1587 1588 return (AE_OK); 1589 } 1590 1591 1592 /****************************************************************************** 1593 * 1594 * FUNCTION: DtCompileDrtm 1595 * 1596 * PARAMETERS: List - Current field list pointer 1597 * 1598 * RETURN: Status 1599 * 1600 * DESCRIPTION: Compile DRTM. 1601 * 1602 *****************************************************************************/ 1603 1604 ACPI_STATUS 1605 DtCompileDrtm ( 1606 void **List) 1607 { 1608 ACPI_STATUS Status; 1609 DT_SUBTABLE *Subtable; 1610 DT_SUBTABLE *ParentTable; 1611 DT_FIELD **PFieldList = (DT_FIELD **) List; 1612 UINT32 Count; 1613 /* ACPI_TABLE_DRTM *Drtm; */ 1614 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 1615 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 1616 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 1617 1618 1619 ParentTable = DtPeekSubtable (); 1620 1621 /* Compile DRTM header */ 1622 1623 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 1624 &Subtable); 1625 if (ACPI_FAILURE (Status)) 1626 { 1627 return (Status); 1628 } 1629 DtInsertSubtable (ParentTable, Subtable); 1630 1631 /* 1632 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1633 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 1634 */ 1635 #if 0 1636 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 1637 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1638 #endif 1639 /* Compile VTL */ 1640 1641 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 1642 &Subtable); 1643 if (ACPI_FAILURE (Status)) 1644 { 1645 return (Status); 1646 } 1647 1648 DtInsertSubtable (ParentTable, Subtable); 1649 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 1650 1651 DtPushSubtable (Subtable); 1652 ParentTable = DtPeekSubtable (); 1653 Count = 0; 1654 1655 while (*PFieldList) 1656 { 1657 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 1658 &Subtable); 1659 if (ACPI_FAILURE (Status)) 1660 { 1661 return (Status); 1662 } 1663 if (!Subtable) 1664 { 1665 break; 1666 } 1667 DtInsertSubtable (ParentTable, Subtable); 1668 Count++; 1669 } 1670 1671 DrtmVtl->ValidatedTableCount = Count; 1672 DtPopSubtable (); 1673 ParentTable = DtPeekSubtable (); 1674 1675 /* Compile RL */ 1676 1677 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 1678 &Subtable); 1679 if (ACPI_FAILURE (Status)) 1680 { 1681 return (Status); 1682 } 1683 1684 DtInsertSubtable (ParentTable, Subtable); 1685 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 1686 1687 DtPushSubtable (Subtable); 1688 ParentTable = DtPeekSubtable (); 1689 Count = 0; 1690 1691 while (*PFieldList) 1692 { 1693 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 1694 &Subtable); 1695 if (ACPI_FAILURE (Status)) 1696 { 1697 return (Status); 1698 } 1699 1700 if (!Subtable) 1701 { 1702 break; 1703 } 1704 1705 DtInsertSubtable (ParentTable, Subtable); 1706 Count++; 1707 } 1708 1709 DrtmRl->ResourceCount = Count; 1710 DtPopSubtable (); 1711 ParentTable = DtPeekSubtable (); 1712 1713 /* Compile DPS */ 1714 1715 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 1716 &Subtable); 1717 if (ACPI_FAILURE (Status)) 1718 { 1719 return (Status); 1720 } 1721 DtInsertSubtable (ParentTable, Subtable); 1722 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 1723 1724 1725 return (AE_OK); 1726 } 1727 1728 1729 /****************************************************************************** 1730 * 1731 * FUNCTION: DtCompileEinj 1732 * 1733 * PARAMETERS: List - Current field list pointer 1734 * 1735 * RETURN: Status 1736 * 1737 * DESCRIPTION: Compile EINJ. 1738 * 1739 *****************************************************************************/ 1740 1741 ACPI_STATUS 1742 DtCompileEinj ( 1743 void **List) 1744 { 1745 ACPI_STATUS Status; 1746 1747 1748 Status = DtCompileTwoSubtables (List, 1749 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 1750 return (Status); 1751 } 1752 1753 1754 /****************************************************************************** 1755 * 1756 * FUNCTION: DtCompileErdt 1757 * 1758 * PARAMETERS: List - Current field list pointer 1759 * 1760 * RETURN: Status 1761 * 1762 * DESCRIPTION: Compile ERST. Complex table with subtables and subsubtables. 1763 * 1764 *****************************************************************************/ 1765 1766 ACPI_STATUS 1767 DtCompileErdt ( 1768 void **List) 1769 { 1770 ACPI_STATUS Status; 1771 DT_SUBTABLE *Subtable, *RmddSubtable = NULL, *Subsubtable; 1772 DT_SUBTABLE *ParentTable; 1773 DT_FIELD **PFieldList = (DT_FIELD **) List; 1774 DT_FIELD *SubtableStart; 1775 ACPI_SUBTBL_HDR_16 *ErdtHeader; 1776 ACPI_DMTABLE_INFO *InfoTable; 1777 ACPI_ERDT_MMRC *Mmrc; 1778 ACPI_ERDT_IBRD *Ibrd; 1779 UINT32 NumEntries; 1780 BOOLEAN SeenRmdd = FALSE; 1781 BOOLEAN SeenSubtable = FALSE; 1782 1783 Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdt, 1784 &Subtable); 1785 if (ACPI_FAILURE (Status)) 1786 { 1787 return (Status); 1788 } 1789 1790 ParentTable = DtPeekSubtable (); 1791 DtInsertSubtable (ParentTable, Subtable); 1792 1793 while (*PFieldList) 1794 { 1795 SubtableStart = *PFieldList; 1796 Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdtHdr, 1797 &Subtable); 1798 if (ACPI_FAILURE (Status)) 1799 { 1800 return (Status); 1801 } 1802 1803 ErdtHeader = ACPI_CAST_PTR (ACPI_SUBTBL_HDR_16, Subtable->Buffer); 1804 1805 /* RMDD tables at top level. All others are subtables of preceeding RMDD */ 1806 if (ErdtHeader->Type == ACPI_ERDT_TYPE_RMDD) 1807 { 1808 if (SeenRmdd && SeenSubtable) 1809 DtPopSubtable (); 1810 SeenRmdd = TRUE; 1811 SeenSubtable = FALSE; 1812 RmddSubtable = Subtable; 1813 } 1814 else 1815 { 1816 if (!SeenSubtable) 1817 { 1818 DtPushSubtable (RmddSubtable); 1819 SeenSubtable = TRUE; 1820 } 1821 } 1822 1823 ParentTable = DtPeekSubtable (); 1824 DtInsertSubtable (ParentTable, Subtable); 1825 DtPushSubtable (Subtable); 1826 1827 switch (ErdtHeader->Type) 1828 { 1829 case ACPI_ERDT_TYPE_RMDD: 1830 InfoTable = AcpiDmTableInfoErdtRmdd; 1831 break; 1832 1833 case ACPI_ERDT_TYPE_CACD: 1834 InfoTable = AcpiDmTableInfoErdtCacd; 1835 break; 1836 1837 case ACPI_ERDT_TYPE_DACD: 1838 InfoTable = AcpiDmTableInfoErdtDacd; 1839 break; 1840 1841 case ACPI_ERDT_TYPE_CMRC: 1842 InfoTable = AcpiDmTableInfoErdtCmrc; 1843 break; 1844 1845 case ACPI_ERDT_TYPE_MMRC: 1846 InfoTable = AcpiDmTableInfoErdtMmrc; 1847 break; 1848 1849 case ACPI_ERDT_TYPE_MARC: 1850 InfoTable = AcpiDmTableInfoErdtMarc; 1851 break; 1852 1853 case ACPI_ERDT_TYPE_CARC: 1854 InfoTable = AcpiDmTableInfoErdtCarc; 1855 break; 1856 1857 case ACPI_ERDT_TYPE_CMRD: 1858 InfoTable = AcpiDmTableInfoErdtCmrd; 1859 break; 1860 1861 case ACPI_ERDT_TYPE_IBRD: 1862 InfoTable = AcpiDmTableInfoErdtIbrd; 1863 break; 1864 1865 case ACPI_ERDT_TYPE_IBAD: 1866 InfoTable = AcpiDmTableInfoErdtIbad; 1867 break; 1868 1869 case ACPI_ERDT_TYPE_CARD: 1870 InfoTable = AcpiDmTableInfoErdtCard; 1871 break; 1872 1873 default: 1874 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ERDT"); 1875 return (AE_ERROR); 1876 } 1877 1878 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1879 if (ACPI_FAILURE (Status)) 1880 { 1881 return (Status); 1882 } 1883 1884 ParentTable = DtPeekSubtable (); 1885 DtInsertSubtable (ParentTable, Subtable); 1886 1887 /* Some subtable types end with flex arrays */ 1888 1889 switch (ErdtHeader->Type) 1890 { 1891 case ACPI_ERDT_TYPE_CACD: 1892 while (*PFieldList) 1893 { 1894 Status = DtCompileTable (PFieldList, 1895 AcpiDmTableInfoErdtCacdX2apic, &Subtable); 1896 if (ACPI_FAILURE (Status)) 1897 { 1898 return (Status); 1899 } 1900 if (!Subtable) 1901 { 1902 break; 1903 } 1904 1905 ParentTable = DtPeekSubtable (); 1906 DtInsertSubtable (ParentTable, Subtable); 1907 } 1908 break; 1909 1910 case ACPI_ERDT_TYPE_DACD: 1911 while (*PFieldList) 1912 { 1913 Status = DtCompileTable (PFieldList, 1914 AcpiDmTableInfoErdtDacdScope, &Subtable); 1915 if (ACPI_FAILURE (Status)) 1916 { 1917 return (Status); 1918 } 1919 if (!Subtable) 1920 { 1921 break; 1922 } 1923 1924 DtPushSubtable (Subtable); 1925 while (*PFieldList) 1926 { 1927 Status = DtCompileTable (PFieldList, 1928 AcpiDmTableInfoErdtDacdPath, &Subsubtable); 1929 if (ACPI_FAILURE (Status)) 1930 { 1931 return (Status); 1932 } 1933 if (!Subsubtable) 1934 { 1935 break; 1936 } 1937 1938 ParentTable = DtPeekSubtable (); 1939 DtInsertSubtable (ParentTable, Subsubtable); 1940 } 1941 DtPopSubtable (); 1942 1943 ParentTable = DtPeekSubtable (); 1944 DtInsertSubtable (ParentTable, Subtable); 1945 } 1946 break; 1947 1948 case ACPI_ERDT_TYPE_MMRC: 1949 Mmrc = ACPI_SUB_PTR (ACPI_ERDT_MMRC, Subtable->Buffer, 1950 sizeof(ACPI_SUBTBL_HDR_16)); 1951 NumEntries = 0; 1952 while (*PFieldList) 1953 { 1954 Status = DtCompileTable (PFieldList, 1955 AcpiDmTableInfoErdtMmrcCorrFactor, &Subtable); 1956 if (ACPI_FAILURE (Status)) 1957 { 1958 return (Status); 1959 } 1960 if (!Subtable) 1961 { 1962 break; 1963 } 1964 1965 ParentTable = DtPeekSubtable (); 1966 DtInsertSubtable (ParentTable, Subtable); 1967 NumEntries++; 1968 } 1969 Mmrc->CorrFactorListLen = NumEntries; 1970 break; 1971 1972 case ACPI_ERDT_TYPE_IBRD: 1973 Ibrd = ACPI_SUB_PTR (ACPI_ERDT_IBRD, Subtable->Buffer, 1974 sizeof(ACPI_SUBTBL_HDR_16)); 1975 NumEntries = 0; 1976 while (*PFieldList) 1977 { 1978 Status = DtCompileTable (PFieldList, 1979 AcpiDmTableInfoErdtIbrdCorrFactor, &Subtable); 1980 if (ACPI_FAILURE (Status)) 1981 { 1982 return (Status); 1983 } 1984 if (!Subtable) 1985 { 1986 break; 1987 } 1988 1989 ParentTable = DtPeekSubtable (); 1990 DtInsertSubtable (ParentTable, Subtable); 1991 NumEntries++; 1992 } 1993 Ibrd->CorrFactorListLen = NumEntries; 1994 break; 1995 1996 default: 1997 /* Already checked for valid subtable type above */ 1998 1999 break; 2000 } 2001 DtPopSubtable (); 2002 } 2003 2004 if (SeenSubtable) 2005 { 2006 DtPopSubtable (); 2007 } 2008 2009 return (AE_OK); 2010 } 2011 2012 2013 /****************************************************************************** 2014 * 2015 * FUNCTION: DtCompileErst 2016 * 2017 * PARAMETERS: List - Current field list pointer 2018 * 2019 * RETURN: Status 2020 * 2021 * DESCRIPTION: Compile ERST. 2022 * 2023 *****************************************************************************/ 2024 2025 ACPI_STATUS 2026 DtCompileErst ( 2027 void **List) 2028 { 2029 ACPI_STATUS Status; 2030 2031 2032 Status = DtCompileTwoSubtables (List, 2033 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 2034 return (Status); 2035 } 2036 2037 2038 /****************************************************************************** 2039 * 2040 * FUNCTION: DtCompileGtdt 2041 * 2042 * PARAMETERS: List - Current field list pointer 2043 * 2044 * RETURN: Status 2045 * 2046 * DESCRIPTION: Compile GTDT. 2047 * 2048 *****************************************************************************/ 2049 2050 ACPI_STATUS 2051 DtCompileGtdt ( 2052 void **List) 2053 { 2054 ACPI_STATUS Status; 2055 DT_SUBTABLE *Subtable; 2056 DT_SUBTABLE *ParentTable; 2057 DT_FIELD **PFieldList = (DT_FIELD **) List; 2058 DT_FIELD *SubtableStart; 2059 ACPI_SUBTABLE_HEADER *GtdtHeader; 2060 ACPI_DMTABLE_INFO *InfoTable; 2061 UINT32 GtCount; 2062 ACPI_TABLE_HEADER *Header; 2063 2064 2065 ParentTable = DtPeekSubtable (); 2066 2067 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2068 2069 /* Compile the main table */ 2070 2071 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 2072 &Subtable); 2073 if (ACPI_FAILURE (Status)) 2074 { 2075 return (Status); 2076 } 2077 2078 /* GTDT revision 3 later contains 2 extra fields before subtables */ 2079 2080 if (Header->Revision > 2) 2081 { 2082 ParentTable = DtPeekSubtable (); 2083 DtInsertSubtable (ParentTable, Subtable); 2084 2085 Status = DtCompileTable (PFieldList, 2086 AcpiDmTableInfoGtdtEl2, &Subtable); 2087 if (ACPI_FAILURE (Status)) 2088 { 2089 return (Status); 2090 } 2091 } 2092 2093 ParentTable = DtPeekSubtable (); 2094 DtInsertSubtable (ParentTable, Subtable); 2095 2096 while (*PFieldList) 2097 { 2098 SubtableStart = *PFieldList; 2099 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 2100 &Subtable); 2101 if (ACPI_FAILURE (Status)) 2102 { 2103 return (Status); 2104 } 2105 2106 ParentTable = DtPeekSubtable (); 2107 DtInsertSubtable (ParentTable, Subtable); 2108 DtPushSubtable (Subtable); 2109 2110 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2111 2112 switch (GtdtHeader->Type) 2113 { 2114 case ACPI_GTDT_TYPE_TIMER_BLOCK: 2115 2116 InfoTable = AcpiDmTableInfoGtdt0; 2117 break; 2118 2119 case ACPI_GTDT_TYPE_WATCHDOG: 2120 2121 InfoTable = AcpiDmTableInfoGtdt1; 2122 break; 2123 2124 default: 2125 2126 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 2127 return (AE_ERROR); 2128 } 2129 2130 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2131 if (ACPI_FAILURE (Status)) 2132 { 2133 return (Status); 2134 } 2135 2136 ParentTable = DtPeekSubtable (); 2137 DtInsertSubtable (ParentTable, Subtable); 2138 2139 /* 2140 * Additional GT block subtable data 2141 */ 2142 2143 switch (GtdtHeader->Type) 2144 { 2145 case ACPI_GTDT_TYPE_TIMER_BLOCK: 2146 2147 DtPushSubtable (Subtable); 2148 ParentTable = DtPeekSubtable (); 2149 2150 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 2151 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 2152 2153 while (GtCount) 2154 { 2155 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 2156 &Subtable); 2157 if (ACPI_FAILURE (Status)) 2158 { 2159 return (Status); 2160 } 2161 2162 DtInsertSubtable (ParentTable, Subtable); 2163 GtCount--; 2164 } 2165 2166 DtPopSubtable (); 2167 break; 2168 2169 default: 2170 2171 break; 2172 } 2173 2174 DtPopSubtable (); 2175 } 2176 2177 return (AE_OK); 2178 } 2179 2180 2181 /****************************************************************************** 2182 * 2183 * FUNCTION: DtCompileFpdt 2184 * 2185 * PARAMETERS: List - Current field list pointer 2186 * 2187 * RETURN: Status 2188 * 2189 * DESCRIPTION: Compile FPDT. 2190 * 2191 *****************************************************************************/ 2192 2193 ACPI_STATUS 2194 DtCompileFpdt ( 2195 void **List) 2196 { 2197 ACPI_STATUS Status; 2198 ACPI_FPDT_HEADER *FpdtHeader; 2199 DT_SUBTABLE *Subtable; 2200 DT_SUBTABLE *ParentTable; 2201 ACPI_DMTABLE_INFO *InfoTable; 2202 DT_FIELD **PFieldList = (DT_FIELD **) List; 2203 DT_FIELD *SubtableStart; 2204 2205 2206 while (*PFieldList) 2207 { 2208 SubtableStart = *PFieldList; 2209 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 2210 &Subtable); 2211 if (ACPI_FAILURE (Status)) 2212 { 2213 return (Status); 2214 } 2215 2216 ParentTable = DtPeekSubtable (); 2217 DtInsertSubtable (ParentTable, Subtable); 2218 DtPushSubtable (Subtable); 2219 2220 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 2221 2222 switch (FpdtHeader->Type) 2223 { 2224 case ACPI_FPDT_TYPE_BOOT: 2225 2226 InfoTable = AcpiDmTableInfoFpdt0; 2227 break; 2228 2229 case ACPI_FPDT_TYPE_S3PERF: 2230 2231 InfoTable = AcpiDmTableInfoFpdt1; 2232 break; 2233 2234 default: 2235 2236 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 2237 return (AE_ERROR); 2238 break; 2239 } 2240 2241 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2242 if (ACPI_FAILURE (Status)) 2243 { 2244 return (Status); 2245 } 2246 2247 ParentTable = DtPeekSubtable (); 2248 DtInsertSubtable (ParentTable, Subtable); 2249 DtPopSubtable (); 2250 } 2251 2252 return (AE_OK); 2253 } 2254 2255 2256 /****************************************************************************** 2257 * 2258 * FUNCTION: DtCompileHest 2259 * 2260 * PARAMETERS: List - Current field list pointer 2261 * 2262 * RETURN: Status 2263 * 2264 * DESCRIPTION: Compile HEST. 2265 * 2266 *****************************************************************************/ 2267 2268 ACPI_STATUS 2269 DtCompileHest ( 2270 void **List) 2271 { 2272 ACPI_STATUS Status; 2273 DT_SUBTABLE *Subtable; 2274 DT_SUBTABLE *ParentTable; 2275 DT_FIELD **PFieldList = (DT_FIELD **) List; 2276 DT_FIELD *SubtableStart; 2277 ACPI_DMTABLE_INFO *InfoTable; 2278 UINT16 Type; 2279 UINT32 BankCount; 2280 2281 2282 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 2283 &Subtable); 2284 if (ACPI_FAILURE (Status)) 2285 { 2286 return (Status); 2287 } 2288 2289 ParentTable = DtPeekSubtable (); 2290 DtInsertSubtable (ParentTable, Subtable); 2291 2292 while (*PFieldList) 2293 { 2294 /* Get subtable type */ 2295 2296 SubtableStart = *PFieldList; 2297 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 2298 2299 switch (Type) 2300 { 2301 case ACPI_HEST_TYPE_IA32_CHECK: 2302 2303 InfoTable = AcpiDmTableInfoHest0; 2304 break; 2305 2306 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 2307 2308 InfoTable = AcpiDmTableInfoHest1; 2309 break; 2310 2311 case ACPI_HEST_TYPE_IA32_NMI: 2312 2313 InfoTable = AcpiDmTableInfoHest2; 2314 break; 2315 2316 case ACPI_HEST_TYPE_AER_ROOT_PORT: 2317 2318 InfoTable = AcpiDmTableInfoHest6; 2319 break; 2320 2321 case ACPI_HEST_TYPE_AER_ENDPOINT: 2322 2323 InfoTable = AcpiDmTableInfoHest7; 2324 break; 2325 2326 case ACPI_HEST_TYPE_AER_BRIDGE: 2327 2328 InfoTable = AcpiDmTableInfoHest8; 2329 break; 2330 2331 case ACPI_HEST_TYPE_GENERIC_ERROR: 2332 2333 InfoTable = AcpiDmTableInfoHest9; 2334 break; 2335 2336 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 2337 2338 InfoTable = AcpiDmTableInfoHest10; 2339 break; 2340 2341 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 2342 2343 InfoTable = AcpiDmTableInfoHest11; 2344 break; 2345 2346 default: 2347 2348 /* Cannot continue on unknown type */ 2349 2350 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 2351 return (AE_ERROR); 2352 } 2353 2354 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2355 if (ACPI_FAILURE (Status)) 2356 { 2357 return (Status); 2358 } 2359 2360 DtInsertSubtable (ParentTable, Subtable); 2361 2362 /* 2363 * Additional subtable data - IA32 Error Bank(s) 2364 */ 2365 BankCount = 0; 2366 switch (Type) 2367 { 2368 case ACPI_HEST_TYPE_IA32_CHECK: 2369 2370 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 2371 Subtable->Buffer))->NumHardwareBanks; 2372 break; 2373 2374 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 2375 2376 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 2377 Subtable->Buffer))->NumHardwareBanks; 2378 break; 2379 2380 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 2381 2382 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 2383 Subtable->Buffer))->NumHardwareBanks; 2384 break; 2385 2386 default: 2387 2388 break; 2389 } 2390 2391 while (BankCount) 2392 { 2393 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 2394 &Subtable); 2395 if (ACPI_FAILURE (Status)) 2396 { 2397 return (Status); 2398 } 2399 2400 DtInsertSubtable (ParentTable, Subtable); 2401 BankCount--; 2402 } 2403 } 2404 2405 return (AE_OK); 2406 } 2407 2408 2409 /****************************************************************************** 2410 * 2411 * FUNCTION: DtCompileHmat 2412 * 2413 * PARAMETERS: List - Current field list pointer 2414 * 2415 * RETURN: Status 2416 * 2417 * DESCRIPTION: Compile HMAT. 2418 * 2419 *****************************************************************************/ 2420 2421 ACPI_STATUS 2422 DtCompileHmat ( 2423 void **List) 2424 { 2425 ACPI_STATUS Status; 2426 DT_SUBTABLE *Subtable; 2427 DT_SUBTABLE *ParentTable; 2428 DT_FIELD **PFieldList = (DT_FIELD **) List; 2429 DT_FIELD *SubtableStart; 2430 DT_FIELD *EntryStart; 2431 ACPI_HMAT_STRUCTURE *HmatStruct; 2432 ACPI_HMAT_LOCALITY *HmatLocality; 2433 ACPI_HMAT_CACHE *HmatCache; 2434 ACPI_DMTABLE_INFO *InfoTable; 2435 UINT32 IntPDNumber; 2436 UINT32 TgtPDNumber; 2437 UINT64 EntryNumber; 2438 UINT16 SMBIOSHandleNumber; 2439 2440 2441 ParentTable = DtPeekSubtable (); 2442 2443 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 2444 &Subtable); 2445 if (ACPI_FAILURE (Status)) 2446 { 2447 return (Status); 2448 } 2449 DtInsertSubtable (ParentTable, Subtable); 2450 2451 while (*PFieldList) 2452 { 2453 /* Compile HMAT structure header */ 2454 2455 SubtableStart = *PFieldList; 2456 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 2457 &Subtable); 2458 if (ACPI_FAILURE (Status)) 2459 { 2460 return (Status); 2461 } 2462 DtInsertSubtable (ParentTable, Subtable); 2463 2464 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 2465 HmatStruct->Length = Subtable->Length; 2466 2467 /* Compile HMAT structure body */ 2468 2469 switch (HmatStruct->Type) 2470 { 2471 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 2472 2473 InfoTable = AcpiDmTableInfoHmat0; 2474 break; 2475 2476 case ACPI_HMAT_TYPE_LOCALITY: 2477 2478 InfoTable = AcpiDmTableInfoHmat1; 2479 break; 2480 2481 case ACPI_HMAT_TYPE_CACHE: 2482 2483 InfoTable = AcpiDmTableInfoHmat2; 2484 break; 2485 2486 default: 2487 2488 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 2489 return (AE_ERROR); 2490 } 2491 2492 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2493 if (ACPI_FAILURE (Status)) 2494 { 2495 return (Status); 2496 } 2497 DtInsertSubtable (ParentTable, Subtable); 2498 HmatStruct->Length += Subtable->Length; 2499 2500 /* Compile HMAT structure additional */ 2501 2502 switch (HmatStruct->Type) 2503 { 2504 case ACPI_HMAT_TYPE_LOCALITY: 2505 2506 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 2507 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 2508 2509 /* Compile initiator proximity domain list */ 2510 2511 IntPDNumber = 0; 2512 while (*PFieldList) 2513 { 2514 Status = DtCompileTable (PFieldList, 2515 AcpiDmTableInfoHmat1a, &Subtable); 2516 if (ACPI_FAILURE (Status)) 2517 { 2518 return (Status); 2519 } 2520 if (!Subtable) 2521 { 2522 break; 2523 } 2524 DtInsertSubtable (ParentTable, Subtable); 2525 HmatStruct->Length += Subtable->Length; 2526 IntPDNumber++; 2527 } 2528 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 2529 2530 /* Compile target proximity domain list */ 2531 2532 TgtPDNumber = 0; 2533 while (*PFieldList) 2534 { 2535 Status = DtCompileTable (PFieldList, 2536 AcpiDmTableInfoHmat1b, &Subtable); 2537 if (ACPI_FAILURE (Status)) 2538 { 2539 return (Status); 2540 } 2541 if (!Subtable) 2542 { 2543 break; 2544 } 2545 DtInsertSubtable (ParentTable, Subtable); 2546 HmatStruct->Length += Subtable->Length; 2547 TgtPDNumber++; 2548 } 2549 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 2550 2551 /* Save start of the entries for reporting errors */ 2552 2553 EntryStart = *PFieldList; 2554 2555 /* Compile latency/bandwidth entries */ 2556 2557 EntryNumber = 0; 2558 while (*PFieldList) 2559 { 2560 Status = DtCompileTable (PFieldList, 2561 AcpiDmTableInfoHmat1c, &Subtable); 2562 if (ACPI_FAILURE (Status)) 2563 { 2564 return (Status); 2565 } 2566 if (!Subtable) 2567 { 2568 break; 2569 } 2570 DtInsertSubtable (ParentTable, Subtable); 2571 HmatStruct->Length += Subtable->Length; 2572 EntryNumber++; 2573 } 2574 2575 /* Validate number of entries */ 2576 2577 if (EntryNumber != 2578 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 2579 { 2580 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 2581 return (AE_ERROR); 2582 } 2583 break; 2584 2585 case ACPI_HMAT_TYPE_CACHE: 2586 2587 /* Compile SMBIOS handles */ 2588 2589 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 2590 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 2591 SMBIOSHandleNumber = 0; 2592 while (*PFieldList) 2593 { 2594 Status = DtCompileTable (PFieldList, 2595 AcpiDmTableInfoHmat2a, &Subtable); 2596 if (ACPI_FAILURE (Status)) 2597 { 2598 return (Status); 2599 } 2600 if (!Subtable) 2601 { 2602 break; 2603 } 2604 DtInsertSubtable (ParentTable, Subtable); 2605 HmatStruct->Length += Subtable->Length; 2606 SMBIOSHandleNumber++; 2607 } 2608 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 2609 break; 2610 2611 default: 2612 2613 break; 2614 } 2615 } 2616 2617 return (AE_OK); 2618 } 2619 2620 2621 /****************************************************************************** 2622 * 2623 * FUNCTION: DtCompileIort 2624 * 2625 * PARAMETERS: List - Current field list pointer 2626 * 2627 * RETURN: Status 2628 * 2629 * DESCRIPTION: Compile IORT. 2630 * 2631 *****************************************************************************/ 2632 2633 ACPI_STATUS 2634 DtCompileIort ( 2635 void **List) 2636 { 2637 ACPI_STATUS Status; 2638 DT_SUBTABLE *Subtable; 2639 DT_SUBTABLE *ParentTable; 2640 DT_FIELD **PFieldList = (DT_FIELD **) List; 2641 DT_FIELD *SubtableStart; 2642 ACPI_TABLE_HEADER *Table; 2643 ACPI_TABLE_IORT *Iort; 2644 ACPI_IORT_NODE *IortNode; 2645 ACPI_IORT_ITS_GROUP *IortItsGroup; 2646 ACPI_IORT_SMMU *IortSmmu; 2647 ACPI_IORT_RMR *IortRmr; 2648 UINT32 NodeNumber; 2649 UINT32 NodeLength; 2650 UINT32 IdMappingNumber; 2651 UINT32 ItsNumber; 2652 UINT32 ContextIrptNumber; 2653 UINT32 PmuIrptNumber; 2654 UINT32 PaddingLength; 2655 UINT8 Revision; 2656 UINT32 RmrCount; 2657 2658 2659 ParentTable = DtPeekSubtable (); 2660 2661 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 2662 &Subtable); 2663 if (ACPI_FAILURE (Status)) 2664 { 2665 return (Status); 2666 } 2667 DtInsertSubtable (ParentTable, Subtable); 2668 2669 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2670 Revision = Table->Revision; 2671 2672 /* IORT Revisions E, E.a & E.c have known issues and are not supported */ 2673 2674 if (Revision == 1 || Revision == 2 || Revision == 4) 2675 { 2676 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision"); 2677 return (AE_ERROR); 2678 } 2679 2680 /* 2681 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 2682 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 2683 */ 2684 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 2685 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 2686 2687 /* 2688 * OptionalPadding - Variable-length data 2689 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 2690 * Optionally allows the generic data types to be used for filling 2691 * this field. 2692 */ 2693 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 2694 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 2695 &Subtable); 2696 if (ACPI_FAILURE (Status)) 2697 { 2698 return (Status); 2699 } 2700 if (Subtable) 2701 { 2702 DtInsertSubtable (ParentTable, Subtable); 2703 Iort->NodeOffset += Subtable->Length; 2704 } 2705 else 2706 { 2707 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 2708 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 2709 if (ACPI_FAILURE (Status)) 2710 { 2711 return (Status); 2712 } 2713 Iort->NodeOffset += PaddingLength; 2714 } 2715 2716 NodeNumber = 0; 2717 while (*PFieldList) 2718 { 2719 SubtableStart = *PFieldList; 2720 if (Revision == 0) 2721 { 2722 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 2723 &Subtable); 2724 } 2725 else if (Revision >= 3) 2726 { 2727 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3, 2728 &Subtable); 2729 } 2730 2731 if (ACPI_FAILURE (Status)) 2732 { 2733 return (Status); 2734 } 2735 2736 DtInsertSubtable (ParentTable, Subtable); 2737 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 2738 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 2739 2740 DtPushSubtable (Subtable); 2741 ParentTable = DtPeekSubtable (); 2742 2743 switch (IortNode->Type) 2744 { 2745 case ACPI_IORT_NODE_ITS_GROUP: 2746 2747 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 2748 &Subtable); 2749 if (ACPI_FAILURE (Status)) 2750 { 2751 return (Status); 2752 } 2753 2754 DtInsertSubtable (ParentTable, Subtable); 2755 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 2756 NodeLength += Subtable->Length; 2757 2758 ItsNumber = 0; 2759 while (*PFieldList) 2760 { 2761 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 2762 &Subtable); 2763 if (ACPI_FAILURE (Status)) 2764 { 2765 return (Status); 2766 } 2767 if (!Subtable) 2768 { 2769 break; 2770 } 2771 2772 DtInsertSubtable (ParentTable, Subtable); 2773 NodeLength += Subtable->Length; 2774 ItsNumber++; 2775 } 2776 2777 IortItsGroup->ItsCount = ItsNumber; 2778 break; 2779 2780 case ACPI_IORT_NODE_NAMED_COMPONENT: 2781 2782 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 2783 &Subtable); 2784 if (ACPI_FAILURE (Status)) 2785 { 2786 return (Status); 2787 } 2788 2789 DtInsertSubtable (ParentTable, Subtable); 2790 NodeLength += Subtable->Length; 2791 2792 /* 2793 * Padding - Variable-length data 2794 * Optionally allows the offset of the ID mappings to be used 2795 * for filling this field. 2796 */ 2797 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 2798 &Subtable); 2799 if (ACPI_FAILURE (Status)) 2800 { 2801 return (Status); 2802 } 2803 2804 if (Subtable) 2805 { 2806 DtInsertSubtable (ParentTable, Subtable); 2807 NodeLength += Subtable->Length; 2808 } 2809 else 2810 { 2811 if (NodeLength > IortNode->MappingOffset) 2812 { 2813 return (AE_BAD_DATA); 2814 } 2815 2816 if (NodeLength < IortNode->MappingOffset) 2817 { 2818 Status = DtCompilePadding ( 2819 IortNode->MappingOffset - NodeLength, 2820 &Subtable); 2821 if (ACPI_FAILURE (Status)) 2822 { 2823 return (Status); 2824 } 2825 2826 DtInsertSubtable (ParentTable, Subtable); 2827 NodeLength = IortNode->MappingOffset; 2828 } 2829 } 2830 break; 2831 2832 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 2833 2834 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 2835 &Subtable); 2836 if (ACPI_FAILURE (Status)) 2837 { 2838 return (Status); 2839 } 2840 2841 DtInsertSubtable (ParentTable, Subtable); 2842 NodeLength += Subtable->Length; 2843 break; 2844 2845 case ACPI_IORT_NODE_SMMU: 2846 2847 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 2848 &Subtable); 2849 if (ACPI_FAILURE (Status)) 2850 { 2851 return (Status); 2852 } 2853 2854 DtInsertSubtable (ParentTable, Subtable); 2855 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 2856 NodeLength += Subtable->Length; 2857 2858 /* Compile global interrupt array */ 2859 2860 IortSmmu->GlobalInterruptOffset = NodeLength; 2861 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 2862 &Subtable); 2863 if (ACPI_FAILURE (Status)) 2864 { 2865 return (Status); 2866 } 2867 2868 DtInsertSubtable (ParentTable, Subtable); 2869 NodeLength += Subtable->Length; 2870 2871 /* Compile context interrupt array */ 2872 2873 ContextIrptNumber = 0; 2874 IortSmmu->ContextInterruptOffset = NodeLength; 2875 while (*PFieldList) 2876 { 2877 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 2878 &Subtable); 2879 if (ACPI_FAILURE (Status)) 2880 { 2881 return (Status); 2882 } 2883 2884 if (!Subtable) 2885 { 2886 break; 2887 } 2888 2889 DtInsertSubtable (ParentTable, Subtable); 2890 NodeLength += Subtable->Length; 2891 ContextIrptNumber++; 2892 } 2893 2894 IortSmmu->ContextInterruptCount = ContextIrptNumber; 2895 2896 /* Compile PMU interrupt array */ 2897 2898 PmuIrptNumber = 0; 2899 IortSmmu->PmuInterruptOffset = NodeLength; 2900 while (*PFieldList) 2901 { 2902 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 2903 &Subtable); 2904 if (ACPI_FAILURE (Status)) 2905 { 2906 return (Status); 2907 } 2908 2909 if (!Subtable) 2910 { 2911 break; 2912 } 2913 2914 DtInsertSubtable (ParentTable, Subtable); 2915 NodeLength += Subtable->Length; 2916 PmuIrptNumber++; 2917 } 2918 2919 IortSmmu->PmuInterruptCount = PmuIrptNumber; 2920 break; 2921 2922 case ACPI_IORT_NODE_SMMU_V3: 2923 2924 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 2925 &Subtable); 2926 if (ACPI_FAILURE (Status)) 2927 { 2928 return (Status); 2929 } 2930 2931 DtInsertSubtable (ParentTable, Subtable); 2932 NodeLength += Subtable->Length; 2933 break; 2934 2935 case ACPI_IORT_NODE_PMCG: 2936 2937 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5, 2938 &Subtable); 2939 if (ACPI_FAILURE (Status)) 2940 { 2941 return (Status); 2942 } 2943 2944 DtInsertSubtable (ParentTable, Subtable); 2945 NodeLength += Subtable->Length; 2946 break; 2947 2948 case ACPI_IORT_NODE_RMR: 2949 2950 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6, 2951 &Subtable); 2952 if (ACPI_FAILURE (Status)) 2953 { 2954 return (Status); 2955 } 2956 2957 DtInsertSubtable (ParentTable, Subtable); 2958 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer); 2959 NodeLength += Subtable->Length; 2960 2961 /* Compile RMR Descriptors */ 2962 2963 RmrCount = 0; 2964 IortRmr->RmrOffset = NodeLength; 2965 while (*PFieldList) 2966 { 2967 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a, 2968 &Subtable); 2969 if (ACPI_FAILURE (Status)) 2970 { 2971 return (Status); 2972 } 2973 2974 if (!Subtable) 2975 { 2976 break; 2977 } 2978 2979 DtInsertSubtable (ParentTable, Subtable); 2980 NodeLength += sizeof (ACPI_IORT_RMR_DESC); 2981 RmrCount++; 2982 } 2983 2984 IortRmr->RmrCount = RmrCount; 2985 break; 2986 2987 default: 2988 2989 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 2990 return (AE_ERROR); 2991 } 2992 2993 /* Compile Array of ID mappings */ 2994 2995 IortNode->MappingOffset = NodeLength; 2996 IdMappingNumber = 0; 2997 while (*PFieldList) 2998 { 2999 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 3000 &Subtable); 3001 if (ACPI_FAILURE (Status)) 3002 { 3003 return (Status); 3004 } 3005 3006 if (!Subtable) 3007 { 3008 break; 3009 } 3010 3011 DtInsertSubtable (ParentTable, Subtable); 3012 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 3013 IdMappingNumber++; 3014 } 3015 3016 IortNode->MappingCount = IdMappingNumber; 3017 if (!IdMappingNumber) 3018 { 3019 IortNode->MappingOffset = 0; 3020 } 3021 3022 /* 3023 * Node length can be determined by DT_LENGTH option 3024 * IortNode->Length = NodeLength; 3025 */ 3026 DtPopSubtable (); 3027 ParentTable = DtPeekSubtable (); 3028 NodeNumber++; 3029 } 3030 3031 Iort->NodeCount = NodeNumber; 3032 return (AE_OK); 3033 } 3034 3035 3036 /****************************************************************************** 3037 * 3038 * FUNCTION: DtCompileIvrs 3039 * 3040 * PARAMETERS: List - Current field list pointer 3041 * 3042 * RETURN: Status 3043 * 3044 * DESCRIPTION: Compile IVRS. Notes: 3045 * The IVRS is essentially a flat table, with the following 3046 * structure: 3047 * <Main ACPI Table Header> 3048 * <Main subtable - virtualization info> 3049 * <IVHD> 3050 * <Device Entries> 3051 * ... 3052 * <IVHD> 3053 * <Device Entries> 3054 * <IVMD> 3055 * ... 3056 * 3057 *****************************************************************************/ 3058 3059 ACPI_STATUS 3060 DtCompileIvrs ( 3061 void **List) 3062 { 3063 ACPI_STATUS Status; 3064 DT_SUBTABLE *Subtable; 3065 DT_SUBTABLE *ParentTable; 3066 DT_SUBTABLE *MainSubtable; 3067 DT_FIELD **PFieldList = (DT_FIELD **) List; 3068 DT_FIELD *SubtableStart; 3069 ACPI_DMTABLE_INFO *InfoTable = NULL; 3070 UINT8 SubtableType; 3071 UINT8 Temp64[16]; 3072 UINT8 Temp8; 3073 3074 3075 /* Main table */ 3076 3077 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 3078 &Subtable); 3079 if (ACPI_FAILURE (Status)) 3080 { 3081 return (Status); 3082 } 3083 3084 ParentTable = DtPeekSubtable (); 3085 DtInsertSubtable (ParentTable, Subtable); 3086 DtPushSubtable (Subtable); 3087 3088 /* Save a pointer to the main subtable */ 3089 3090 MainSubtable = Subtable; 3091 3092 while (*PFieldList) 3093 { 3094 SubtableStart = *PFieldList; 3095 3096 /* Compile the SubtableType integer */ 3097 3098 DtCompileInteger (&SubtableType, *PFieldList, 1, 0); 3099 3100 switch (SubtableType) 3101 { 3102 3103 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */ 3104 3105 case ACPI_IVRS_TYPE_HARDWARE1: 3106 3107 InfoTable = AcpiDmTableInfoIvrsHware1; 3108 break; 3109 3110 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */ 3111 3112 case ACPI_IVRS_TYPE_HARDWARE2: 3113 case ACPI_IVRS_TYPE_HARDWARE3: 3114 3115 InfoTable = AcpiDmTableInfoIvrsHware23; 3116 break; 3117 3118 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */ 3119 3120 case ACPI_IVRS_TYPE_MEMORY1: 3121 case ACPI_IVRS_TYPE_MEMORY2: 3122 case ACPI_IVRS_TYPE_MEMORY3: 3123 3124 InfoTable = AcpiDmTableInfoIvrsMemory; 3125 break; 3126 3127 /* 4-byte device entries */ 3128 3129 case ACPI_IVRS_TYPE_PAD4: 3130 case ACPI_IVRS_TYPE_ALL: 3131 case ACPI_IVRS_TYPE_SELECT: 3132 case ACPI_IVRS_TYPE_START: 3133 case ACPI_IVRS_TYPE_END: 3134 3135 InfoTable = AcpiDmTableInfoIvrs4; 3136 break; 3137 3138 /* 8-byte device entries, type A */ 3139 3140 case ACPI_IVRS_TYPE_ALIAS_SELECT: 3141 case ACPI_IVRS_TYPE_ALIAS_START: 3142 3143 InfoTable = AcpiDmTableInfoIvrs8a; 3144 break; 3145 3146 /* 8-byte device entries, type B */ 3147 3148 case ACPI_IVRS_TYPE_EXT_SELECT: 3149 case ACPI_IVRS_TYPE_EXT_START: 3150 3151 InfoTable = AcpiDmTableInfoIvrs8b; 3152 break; 3153 3154 /* 8-byte device entries, type C */ 3155 3156 case ACPI_IVRS_TYPE_SPECIAL: 3157 3158 InfoTable = AcpiDmTableInfoIvrs8c; 3159 break; 3160 3161 /* Variable device entries, type F0h */ 3162 3163 case ACPI_IVRS_TYPE_HID: 3164 3165 InfoTable = AcpiDmTableInfoIvrsHid; 3166 break; 3167 3168 default: 3169 3170 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 3171 "IVRS Device Entry"); 3172 return (AE_ERROR); 3173 } 3174 3175 /* Compile the InfoTable from above */ 3176 3177 Status = DtCompileTable (PFieldList, InfoTable, 3178 &Subtable); 3179 if (ACPI_FAILURE (Status)) 3180 { 3181 return (Status); 3182 } 3183 3184 ParentTable = DtPeekSubtable (); 3185 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 && 3186 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 && 3187 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 && 3188 SubtableType != ACPI_IVRS_TYPE_HID && 3189 SubtableType != ACPI_IVRS_TYPE_MEMORY1 && 3190 SubtableType != ACPI_IVRS_TYPE_MEMORY2 && 3191 SubtableType != ACPI_IVRS_TYPE_MEMORY3) 3192 { 3193 if (ParentTable) 3194 DtInsertSubtable (ParentTable, Subtable); 3195 } 3196 3197 switch (SubtableType) 3198 { 3199 case ACPI_IVRS_TYPE_HARDWARE1: 3200 case ACPI_IVRS_TYPE_HARDWARE2: 3201 case ACPI_IVRS_TYPE_HARDWARE3: 3202 case ACPI_IVRS_TYPE_MEMORY1: 3203 case ACPI_IVRS_TYPE_MEMORY2: 3204 case ACPI_IVRS_TYPE_MEMORY3: 3205 3206 /* Insert these IVHDs/IVMDs at the root subtable */ 3207 3208 DtInsertSubtable (MainSubtable, Subtable); 3209 DtPushSubtable (Subtable); 3210 break; 3211 3212 case ACPI_IVRS_TYPE_HID: 3213 3214 /* Special handling for the HID named device entry (0xF0) */ 3215 3216 if (ParentTable) 3217 { 3218 DtInsertSubtable (ParentTable, Subtable); 3219 } 3220 3221 /* 3222 * Process the HID value. First, get the HID value as a string. 3223 */ 3224 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 3225 3226 /* 3227 * Determine if the HID is an integer or a string. 3228 * An integer is defined to be 32 bits, with the upper 32 bits 3229 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit 3230 * integer or a character string. If an integer, the lower 3231 * 4 bytes of the field contain the integer and the upper 3232 * 4 bytes are padded with 0". 3233 */ 3234 if (UtIsIdInteger ((UINT8 *) &Temp64)) 3235 { 3236 /* Compile the HID value as an integer */ 3237 3238 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 3239 3240 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger, 3241 &Subtable); 3242 if (ACPI_FAILURE (Status)) 3243 { 3244 return (Status); 3245 } 3246 } 3247 else 3248 { 3249 /* Compile the HID value as a string */ 3250 3251 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString, 3252 &Subtable); 3253 if (ACPI_FAILURE (Status)) 3254 { 3255 return (Status); 3256 } 3257 } 3258 3259 DtInsertSubtable (ParentTable, Subtable); 3260 3261 /* 3262 * Process the CID value. First, get the CID value as a string. 3263 */ 3264 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 3265 3266 if (UtIsIdInteger ((UINT8 *) &Temp64)) 3267 { 3268 /* Compile the CID value as an integer */ 3269 3270 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 3271 3272 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger, 3273 &Subtable); 3274 if (ACPI_FAILURE (Status)) 3275 { 3276 return (Status); 3277 } 3278 } 3279 else 3280 { 3281 /* Compile the CID value as a string */ 3282 3283 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString, 3284 &Subtable); 3285 if (ACPI_FAILURE (Status)) 3286 { 3287 return (Status); 3288 } 3289 } 3290 3291 DtInsertSubtable (ParentTable, Subtable); 3292 3293 /* 3294 * Process the UID value. First, get and decode the "UID Format" field (Integer). 3295 */ 3296 if (!*PFieldList) 3297 { 3298 return (AE_OK); 3299 } 3300 3301 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0); 3302 3303 switch (Temp8) 3304 { 3305 case ACPI_IVRS_UID_NOT_PRESENT: 3306 break; 3307 3308 case ACPI_IVRS_UID_IS_INTEGER: 3309 3310 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger, 3311 &Subtable); 3312 if (ACPI_FAILURE (Status)) 3313 { 3314 return (Status); 3315 } 3316 DtInsertSubtable (ParentTable, Subtable); 3317 break; 3318 3319 case ACPI_IVRS_UID_IS_STRING: 3320 3321 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString, 3322 &Subtable); 3323 if (ACPI_FAILURE (Status)) 3324 { 3325 return (Status); 3326 } 3327 DtInsertSubtable (ParentTable, Subtable); 3328 break; 3329 3330 default: 3331 3332 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart, 3333 "IVRS Device Entry"); 3334 return (AE_ERROR); 3335 } 3336 3337 default: 3338 3339 /* All other subtable types come through here */ 3340 break; 3341 } 3342 } 3343 3344 return (AE_OK); 3345 } 3346 3347 3348 /****************************************************************************** 3349 * 3350 * FUNCTION: DtCompileRimt 3351 * 3352 * PARAMETERS: List - Current field list pointer 3353 * 3354 * RETURN: Status 3355 * 3356 * DESCRIPTION: Compile RIMT. 3357 * 3358 *****************************************************************************/ 3359 3360 ACPI_STATUS 3361 DtCompileRimt ( 3362 void **List) 3363 { 3364 ACPI_RIMT_PLATFORM_DEVICE *PlatDevNode; 3365 ACPI_RIMT_PCIE_RC *PcieRcNode; 3366 ACPI_TABLE_RIMT *Rimt; 3367 ACPI_RIMT_IOMMU *IommuNode; 3368 ACPI_RIMT_NODE *RimtNode; 3369 ACPI_STATUS Status; 3370 DT_SUBTABLE *Subtable; 3371 DT_SUBTABLE *ParentTable; 3372 DT_FIELD **PFieldList = (DT_FIELD **) List; 3373 DT_FIELD *SubtableStart; 3374 UINT32 NodeNumber; 3375 UINT32 NodeLength; 3376 UINT16 IdMappingNumber; 3377 UINT32 i; 3378 3379 3380 ParentTable = DtPeekSubtable (); 3381 3382 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimt, &Subtable); 3383 if (ACPI_FAILURE (Status)) 3384 { 3385 return (Status); 3386 } 3387 3388 DtInsertSubtable (ParentTable, Subtable); 3389 3390 /* 3391 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 3392 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 3393 */ 3394 Rimt = ACPI_SUB_PTR (ACPI_TABLE_RIMT, Subtable->Buffer, 3395 sizeof (ACPI_TABLE_HEADER)); 3396 3397 NodeNumber = 0; 3398 while (*PFieldList) 3399 { 3400 SubtableStart = *PFieldList; 3401 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtNodeHdr, &Subtable); 3402 3403 if (ACPI_FAILURE (Status)) 3404 { 3405 return (Status); 3406 } 3407 3408 DtInsertSubtable (ParentTable, Subtable); 3409 RimtNode = ACPI_CAST_PTR (ACPI_RIMT_NODE, Subtable->Buffer); 3410 NodeLength = ACPI_OFFSET (ACPI_RIMT_NODE, NodeData); 3411 3412 DtPushSubtable (Subtable); 3413 ParentTable = DtPeekSubtable (); 3414 3415 switch (RimtNode->Type) 3416 { 3417 case ACPI_RIMT_NODE_TYPE_IOMMU: 3418 3419 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtIommu, 3420 &Subtable); 3421 if (ACPI_FAILURE (Status)) 3422 { 3423 return (Status); 3424 } 3425 3426 IommuNode = ACPI_CAST_PTR (ACPI_RIMT_IOMMU, Subtable->Buffer); 3427 DtInsertSubtable (ParentTable, Subtable); 3428 NodeLength += Subtable->Length; 3429 3430 for (i = 0; i < IommuNode->NumInterruptWires; i++) 3431 { 3432 while (*PFieldList) 3433 { 3434 Status = DtCompileTable (PFieldList, 3435 AcpiDmTableInfoRimtIommuWire, 3436 &Subtable); 3437 if (ACPI_FAILURE (Status)) 3438 { 3439 return (Status); 3440 } 3441 if (!Subtable) 3442 { 3443 break; 3444 } 3445 3446 DtInsertSubtable (ParentTable, Subtable); 3447 NodeLength += Subtable->Length; 3448 } 3449 } 3450 3451 break; 3452 3453 case ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX: 3454 3455 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPcieRc, 3456 &Subtable); 3457 if (ACPI_FAILURE (Status)) 3458 { 3459 return (Status); 3460 } 3461 3462 DtInsertSubtable (ParentTable, Subtable); 3463 PcieRcNode = ACPI_CAST_PTR (ACPI_RIMT_PCIE_RC, Subtable->Buffer); 3464 NodeLength += Subtable->Length; 3465 3466 /* Compile Array of ID mappings */ 3467 3468 PcieRcNode->IdMappingOffset = (UINT16) NodeLength; 3469 IdMappingNumber = 0; 3470 while (*PFieldList) 3471 { 3472 Status = DtCompileTable (PFieldList, 3473 AcpiDmTableInfoRimtIdMapping, 3474 &Subtable); 3475 if (ACPI_FAILURE (Status)) 3476 { 3477 return (Status); 3478 } 3479 3480 if (!Subtable) 3481 { 3482 break; 3483 } 3484 3485 DtInsertSubtable (ParentTable, Subtable); 3486 NodeLength += sizeof (ACPI_RIMT_ID_MAPPING); 3487 IdMappingNumber++; 3488 } 3489 3490 PcieRcNode->NumIdMappings = IdMappingNumber; 3491 if (!IdMappingNumber) 3492 { 3493 PcieRcNode->IdMappingOffset = 0; 3494 } 3495 3496 break; 3497 3498 case ACPI_RIMT_NODE_TYPE_PLAT_DEVICE: 3499 3500 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDev, 3501 &Subtable); 3502 if (ACPI_FAILURE (Status)) 3503 { 3504 return (Status); 3505 } 3506 3507 DtInsertSubtable (ParentTable, Subtable); 3508 PlatDevNode = ACPI_CAST_PTR (ACPI_RIMT_PLATFORM_DEVICE, Subtable->Buffer); 3509 NodeLength += Subtable->Length; 3510 3511 /* 3512 * Padding - Variable-length data 3513 * Optionally allows the offset of the ID mappings to be used 3514 * for filling this field. 3515 */ 3516 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDevPad, 3517 &Subtable); 3518 if (ACPI_FAILURE (Status)) 3519 { 3520 return (Status); 3521 } 3522 3523 if (Subtable) 3524 { 3525 DtInsertSubtable (ParentTable, Subtable); 3526 NodeLength += Subtable->Length; 3527 } 3528 else 3529 { 3530 if (NodeLength > PlatDevNode->IdMappingOffset) 3531 { 3532 return (AE_BAD_DATA); 3533 } 3534 3535 if (NodeLength < PlatDevNode->IdMappingOffset) 3536 { 3537 Status = DtCompilePadding ( 3538 PlatDevNode->IdMappingOffset - (UINT16) NodeLength, 3539 &Subtable); 3540 if (ACPI_FAILURE (Status)) 3541 { 3542 return (Status); 3543 } 3544 3545 DtInsertSubtable (ParentTable, Subtable); 3546 NodeLength = PlatDevNode->IdMappingOffset; 3547 } 3548 } 3549 3550 /* Compile Array of ID mappings */ 3551 3552 PlatDevNode->IdMappingOffset = (UINT16) NodeLength; 3553 IdMappingNumber = 0; 3554 while (*PFieldList) 3555 { 3556 Status = DtCompileTable (PFieldList, 3557 AcpiDmTableInfoRimtIdMapping, 3558 &Subtable); 3559 if (ACPI_FAILURE (Status)) 3560 { 3561 return (Status); 3562 } 3563 3564 if (!Subtable) 3565 { 3566 break; 3567 } 3568 3569 DtInsertSubtable (ParentTable, Subtable); 3570 NodeLength += sizeof (ACPI_RIMT_ID_MAPPING); 3571 IdMappingNumber++; 3572 } 3573 3574 PlatDevNode->NumIdMappings = IdMappingNumber; 3575 if (!IdMappingNumber) 3576 { 3577 PlatDevNode->IdMappingOffset = 0; 3578 } 3579 3580 break; 3581 3582 3583 default: 3584 3585 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RIMT"); 3586 return (AE_ERROR); 3587 } 3588 3589 DtPopSubtable (); 3590 ParentTable = DtPeekSubtable (); 3591 NodeNumber++; 3592 } 3593 3594 Rimt->NumNodes = NodeNumber; 3595 return (AE_OK); 3596 } 3597