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