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 - 2024, 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 default: 1511 1512 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 1513 return (AE_ERROR); 1514 } 1515 1516 /* DMAR Subtable */ 1517 1518 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1519 if (ACPI_FAILURE (Status)) 1520 { 1521 return (Status); 1522 } 1523 1524 ParentTable = DtPeekSubtable (); 1525 DtInsertSubtable (ParentTable, Subtable); 1526 1527 /* 1528 * Optional Device Scope subtables 1529 */ 1530 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 1531 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 1532 { 1533 /* These types do not support device scopes */ 1534 1535 DtPopSubtable (); 1536 continue; 1537 } 1538 1539 DtPushSubtable (Subtable); 1540 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 1541 ParentTable->Length; 1542 while (DeviceScopeLength) 1543 { 1544 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 1545 &Subtable); 1546 if (Status == AE_NOT_FOUND) 1547 { 1548 break; 1549 } 1550 1551 ParentTable = DtPeekSubtable (); 1552 DtInsertSubtable (ParentTable, Subtable); 1553 DtPushSubtable (Subtable); 1554 1555 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 1556 1557 /* Optional PCI Paths */ 1558 1559 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 1560 while (PciPathLength) 1561 { 1562 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 1563 &Subtable); 1564 if (Status == AE_NOT_FOUND) 1565 { 1566 DtPopSubtable (); 1567 break; 1568 } 1569 1570 ParentTable = DtPeekSubtable (); 1571 DtInsertSubtable (ParentTable, Subtable); 1572 PciPathLength -= Subtable->Length; 1573 } 1574 1575 DtPopSubtable (); 1576 DeviceScopeLength -= DmarDeviceScope->Length; 1577 } 1578 1579 DtPopSubtable (); 1580 DtPopSubtable (); 1581 } 1582 1583 return (AE_OK); 1584 } 1585 1586 1587 /****************************************************************************** 1588 * 1589 * FUNCTION: DtCompileDrtm 1590 * 1591 * PARAMETERS: List - Current field list pointer 1592 * 1593 * RETURN: Status 1594 * 1595 * DESCRIPTION: Compile DRTM. 1596 * 1597 *****************************************************************************/ 1598 1599 ACPI_STATUS 1600 DtCompileDrtm ( 1601 void **List) 1602 { 1603 ACPI_STATUS Status; 1604 DT_SUBTABLE *Subtable; 1605 DT_SUBTABLE *ParentTable; 1606 DT_FIELD **PFieldList = (DT_FIELD **) List; 1607 UINT32 Count; 1608 /* ACPI_TABLE_DRTM *Drtm; */ 1609 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 1610 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 1611 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 1612 1613 1614 ParentTable = DtPeekSubtable (); 1615 1616 /* Compile DRTM header */ 1617 1618 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 1619 &Subtable); 1620 if (ACPI_FAILURE (Status)) 1621 { 1622 return (Status); 1623 } 1624 DtInsertSubtable (ParentTable, Subtable); 1625 1626 /* 1627 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1628 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 1629 */ 1630 #if 0 1631 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 1632 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1633 #endif 1634 /* Compile VTL */ 1635 1636 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 1637 &Subtable); 1638 if (ACPI_FAILURE (Status)) 1639 { 1640 return (Status); 1641 } 1642 1643 DtInsertSubtable (ParentTable, Subtable); 1644 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 1645 1646 DtPushSubtable (Subtable); 1647 ParentTable = DtPeekSubtable (); 1648 Count = 0; 1649 1650 while (*PFieldList) 1651 { 1652 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 1653 &Subtable); 1654 if (ACPI_FAILURE (Status)) 1655 { 1656 return (Status); 1657 } 1658 if (!Subtable) 1659 { 1660 break; 1661 } 1662 DtInsertSubtable (ParentTable, Subtable); 1663 Count++; 1664 } 1665 1666 DrtmVtl->ValidatedTableCount = Count; 1667 DtPopSubtable (); 1668 ParentTable = DtPeekSubtable (); 1669 1670 /* Compile RL */ 1671 1672 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 1673 &Subtable); 1674 if (ACPI_FAILURE (Status)) 1675 { 1676 return (Status); 1677 } 1678 1679 DtInsertSubtable (ParentTable, Subtable); 1680 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 1681 1682 DtPushSubtable (Subtable); 1683 ParentTable = DtPeekSubtable (); 1684 Count = 0; 1685 1686 while (*PFieldList) 1687 { 1688 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 1689 &Subtable); 1690 if (ACPI_FAILURE (Status)) 1691 { 1692 return (Status); 1693 } 1694 1695 if (!Subtable) 1696 { 1697 break; 1698 } 1699 1700 DtInsertSubtable (ParentTable, Subtable); 1701 Count++; 1702 } 1703 1704 DrtmRl->ResourceCount = Count; 1705 DtPopSubtable (); 1706 ParentTable = DtPeekSubtable (); 1707 1708 /* Compile DPS */ 1709 1710 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 1711 &Subtable); 1712 if (ACPI_FAILURE (Status)) 1713 { 1714 return (Status); 1715 } 1716 DtInsertSubtable (ParentTable, Subtable); 1717 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 1718 1719 1720 return (AE_OK); 1721 } 1722 1723 1724 /****************************************************************************** 1725 * 1726 * FUNCTION: DtCompileEinj 1727 * 1728 * PARAMETERS: List - Current field list pointer 1729 * 1730 * RETURN: Status 1731 * 1732 * DESCRIPTION: Compile EINJ. 1733 * 1734 *****************************************************************************/ 1735 1736 ACPI_STATUS 1737 DtCompileEinj ( 1738 void **List) 1739 { 1740 ACPI_STATUS Status; 1741 1742 1743 Status = DtCompileTwoSubtables (List, 1744 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 1745 return (Status); 1746 } 1747 1748 1749 /****************************************************************************** 1750 * 1751 * FUNCTION: DtCompileErst 1752 * 1753 * PARAMETERS: List - Current field list pointer 1754 * 1755 * RETURN: Status 1756 * 1757 * DESCRIPTION: Compile ERST. 1758 * 1759 *****************************************************************************/ 1760 1761 ACPI_STATUS 1762 DtCompileErst ( 1763 void **List) 1764 { 1765 ACPI_STATUS Status; 1766 1767 1768 Status = DtCompileTwoSubtables (List, 1769 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 1770 return (Status); 1771 } 1772 1773 1774 /****************************************************************************** 1775 * 1776 * FUNCTION: DtCompileGtdt 1777 * 1778 * PARAMETERS: List - Current field list pointer 1779 * 1780 * RETURN: Status 1781 * 1782 * DESCRIPTION: Compile GTDT. 1783 * 1784 *****************************************************************************/ 1785 1786 ACPI_STATUS 1787 DtCompileGtdt ( 1788 void **List) 1789 { 1790 ACPI_STATUS Status; 1791 DT_SUBTABLE *Subtable; 1792 DT_SUBTABLE *ParentTable; 1793 DT_FIELD **PFieldList = (DT_FIELD **) List; 1794 DT_FIELD *SubtableStart; 1795 ACPI_SUBTABLE_HEADER *GtdtHeader; 1796 ACPI_DMTABLE_INFO *InfoTable; 1797 UINT32 GtCount; 1798 ACPI_TABLE_HEADER *Header; 1799 1800 1801 ParentTable = DtPeekSubtable (); 1802 1803 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1804 1805 /* Compile the main table */ 1806 1807 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 1808 &Subtable); 1809 if (ACPI_FAILURE (Status)) 1810 { 1811 return (Status); 1812 } 1813 1814 /* GTDT revision 3 later contains 2 extra fields before subtables */ 1815 1816 if (Header->Revision > 2) 1817 { 1818 ParentTable = DtPeekSubtable (); 1819 DtInsertSubtable (ParentTable, Subtable); 1820 1821 Status = DtCompileTable (PFieldList, 1822 AcpiDmTableInfoGtdtEl2, &Subtable); 1823 if (ACPI_FAILURE (Status)) 1824 { 1825 return (Status); 1826 } 1827 } 1828 1829 ParentTable = DtPeekSubtable (); 1830 DtInsertSubtable (ParentTable, Subtable); 1831 1832 while (*PFieldList) 1833 { 1834 SubtableStart = *PFieldList; 1835 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 1836 &Subtable); 1837 if (ACPI_FAILURE (Status)) 1838 { 1839 return (Status); 1840 } 1841 1842 ParentTable = DtPeekSubtable (); 1843 DtInsertSubtable (ParentTable, Subtable); 1844 DtPushSubtable (Subtable); 1845 1846 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1847 1848 switch (GtdtHeader->Type) 1849 { 1850 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1851 1852 InfoTable = AcpiDmTableInfoGtdt0; 1853 break; 1854 1855 case ACPI_GTDT_TYPE_WATCHDOG: 1856 1857 InfoTable = AcpiDmTableInfoGtdt1; 1858 break; 1859 1860 default: 1861 1862 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 1863 return (AE_ERROR); 1864 } 1865 1866 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1867 if (ACPI_FAILURE (Status)) 1868 { 1869 return (Status); 1870 } 1871 1872 ParentTable = DtPeekSubtable (); 1873 DtInsertSubtable (ParentTable, Subtable); 1874 1875 /* 1876 * Additional GT block subtable data 1877 */ 1878 1879 switch (GtdtHeader->Type) 1880 { 1881 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1882 1883 DtPushSubtable (Subtable); 1884 ParentTable = DtPeekSubtable (); 1885 1886 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 1887 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 1888 1889 while (GtCount) 1890 { 1891 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 1892 &Subtable); 1893 if (ACPI_FAILURE (Status)) 1894 { 1895 return (Status); 1896 } 1897 1898 DtInsertSubtable (ParentTable, Subtable); 1899 GtCount--; 1900 } 1901 1902 DtPopSubtable (); 1903 break; 1904 1905 default: 1906 1907 break; 1908 } 1909 1910 DtPopSubtable (); 1911 } 1912 1913 return (AE_OK); 1914 } 1915 1916 1917 /****************************************************************************** 1918 * 1919 * FUNCTION: DtCompileFpdt 1920 * 1921 * PARAMETERS: List - Current field list pointer 1922 * 1923 * RETURN: Status 1924 * 1925 * DESCRIPTION: Compile FPDT. 1926 * 1927 *****************************************************************************/ 1928 1929 ACPI_STATUS 1930 DtCompileFpdt ( 1931 void **List) 1932 { 1933 ACPI_STATUS Status; 1934 ACPI_FPDT_HEADER *FpdtHeader; 1935 DT_SUBTABLE *Subtable; 1936 DT_SUBTABLE *ParentTable; 1937 ACPI_DMTABLE_INFO *InfoTable; 1938 DT_FIELD **PFieldList = (DT_FIELD **) List; 1939 DT_FIELD *SubtableStart; 1940 1941 1942 while (*PFieldList) 1943 { 1944 SubtableStart = *PFieldList; 1945 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1946 &Subtable); 1947 if (ACPI_FAILURE (Status)) 1948 { 1949 return (Status); 1950 } 1951 1952 ParentTable = DtPeekSubtable (); 1953 DtInsertSubtable (ParentTable, Subtable); 1954 DtPushSubtable (Subtable); 1955 1956 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1957 1958 switch (FpdtHeader->Type) 1959 { 1960 case ACPI_FPDT_TYPE_BOOT: 1961 1962 InfoTable = AcpiDmTableInfoFpdt0; 1963 break; 1964 1965 case ACPI_FPDT_TYPE_S3PERF: 1966 1967 InfoTable = AcpiDmTableInfoFpdt1; 1968 break; 1969 1970 default: 1971 1972 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1973 return (AE_ERROR); 1974 break; 1975 } 1976 1977 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1978 if (ACPI_FAILURE (Status)) 1979 { 1980 return (Status); 1981 } 1982 1983 ParentTable = DtPeekSubtable (); 1984 DtInsertSubtable (ParentTable, Subtable); 1985 DtPopSubtable (); 1986 } 1987 1988 return (AE_OK); 1989 } 1990 1991 1992 /****************************************************************************** 1993 * 1994 * FUNCTION: DtCompileHest 1995 * 1996 * PARAMETERS: List - Current field list pointer 1997 * 1998 * RETURN: Status 1999 * 2000 * DESCRIPTION: Compile HEST. 2001 * 2002 *****************************************************************************/ 2003 2004 ACPI_STATUS 2005 DtCompileHest ( 2006 void **List) 2007 { 2008 ACPI_STATUS Status; 2009 DT_SUBTABLE *Subtable; 2010 DT_SUBTABLE *ParentTable; 2011 DT_FIELD **PFieldList = (DT_FIELD **) List; 2012 DT_FIELD *SubtableStart; 2013 ACPI_DMTABLE_INFO *InfoTable; 2014 UINT16 Type; 2015 UINT32 BankCount; 2016 2017 2018 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 2019 &Subtable); 2020 if (ACPI_FAILURE (Status)) 2021 { 2022 return (Status); 2023 } 2024 2025 ParentTable = DtPeekSubtable (); 2026 DtInsertSubtable (ParentTable, Subtable); 2027 2028 while (*PFieldList) 2029 { 2030 /* Get subtable type */ 2031 2032 SubtableStart = *PFieldList; 2033 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 2034 2035 switch (Type) 2036 { 2037 case ACPI_HEST_TYPE_IA32_CHECK: 2038 2039 InfoTable = AcpiDmTableInfoHest0; 2040 break; 2041 2042 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 2043 2044 InfoTable = AcpiDmTableInfoHest1; 2045 break; 2046 2047 case ACPI_HEST_TYPE_IA32_NMI: 2048 2049 InfoTable = AcpiDmTableInfoHest2; 2050 break; 2051 2052 case ACPI_HEST_TYPE_AER_ROOT_PORT: 2053 2054 InfoTable = AcpiDmTableInfoHest6; 2055 break; 2056 2057 case ACPI_HEST_TYPE_AER_ENDPOINT: 2058 2059 InfoTable = AcpiDmTableInfoHest7; 2060 break; 2061 2062 case ACPI_HEST_TYPE_AER_BRIDGE: 2063 2064 InfoTable = AcpiDmTableInfoHest8; 2065 break; 2066 2067 case ACPI_HEST_TYPE_GENERIC_ERROR: 2068 2069 InfoTable = AcpiDmTableInfoHest9; 2070 break; 2071 2072 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 2073 2074 InfoTable = AcpiDmTableInfoHest10; 2075 break; 2076 2077 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 2078 2079 InfoTable = AcpiDmTableInfoHest11; 2080 break; 2081 2082 default: 2083 2084 /* Cannot continue on unknown type */ 2085 2086 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 2087 return (AE_ERROR); 2088 } 2089 2090 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2091 if (ACPI_FAILURE (Status)) 2092 { 2093 return (Status); 2094 } 2095 2096 DtInsertSubtable (ParentTable, Subtable); 2097 2098 /* 2099 * Additional subtable data - IA32 Error Bank(s) 2100 */ 2101 BankCount = 0; 2102 switch (Type) 2103 { 2104 case ACPI_HEST_TYPE_IA32_CHECK: 2105 2106 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 2107 Subtable->Buffer))->NumHardwareBanks; 2108 break; 2109 2110 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 2111 2112 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 2113 Subtable->Buffer))->NumHardwareBanks; 2114 break; 2115 2116 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 2117 2118 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 2119 Subtable->Buffer))->NumHardwareBanks; 2120 break; 2121 2122 default: 2123 2124 break; 2125 } 2126 2127 while (BankCount) 2128 { 2129 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 2130 &Subtable); 2131 if (ACPI_FAILURE (Status)) 2132 { 2133 return (Status); 2134 } 2135 2136 DtInsertSubtable (ParentTable, Subtable); 2137 BankCount--; 2138 } 2139 } 2140 2141 return (AE_OK); 2142 } 2143 2144 2145 /****************************************************************************** 2146 * 2147 * FUNCTION: DtCompileHmat 2148 * 2149 * PARAMETERS: List - Current field list pointer 2150 * 2151 * RETURN: Status 2152 * 2153 * DESCRIPTION: Compile HMAT. 2154 * 2155 *****************************************************************************/ 2156 2157 ACPI_STATUS 2158 DtCompileHmat ( 2159 void **List) 2160 { 2161 ACPI_STATUS Status; 2162 DT_SUBTABLE *Subtable; 2163 DT_SUBTABLE *ParentTable; 2164 DT_FIELD **PFieldList = (DT_FIELD **) List; 2165 DT_FIELD *SubtableStart; 2166 DT_FIELD *EntryStart; 2167 ACPI_HMAT_STRUCTURE *HmatStruct; 2168 ACPI_HMAT_LOCALITY *HmatLocality; 2169 ACPI_HMAT_CACHE *HmatCache; 2170 ACPI_DMTABLE_INFO *InfoTable; 2171 UINT32 IntPDNumber; 2172 UINT32 TgtPDNumber; 2173 UINT64 EntryNumber; 2174 UINT16 SMBIOSHandleNumber; 2175 2176 2177 ParentTable = DtPeekSubtable (); 2178 2179 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 2180 &Subtable); 2181 if (ACPI_FAILURE (Status)) 2182 { 2183 return (Status); 2184 } 2185 DtInsertSubtable (ParentTable, Subtable); 2186 2187 while (*PFieldList) 2188 { 2189 /* Compile HMAT structure header */ 2190 2191 SubtableStart = *PFieldList; 2192 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 2193 &Subtable); 2194 if (ACPI_FAILURE (Status)) 2195 { 2196 return (Status); 2197 } 2198 DtInsertSubtable (ParentTable, Subtable); 2199 2200 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 2201 HmatStruct->Length = Subtable->Length; 2202 2203 /* Compile HMAT structure body */ 2204 2205 switch (HmatStruct->Type) 2206 { 2207 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 2208 2209 InfoTable = AcpiDmTableInfoHmat0; 2210 break; 2211 2212 case ACPI_HMAT_TYPE_LOCALITY: 2213 2214 InfoTable = AcpiDmTableInfoHmat1; 2215 break; 2216 2217 case ACPI_HMAT_TYPE_CACHE: 2218 2219 InfoTable = AcpiDmTableInfoHmat2; 2220 break; 2221 2222 default: 2223 2224 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 2225 return (AE_ERROR); 2226 } 2227 2228 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2229 if (ACPI_FAILURE (Status)) 2230 { 2231 return (Status); 2232 } 2233 DtInsertSubtable (ParentTable, Subtable); 2234 HmatStruct->Length += Subtable->Length; 2235 2236 /* Compile HMAT structure additional */ 2237 2238 switch (HmatStruct->Type) 2239 { 2240 case ACPI_HMAT_TYPE_LOCALITY: 2241 2242 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 2243 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 2244 2245 /* Compile initiator proximity domain list */ 2246 2247 IntPDNumber = 0; 2248 while (*PFieldList) 2249 { 2250 Status = DtCompileTable (PFieldList, 2251 AcpiDmTableInfoHmat1a, &Subtable); 2252 if (ACPI_FAILURE (Status)) 2253 { 2254 return (Status); 2255 } 2256 if (!Subtable) 2257 { 2258 break; 2259 } 2260 DtInsertSubtable (ParentTable, Subtable); 2261 HmatStruct->Length += Subtable->Length; 2262 IntPDNumber++; 2263 } 2264 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 2265 2266 /* Compile target proximity domain list */ 2267 2268 TgtPDNumber = 0; 2269 while (*PFieldList) 2270 { 2271 Status = DtCompileTable (PFieldList, 2272 AcpiDmTableInfoHmat1b, &Subtable); 2273 if (ACPI_FAILURE (Status)) 2274 { 2275 return (Status); 2276 } 2277 if (!Subtable) 2278 { 2279 break; 2280 } 2281 DtInsertSubtable (ParentTable, Subtable); 2282 HmatStruct->Length += Subtable->Length; 2283 TgtPDNumber++; 2284 } 2285 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 2286 2287 /* Save start of the entries for reporting errors */ 2288 2289 EntryStart = *PFieldList; 2290 2291 /* Compile latency/bandwidth entries */ 2292 2293 EntryNumber = 0; 2294 while (*PFieldList) 2295 { 2296 Status = DtCompileTable (PFieldList, 2297 AcpiDmTableInfoHmat1c, &Subtable); 2298 if (ACPI_FAILURE (Status)) 2299 { 2300 return (Status); 2301 } 2302 if (!Subtable) 2303 { 2304 break; 2305 } 2306 DtInsertSubtable (ParentTable, Subtable); 2307 HmatStruct->Length += Subtable->Length; 2308 EntryNumber++; 2309 } 2310 2311 /* Validate number of entries */ 2312 2313 if (EntryNumber != 2314 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 2315 { 2316 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 2317 return (AE_ERROR); 2318 } 2319 break; 2320 2321 case ACPI_HMAT_TYPE_CACHE: 2322 2323 /* Compile SMBIOS handles */ 2324 2325 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 2326 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 2327 SMBIOSHandleNumber = 0; 2328 while (*PFieldList) 2329 { 2330 Status = DtCompileTable (PFieldList, 2331 AcpiDmTableInfoHmat2a, &Subtable); 2332 if (ACPI_FAILURE (Status)) 2333 { 2334 return (Status); 2335 } 2336 if (!Subtable) 2337 { 2338 break; 2339 } 2340 DtInsertSubtable (ParentTable, Subtable); 2341 HmatStruct->Length += Subtable->Length; 2342 SMBIOSHandleNumber++; 2343 } 2344 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 2345 break; 2346 2347 default: 2348 2349 break; 2350 } 2351 } 2352 2353 return (AE_OK); 2354 } 2355 2356 2357 /****************************************************************************** 2358 * 2359 * FUNCTION: DtCompileIort 2360 * 2361 * PARAMETERS: List - Current field list pointer 2362 * 2363 * RETURN: Status 2364 * 2365 * DESCRIPTION: Compile IORT. 2366 * 2367 *****************************************************************************/ 2368 2369 ACPI_STATUS 2370 DtCompileIort ( 2371 void **List) 2372 { 2373 ACPI_STATUS Status; 2374 DT_SUBTABLE *Subtable; 2375 DT_SUBTABLE *ParentTable; 2376 DT_FIELD **PFieldList = (DT_FIELD **) List; 2377 DT_FIELD *SubtableStart; 2378 ACPI_TABLE_HEADER *Table; 2379 ACPI_TABLE_IORT *Iort; 2380 ACPI_IORT_NODE *IortNode; 2381 ACPI_IORT_ITS_GROUP *IortItsGroup; 2382 ACPI_IORT_SMMU *IortSmmu; 2383 ACPI_IORT_RMR *IortRmr; 2384 UINT32 NodeNumber; 2385 UINT32 NodeLength; 2386 UINT32 IdMappingNumber; 2387 UINT32 ItsNumber; 2388 UINT32 ContextIrptNumber; 2389 UINT32 PmuIrptNumber; 2390 UINT32 PaddingLength; 2391 UINT8 Revision; 2392 UINT32 RmrCount; 2393 2394 2395 ParentTable = DtPeekSubtable (); 2396 2397 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 2398 &Subtable); 2399 if (ACPI_FAILURE (Status)) 2400 { 2401 return (Status); 2402 } 2403 DtInsertSubtable (ParentTable, Subtable); 2404 2405 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2406 Revision = Table->Revision; 2407 2408 /* IORT Revisions E, E.a & E.c have known issues and are not supported */ 2409 2410 if (Revision == 1 || Revision == 2 || Revision == 4) 2411 { 2412 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision"); 2413 return (AE_ERROR); 2414 } 2415 2416 /* 2417 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 2418 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 2419 */ 2420 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 2421 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 2422 2423 /* 2424 * OptionalPadding - Variable-length data 2425 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 2426 * Optionally allows the generic data types to be used for filling 2427 * this field. 2428 */ 2429 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 2430 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 2431 &Subtable); 2432 if (ACPI_FAILURE (Status)) 2433 { 2434 return (Status); 2435 } 2436 if (Subtable) 2437 { 2438 DtInsertSubtable (ParentTable, Subtable); 2439 Iort->NodeOffset += Subtable->Length; 2440 } 2441 else 2442 { 2443 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 2444 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 2445 if (ACPI_FAILURE (Status)) 2446 { 2447 return (Status); 2448 } 2449 Iort->NodeOffset += PaddingLength; 2450 } 2451 2452 NodeNumber = 0; 2453 while (*PFieldList) 2454 { 2455 SubtableStart = *PFieldList; 2456 if (Revision == 0) 2457 { 2458 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 2459 &Subtable); 2460 } 2461 else if (Revision >= 3) 2462 { 2463 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3, 2464 &Subtable); 2465 } 2466 2467 if (ACPI_FAILURE (Status)) 2468 { 2469 return (Status); 2470 } 2471 2472 DtInsertSubtable (ParentTable, Subtable); 2473 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 2474 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 2475 2476 DtPushSubtable (Subtable); 2477 ParentTable = DtPeekSubtable (); 2478 2479 switch (IortNode->Type) 2480 { 2481 case ACPI_IORT_NODE_ITS_GROUP: 2482 2483 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 2484 &Subtable); 2485 if (ACPI_FAILURE (Status)) 2486 { 2487 return (Status); 2488 } 2489 2490 DtInsertSubtable (ParentTable, Subtable); 2491 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 2492 NodeLength += Subtable->Length; 2493 2494 ItsNumber = 0; 2495 while (*PFieldList) 2496 { 2497 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 2498 &Subtable); 2499 if (ACPI_FAILURE (Status)) 2500 { 2501 return (Status); 2502 } 2503 if (!Subtable) 2504 { 2505 break; 2506 } 2507 2508 DtInsertSubtable (ParentTable, Subtable); 2509 NodeLength += Subtable->Length; 2510 ItsNumber++; 2511 } 2512 2513 IortItsGroup->ItsCount = ItsNumber; 2514 break; 2515 2516 case ACPI_IORT_NODE_NAMED_COMPONENT: 2517 2518 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 2519 &Subtable); 2520 if (ACPI_FAILURE (Status)) 2521 { 2522 return (Status); 2523 } 2524 2525 DtInsertSubtable (ParentTable, Subtable); 2526 NodeLength += Subtable->Length; 2527 2528 /* 2529 * Padding - Variable-length data 2530 * Optionally allows the offset of the ID mappings to be used 2531 * for filling this field. 2532 */ 2533 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 2534 &Subtable); 2535 if (ACPI_FAILURE (Status)) 2536 { 2537 return (Status); 2538 } 2539 2540 if (Subtable) 2541 { 2542 DtInsertSubtable (ParentTable, Subtable); 2543 NodeLength += Subtable->Length; 2544 } 2545 else 2546 { 2547 if (NodeLength > IortNode->MappingOffset) 2548 { 2549 return (AE_BAD_DATA); 2550 } 2551 2552 if (NodeLength < IortNode->MappingOffset) 2553 { 2554 Status = DtCompilePadding ( 2555 IortNode->MappingOffset - NodeLength, 2556 &Subtable); 2557 if (ACPI_FAILURE (Status)) 2558 { 2559 return (Status); 2560 } 2561 2562 DtInsertSubtable (ParentTable, Subtable); 2563 NodeLength = IortNode->MappingOffset; 2564 } 2565 } 2566 break; 2567 2568 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 2569 2570 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 2571 &Subtable); 2572 if (ACPI_FAILURE (Status)) 2573 { 2574 return (Status); 2575 } 2576 2577 DtInsertSubtable (ParentTable, Subtable); 2578 NodeLength += Subtable->Length; 2579 break; 2580 2581 case ACPI_IORT_NODE_SMMU: 2582 2583 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 2584 &Subtable); 2585 if (ACPI_FAILURE (Status)) 2586 { 2587 return (Status); 2588 } 2589 2590 DtInsertSubtable (ParentTable, Subtable); 2591 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 2592 NodeLength += Subtable->Length; 2593 2594 /* Compile global interrupt array */ 2595 2596 IortSmmu->GlobalInterruptOffset = NodeLength; 2597 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 2598 &Subtable); 2599 if (ACPI_FAILURE (Status)) 2600 { 2601 return (Status); 2602 } 2603 2604 DtInsertSubtable (ParentTable, Subtable); 2605 NodeLength += Subtable->Length; 2606 2607 /* Compile context interrupt array */ 2608 2609 ContextIrptNumber = 0; 2610 IortSmmu->ContextInterruptOffset = NodeLength; 2611 while (*PFieldList) 2612 { 2613 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 2614 &Subtable); 2615 if (ACPI_FAILURE (Status)) 2616 { 2617 return (Status); 2618 } 2619 2620 if (!Subtable) 2621 { 2622 break; 2623 } 2624 2625 DtInsertSubtable (ParentTable, Subtable); 2626 NodeLength += Subtable->Length; 2627 ContextIrptNumber++; 2628 } 2629 2630 IortSmmu->ContextInterruptCount = ContextIrptNumber; 2631 2632 /* Compile PMU interrupt array */ 2633 2634 PmuIrptNumber = 0; 2635 IortSmmu->PmuInterruptOffset = NodeLength; 2636 while (*PFieldList) 2637 { 2638 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 2639 &Subtable); 2640 if (ACPI_FAILURE (Status)) 2641 { 2642 return (Status); 2643 } 2644 2645 if (!Subtable) 2646 { 2647 break; 2648 } 2649 2650 DtInsertSubtable (ParentTable, Subtable); 2651 NodeLength += Subtable->Length; 2652 PmuIrptNumber++; 2653 } 2654 2655 IortSmmu->PmuInterruptCount = PmuIrptNumber; 2656 break; 2657 2658 case ACPI_IORT_NODE_SMMU_V3: 2659 2660 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 2661 &Subtable); 2662 if (ACPI_FAILURE (Status)) 2663 { 2664 return (Status); 2665 } 2666 2667 DtInsertSubtable (ParentTable, Subtable); 2668 NodeLength += Subtable->Length; 2669 break; 2670 2671 case ACPI_IORT_NODE_PMCG: 2672 2673 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5, 2674 &Subtable); 2675 if (ACPI_FAILURE (Status)) 2676 { 2677 return (Status); 2678 } 2679 2680 DtInsertSubtable (ParentTable, Subtable); 2681 NodeLength += Subtable->Length; 2682 break; 2683 2684 case ACPI_IORT_NODE_RMR: 2685 2686 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6, 2687 &Subtable); 2688 if (ACPI_FAILURE (Status)) 2689 { 2690 return (Status); 2691 } 2692 2693 DtInsertSubtable (ParentTable, Subtable); 2694 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer); 2695 NodeLength += Subtable->Length; 2696 2697 /* Compile RMR Descriptors */ 2698 2699 RmrCount = 0; 2700 IortRmr->RmrOffset = NodeLength; 2701 while (*PFieldList) 2702 { 2703 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a, 2704 &Subtable); 2705 if (ACPI_FAILURE (Status)) 2706 { 2707 return (Status); 2708 } 2709 2710 if (!Subtable) 2711 { 2712 break; 2713 } 2714 2715 DtInsertSubtable (ParentTable, Subtable); 2716 NodeLength += sizeof (ACPI_IORT_RMR_DESC); 2717 RmrCount++; 2718 } 2719 2720 IortRmr->RmrCount = RmrCount; 2721 break; 2722 2723 default: 2724 2725 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 2726 return (AE_ERROR); 2727 } 2728 2729 /* Compile Array of ID mappings */ 2730 2731 IortNode->MappingOffset = NodeLength; 2732 IdMappingNumber = 0; 2733 while (*PFieldList) 2734 { 2735 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 2736 &Subtable); 2737 if (ACPI_FAILURE (Status)) 2738 { 2739 return (Status); 2740 } 2741 2742 if (!Subtable) 2743 { 2744 break; 2745 } 2746 2747 DtInsertSubtable (ParentTable, Subtable); 2748 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 2749 IdMappingNumber++; 2750 } 2751 2752 IortNode->MappingCount = IdMappingNumber; 2753 if (!IdMappingNumber) 2754 { 2755 IortNode->MappingOffset = 0; 2756 } 2757 2758 /* 2759 * Node length can be determined by DT_LENGTH option 2760 * IortNode->Length = NodeLength; 2761 */ 2762 DtPopSubtable (); 2763 ParentTable = DtPeekSubtable (); 2764 NodeNumber++; 2765 } 2766 2767 Iort->NodeCount = NodeNumber; 2768 return (AE_OK); 2769 } 2770 2771 2772 /****************************************************************************** 2773 * 2774 * FUNCTION: DtCompileIvrs 2775 * 2776 * PARAMETERS: List - Current field list pointer 2777 * 2778 * RETURN: Status 2779 * 2780 * DESCRIPTION: Compile IVRS. Notes: 2781 * The IVRS is essentially a flat table, with the following 2782 * structure: 2783 * <Main ACPI Table Header> 2784 * <Main subtable - virtualization info> 2785 * <IVHD> 2786 * <Device Entries> 2787 * ... 2788 * <IVHD> 2789 * <Device Entries> 2790 * <IVMD> 2791 * ... 2792 * 2793 *****************************************************************************/ 2794 2795 ACPI_STATUS 2796 DtCompileIvrs ( 2797 void **List) 2798 { 2799 ACPI_STATUS Status; 2800 DT_SUBTABLE *Subtable; 2801 DT_SUBTABLE *ParentTable; 2802 DT_SUBTABLE *MainSubtable; 2803 DT_FIELD **PFieldList = (DT_FIELD **) List; 2804 DT_FIELD *SubtableStart; 2805 ACPI_DMTABLE_INFO *InfoTable = NULL; 2806 UINT8 SubtableType; 2807 UINT8 Temp64[16]; 2808 UINT8 Temp8; 2809 2810 2811 /* Main table */ 2812 2813 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 2814 &Subtable); 2815 if (ACPI_FAILURE (Status)) 2816 { 2817 return (Status); 2818 } 2819 2820 ParentTable = DtPeekSubtable (); 2821 DtInsertSubtable (ParentTable, Subtable); 2822 DtPushSubtable (Subtable); 2823 2824 /* Save a pointer to the main subtable */ 2825 2826 MainSubtable = Subtable; 2827 2828 while (*PFieldList) 2829 { 2830 SubtableStart = *PFieldList; 2831 2832 /* Compile the SubtableType integer */ 2833 2834 DtCompileInteger (&SubtableType, *PFieldList, 1, 0); 2835 2836 switch (SubtableType) 2837 { 2838 2839 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */ 2840 2841 case ACPI_IVRS_TYPE_HARDWARE1: 2842 2843 InfoTable = AcpiDmTableInfoIvrsHware1; 2844 break; 2845 2846 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */ 2847 2848 case ACPI_IVRS_TYPE_HARDWARE2: 2849 case ACPI_IVRS_TYPE_HARDWARE3: 2850 2851 InfoTable = AcpiDmTableInfoIvrsHware23; 2852 break; 2853 2854 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */ 2855 2856 case ACPI_IVRS_TYPE_MEMORY1: 2857 case ACPI_IVRS_TYPE_MEMORY2: 2858 case ACPI_IVRS_TYPE_MEMORY3: 2859 2860 InfoTable = AcpiDmTableInfoIvrsMemory; 2861 break; 2862 2863 /* 4-byte device entries */ 2864 2865 case ACPI_IVRS_TYPE_PAD4: 2866 case ACPI_IVRS_TYPE_ALL: 2867 case ACPI_IVRS_TYPE_SELECT: 2868 case ACPI_IVRS_TYPE_START: 2869 case ACPI_IVRS_TYPE_END: 2870 2871 InfoTable = AcpiDmTableInfoIvrs4; 2872 break; 2873 2874 /* 8-byte device entries, type A */ 2875 2876 case ACPI_IVRS_TYPE_ALIAS_SELECT: 2877 case ACPI_IVRS_TYPE_ALIAS_START: 2878 2879 InfoTable = AcpiDmTableInfoIvrs8a; 2880 break; 2881 2882 /* 8-byte device entries, type B */ 2883 2884 case ACPI_IVRS_TYPE_EXT_SELECT: 2885 case ACPI_IVRS_TYPE_EXT_START: 2886 2887 InfoTable = AcpiDmTableInfoIvrs8b; 2888 break; 2889 2890 /* 8-byte device entries, type C */ 2891 2892 case ACPI_IVRS_TYPE_SPECIAL: 2893 2894 InfoTable = AcpiDmTableInfoIvrs8c; 2895 break; 2896 2897 /* Variable device entries, type F0h */ 2898 2899 case ACPI_IVRS_TYPE_HID: 2900 2901 InfoTable = AcpiDmTableInfoIvrsHid; 2902 break; 2903 2904 default: 2905 2906 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 2907 "IVRS Device Entry"); 2908 return (AE_ERROR); 2909 } 2910 2911 /* Compile the InfoTable from above */ 2912 2913 Status = DtCompileTable (PFieldList, InfoTable, 2914 &Subtable); 2915 if (ACPI_FAILURE (Status)) 2916 { 2917 return (Status); 2918 } 2919 2920 ParentTable = DtPeekSubtable (); 2921 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 && 2922 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 && 2923 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 && 2924 SubtableType != ACPI_IVRS_TYPE_HID && 2925 SubtableType != ACPI_IVRS_TYPE_MEMORY1 && 2926 SubtableType != ACPI_IVRS_TYPE_MEMORY2 && 2927 SubtableType != ACPI_IVRS_TYPE_MEMORY3) 2928 { 2929 if (ParentTable) 2930 DtInsertSubtable (ParentTable, Subtable); 2931 } 2932 2933 switch (SubtableType) 2934 { 2935 case ACPI_IVRS_TYPE_HARDWARE1: 2936 case ACPI_IVRS_TYPE_HARDWARE2: 2937 case ACPI_IVRS_TYPE_HARDWARE3: 2938 case ACPI_IVRS_TYPE_MEMORY1: 2939 case ACPI_IVRS_TYPE_MEMORY2: 2940 case ACPI_IVRS_TYPE_MEMORY3: 2941 2942 /* Insert these IVHDs/IVMDs at the root subtable */ 2943 2944 DtInsertSubtable (MainSubtable, Subtable); 2945 DtPushSubtable (Subtable); 2946 break; 2947 2948 case ACPI_IVRS_TYPE_HID: 2949 2950 /* Special handling for the HID named device entry (0xF0) */ 2951 2952 if (ParentTable) 2953 { 2954 DtInsertSubtable (ParentTable, Subtable); 2955 } 2956 2957 /* 2958 * Process the HID value. First, get the HID value as a string. 2959 */ 2960 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 2961 2962 /* 2963 * Determine if the HID is an integer or a string. 2964 * An integer is defined to be 32 bits, with the upper 32 bits 2965 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit 2966 * integer or a character string. If an integer, the lower 2967 * 4 bytes of the field contain the integer and the upper 2968 * 4 bytes are padded with 0". 2969 */ 2970 if (UtIsIdInteger ((UINT8 *) &Temp64)) 2971 { 2972 /* Compile the HID value as an integer */ 2973 2974 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 2975 2976 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger, 2977 &Subtable); 2978 if (ACPI_FAILURE (Status)) 2979 { 2980 return (Status); 2981 } 2982 } 2983 else 2984 { 2985 /* Compile the HID value as a string */ 2986 2987 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString, 2988 &Subtable); 2989 if (ACPI_FAILURE (Status)) 2990 { 2991 return (Status); 2992 } 2993 } 2994 2995 DtInsertSubtable (ParentTable, Subtable); 2996 2997 /* 2998 * Process the CID value. First, get the CID value as a string. 2999 */ 3000 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0); 3001 3002 if (UtIsIdInteger ((UINT8 *) &Temp64)) 3003 { 3004 /* Compile the CID value as an integer */ 3005 3006 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0); 3007 3008 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger, 3009 &Subtable); 3010 if (ACPI_FAILURE (Status)) 3011 { 3012 return (Status); 3013 } 3014 } 3015 else 3016 { 3017 /* Compile the CID value as a string */ 3018 3019 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString, 3020 &Subtable); 3021 if (ACPI_FAILURE (Status)) 3022 { 3023 return (Status); 3024 } 3025 } 3026 3027 DtInsertSubtable (ParentTable, Subtable); 3028 3029 /* 3030 * Process the UID value. First, get and decode the "UID Format" field (Integer). 3031 */ 3032 if (!*PFieldList) 3033 { 3034 return (AE_OK); 3035 } 3036 3037 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0); 3038 3039 switch (Temp8) 3040 { 3041 case ACPI_IVRS_UID_NOT_PRESENT: 3042 break; 3043 3044 case ACPI_IVRS_UID_IS_INTEGER: 3045 3046 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger, 3047 &Subtable); 3048 if (ACPI_FAILURE (Status)) 3049 { 3050 return (Status); 3051 } 3052 DtInsertSubtable (ParentTable, Subtable); 3053 break; 3054 3055 case ACPI_IVRS_UID_IS_STRING: 3056 3057 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString, 3058 &Subtable); 3059 if (ACPI_FAILURE (Status)) 3060 { 3061 return (Status); 3062 } 3063 DtInsertSubtable (ParentTable, Subtable); 3064 break; 3065 3066 default: 3067 3068 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart, 3069 "IVRS Device Entry"); 3070 return (AE_ERROR); 3071 } 3072 3073 default: 3074 3075 /* All other subtable types come through here */ 3076 break; 3077 } 3078 } 3079 3080 return (AE_OK); 3081 } 3082