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 - 2017, 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 #include <contrib/dev/acpica/compiler/dtcompiler.h> 156 157 #define _COMPONENT DT_COMPILER 158 ACPI_MODULE_NAME ("dttable1") 159 160 161 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] = 162 { 163 {ACPI_DMT_BUFFER, 0, "Addresses", 0}, 164 {ACPI_DMT_EXIT, 0, NULL, 0} 165 }; 166 167 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] = 168 { 169 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0}, 170 {ACPI_DMT_EXIT, 0, NULL, 0} 171 }; 172 173 174 /****************************************************************************** 175 * 176 * FUNCTION: DtCompileAsf 177 * 178 * PARAMETERS: List - Current field list pointer 179 * 180 * RETURN: Status 181 * 182 * DESCRIPTION: Compile ASF!. 183 * 184 *****************************************************************************/ 185 186 ACPI_STATUS 187 DtCompileAsf ( 188 void **List) 189 { 190 ACPI_ASF_INFO *AsfTable; 191 DT_SUBTABLE *Subtable; 192 DT_SUBTABLE *ParentTable; 193 ACPI_DMTABLE_INFO *InfoTable; 194 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 195 UINT32 DataCount = 0; 196 ACPI_STATUS Status; 197 UINT32 i; 198 DT_FIELD **PFieldList = (DT_FIELD **) List; 199 DT_FIELD *SubtableStart; 200 201 202 while (*PFieldList) 203 { 204 SubtableStart = *PFieldList; 205 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 206 &Subtable, TRUE); 207 if (ACPI_FAILURE (Status)) 208 { 209 return (Status); 210 } 211 212 ParentTable = DtPeekSubtable (); 213 DtInsertSubtable (ParentTable, Subtable); 214 DtPushSubtable (Subtable); 215 216 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 217 218 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 219 { 220 case ACPI_ASF_TYPE_INFO: 221 222 InfoTable = AcpiDmTableInfoAsf0; 223 break; 224 225 case ACPI_ASF_TYPE_ALERT: 226 227 InfoTable = AcpiDmTableInfoAsf1; 228 break; 229 230 case ACPI_ASF_TYPE_CONTROL: 231 232 InfoTable = AcpiDmTableInfoAsf2; 233 break; 234 235 case ACPI_ASF_TYPE_BOOT: 236 237 InfoTable = AcpiDmTableInfoAsf3; 238 break; 239 240 case ACPI_ASF_TYPE_ADDRESS: 241 242 InfoTable = AcpiDmTableInfoAsf4; 243 break; 244 245 default: 246 247 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 248 return (AE_ERROR); 249 } 250 251 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 252 if (ACPI_FAILURE (Status)) 253 { 254 return (Status); 255 } 256 257 ParentTable = DtPeekSubtable (); 258 DtInsertSubtable (ParentTable, Subtable); 259 260 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 261 { 262 case ACPI_ASF_TYPE_INFO: 263 264 DataInfoTable = NULL; 265 break; 266 267 case ACPI_ASF_TYPE_ALERT: 268 269 DataInfoTable = AcpiDmTableInfoAsf1a; 270 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 271 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 272 sizeof (ACPI_ASF_HEADER)))->Alerts; 273 break; 274 275 case ACPI_ASF_TYPE_CONTROL: 276 277 DataInfoTable = AcpiDmTableInfoAsf2a; 278 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 279 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 280 sizeof (ACPI_ASF_HEADER)))->Controls; 281 break; 282 283 case ACPI_ASF_TYPE_BOOT: 284 285 DataInfoTable = NULL; 286 break; 287 288 case ACPI_ASF_TYPE_ADDRESS: 289 290 DataInfoTable = TableInfoAsfAddress; 291 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 292 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 293 sizeof (ACPI_ASF_HEADER)))->Devices; 294 break; 295 296 default: 297 298 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 299 return (AE_ERROR); 300 } 301 302 if (DataInfoTable) 303 { 304 switch (AsfTable->Header.Type & 0x7F) 305 { 306 case ACPI_ASF_TYPE_ADDRESS: 307 308 while (DataCount > 0) 309 { 310 Status = DtCompileTable (PFieldList, DataInfoTable, 311 &Subtable, TRUE); 312 if (ACPI_FAILURE (Status)) 313 { 314 return (Status); 315 } 316 317 DtInsertSubtable (ParentTable, Subtable); 318 DataCount = DataCount - Subtable->Length; 319 } 320 break; 321 322 default: 323 324 for (i = 0; i < DataCount; i++) 325 { 326 Status = DtCompileTable (PFieldList, DataInfoTable, 327 &Subtable, TRUE); 328 if (ACPI_FAILURE (Status)) 329 { 330 return (Status); 331 } 332 333 DtInsertSubtable (ParentTable, Subtable); 334 } 335 break; 336 } 337 } 338 339 DtPopSubtable (); 340 } 341 342 return (AE_OK); 343 } 344 345 346 /****************************************************************************** 347 * 348 * FUNCTION: DtCompileCpep 349 * 350 * PARAMETERS: List - Current field list pointer 351 * 352 * RETURN: Status 353 * 354 * DESCRIPTION: Compile CPEP. 355 * 356 *****************************************************************************/ 357 358 ACPI_STATUS 359 DtCompileCpep ( 360 void **List) 361 { 362 ACPI_STATUS Status; 363 364 365 Status = DtCompileTwoSubtables (List, 366 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 367 return (Status); 368 } 369 370 371 /****************************************************************************** 372 * 373 * FUNCTION: DtCompileCsrt 374 * 375 * PARAMETERS: List - Current field list pointer 376 * 377 * RETURN: Status 378 * 379 * DESCRIPTION: Compile CSRT. 380 * 381 *****************************************************************************/ 382 383 ACPI_STATUS 384 DtCompileCsrt ( 385 void **List) 386 { 387 ACPI_STATUS Status = AE_OK; 388 DT_SUBTABLE *Subtable; 389 DT_SUBTABLE *ParentTable; 390 DT_FIELD **PFieldList = (DT_FIELD **) List; 391 UINT32 DescriptorCount; 392 UINT32 GroupLength; 393 394 395 /* Subtables (Resource Groups) */ 396 397 ParentTable = DtPeekSubtable (); 398 while (*PFieldList) 399 { 400 /* Resource group subtable */ 401 402 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 403 &Subtable, TRUE); 404 if (ACPI_FAILURE (Status)) 405 { 406 return (Status); 407 } 408 409 /* Compute the number of resource descriptors */ 410 411 GroupLength = 412 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 413 Subtable->Buffer))->Length - 414 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 415 Subtable->Buffer))->SharedInfoLength - 416 sizeof (ACPI_CSRT_GROUP); 417 418 DescriptorCount = (GroupLength / 419 sizeof (ACPI_CSRT_DESCRIPTOR)); 420 421 DtInsertSubtable (ParentTable, Subtable); 422 DtPushSubtable (Subtable); 423 ParentTable = DtPeekSubtable (); 424 425 /* Shared info subtable (One per resource group) */ 426 427 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 428 &Subtable, TRUE); 429 if (ACPI_FAILURE (Status)) 430 { 431 return (Status); 432 } 433 434 DtInsertSubtable (ParentTable, Subtable); 435 436 /* Sub-Subtables (Resource Descriptors) */ 437 438 while (*PFieldList && DescriptorCount) 439 { 440 441 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 442 &Subtable, TRUE); 443 if (ACPI_FAILURE (Status)) 444 { 445 return (Status); 446 } 447 448 DtInsertSubtable (ParentTable, Subtable); 449 450 DtPushSubtable (Subtable); 451 ParentTable = DtPeekSubtable (); 452 if (*PFieldList) 453 { 454 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 455 &Subtable, TRUE); 456 if (ACPI_FAILURE (Status)) 457 { 458 return (Status); 459 } 460 if (Subtable) 461 { 462 DtInsertSubtable (ParentTable, Subtable); 463 } 464 } 465 466 DtPopSubtable (); 467 ParentTable = DtPeekSubtable (); 468 DescriptorCount--; 469 } 470 471 DtPopSubtable (); 472 ParentTable = DtPeekSubtable (); 473 } 474 475 return (Status); 476 } 477 478 479 /****************************************************************************** 480 * 481 * FUNCTION: DtCompileDbg2 482 * 483 * PARAMETERS: List - Current field list pointer 484 * 485 * RETURN: Status 486 * 487 * DESCRIPTION: Compile DBG2. 488 * 489 *****************************************************************************/ 490 491 ACPI_STATUS 492 DtCompileDbg2 ( 493 void **List) 494 { 495 ACPI_STATUS Status; 496 DT_SUBTABLE *Subtable; 497 DT_SUBTABLE *ParentTable; 498 DT_FIELD **PFieldList = (DT_FIELD **) List; 499 UINT32 SubtableCount; 500 ACPI_DBG2_HEADER *Dbg2Header; 501 ACPI_DBG2_DEVICE *DeviceInfo; 502 UINT16 CurrentOffset; 503 UINT32 i; 504 505 506 /* Main table */ 507 508 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE); 509 if (ACPI_FAILURE (Status)) 510 { 511 return (Status); 512 } 513 514 ParentTable = DtPeekSubtable (); 515 DtInsertSubtable (ParentTable, Subtable); 516 517 /* Main table fields */ 518 519 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 520 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 521 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 522 523 SubtableCount = Dbg2Header->InfoCount; 524 DtPushSubtable (Subtable); 525 526 /* Process all Device Information subtables (Count = InfoCount) */ 527 528 while (*PFieldList && SubtableCount) 529 { 530 /* Subtable: Debug Device Information */ 531 532 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 533 &Subtable, TRUE); 534 if (ACPI_FAILURE (Status)) 535 { 536 return (Status); 537 } 538 539 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 540 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 541 542 ParentTable = DtPeekSubtable (); 543 DtInsertSubtable (ParentTable, Subtable); 544 DtPushSubtable (Subtable); 545 546 ParentTable = DtPeekSubtable (); 547 548 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 549 550 DeviceInfo->BaseAddressOffset = CurrentOffset; 551 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 552 { 553 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 554 &Subtable, TRUE); 555 if (ACPI_FAILURE (Status)) 556 { 557 return (Status); 558 } 559 560 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 561 DtInsertSubtable (ParentTable, Subtable); 562 } 563 564 /* AddressSize array (Required, size = RegisterCount) */ 565 566 DeviceInfo->AddressSizeOffset = CurrentOffset; 567 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 568 { 569 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 570 &Subtable, TRUE); 571 if (ACPI_FAILURE (Status)) 572 { 573 return (Status); 574 } 575 576 CurrentOffset += (UINT16) sizeof (UINT32); 577 DtInsertSubtable (ParentTable, Subtable); 578 } 579 580 /* NamespaceString device identifier (Required, size = NamePathLength) */ 581 582 DeviceInfo->NamepathOffset = CurrentOffset; 583 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 584 &Subtable, TRUE); 585 if (ACPI_FAILURE (Status)) 586 { 587 return (Status); 588 } 589 590 /* Update the device info header */ 591 592 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 593 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 594 DtInsertSubtable (ParentTable, Subtable); 595 596 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 597 598 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 599 &Subtable, TRUE); 600 if (ACPI_FAILURE (Status)) 601 { 602 return (Status); 603 } 604 605 /* Update the device info header (zeros if no OEM data present) */ 606 607 DeviceInfo->OemDataOffset = 0; 608 DeviceInfo->OemDataLength = 0; 609 610 /* Optional subtable (OemData) */ 611 612 if (Subtable && Subtable->Length) 613 { 614 DeviceInfo->OemDataOffset = CurrentOffset; 615 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 616 617 DtInsertSubtable (ParentTable, Subtable); 618 } 619 620 SubtableCount--; 621 DtPopSubtable (); /* Get next Device Information subtable */ 622 } 623 624 DtPopSubtable (); 625 return (AE_OK); 626 } 627 628 629 /****************************************************************************** 630 * 631 * FUNCTION: DtCompileDmar 632 * 633 * PARAMETERS: List - Current field list pointer 634 * 635 * RETURN: Status 636 * 637 * DESCRIPTION: Compile DMAR. 638 * 639 *****************************************************************************/ 640 641 ACPI_STATUS 642 DtCompileDmar ( 643 void **List) 644 { 645 ACPI_STATUS Status; 646 DT_SUBTABLE *Subtable; 647 DT_SUBTABLE *ParentTable; 648 DT_FIELD **PFieldList = (DT_FIELD **) List; 649 DT_FIELD *SubtableStart; 650 ACPI_DMTABLE_INFO *InfoTable; 651 ACPI_DMAR_HEADER *DmarHeader; 652 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 653 UINT32 DeviceScopeLength; 654 UINT32 PciPathLength; 655 656 657 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE); 658 if (ACPI_FAILURE (Status)) 659 { 660 return (Status); 661 } 662 663 ParentTable = DtPeekSubtable (); 664 DtInsertSubtable (ParentTable, Subtable); 665 DtPushSubtable (Subtable); 666 667 while (*PFieldList) 668 { 669 /* DMAR Header */ 670 671 SubtableStart = *PFieldList; 672 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 673 &Subtable, TRUE); 674 if (ACPI_FAILURE (Status)) 675 { 676 return (Status); 677 } 678 679 ParentTable = DtPeekSubtable (); 680 DtInsertSubtable (ParentTable, Subtable); 681 DtPushSubtable (Subtable); 682 683 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 684 685 switch (DmarHeader->Type) 686 { 687 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 688 689 InfoTable = AcpiDmTableInfoDmar0; 690 break; 691 692 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 693 694 InfoTable = AcpiDmTableInfoDmar1; 695 break; 696 697 case ACPI_DMAR_TYPE_ROOT_ATS: 698 699 InfoTable = AcpiDmTableInfoDmar2; 700 break; 701 702 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 703 704 InfoTable = AcpiDmTableInfoDmar3; 705 break; 706 707 case ACPI_DMAR_TYPE_NAMESPACE: 708 709 InfoTable = AcpiDmTableInfoDmar4; 710 break; 711 712 default: 713 714 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 715 return (AE_ERROR); 716 } 717 718 /* DMAR Subtable */ 719 720 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 721 if (ACPI_FAILURE (Status)) 722 { 723 return (Status); 724 } 725 726 ParentTable = DtPeekSubtable (); 727 DtInsertSubtable (ParentTable, Subtable); 728 729 /* 730 * Optional Device Scope subtables 731 */ 732 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 733 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 734 { 735 /* These types do not support device scopes */ 736 737 DtPopSubtable (); 738 continue; 739 } 740 741 DtPushSubtable (Subtable); 742 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 743 ParentTable->Length; 744 while (DeviceScopeLength) 745 { 746 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 747 &Subtable, FALSE); 748 if (Status == AE_NOT_FOUND) 749 { 750 break; 751 } 752 753 ParentTable = DtPeekSubtable (); 754 DtInsertSubtable (ParentTable, Subtable); 755 DtPushSubtable (Subtable); 756 757 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 758 759 /* Optional PCI Paths */ 760 761 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 762 while (PciPathLength) 763 { 764 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 765 &Subtable, FALSE); 766 if (Status == AE_NOT_FOUND) 767 { 768 DtPopSubtable (); 769 break; 770 } 771 772 ParentTable = DtPeekSubtable (); 773 DtInsertSubtable (ParentTable, Subtable); 774 PciPathLength -= Subtable->Length; 775 } 776 777 DtPopSubtable (); 778 DeviceScopeLength -= DmarDeviceScope->Length; 779 } 780 781 DtPopSubtable (); 782 DtPopSubtable (); 783 } 784 785 return (AE_OK); 786 } 787 788 789 /****************************************************************************** 790 * 791 * FUNCTION: DtCompileDrtm 792 * 793 * PARAMETERS: List - Current field list pointer 794 * 795 * RETURN: Status 796 * 797 * DESCRIPTION: Compile DRTM. 798 * 799 *****************************************************************************/ 800 801 ACPI_STATUS 802 DtCompileDrtm ( 803 void **List) 804 { 805 ACPI_STATUS Status; 806 DT_SUBTABLE *Subtable; 807 DT_SUBTABLE *ParentTable; 808 DT_FIELD **PFieldList = (DT_FIELD **) List; 809 UINT32 Count; 810 /* ACPI_TABLE_DRTM *Drtm; */ 811 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 812 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 813 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 814 815 816 ParentTable = DtPeekSubtable (); 817 818 /* Compile DRTM header */ 819 820 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 821 &Subtable, TRUE); 822 if (ACPI_FAILURE (Status)) 823 { 824 return (Status); 825 } 826 DtInsertSubtable (ParentTable, Subtable); 827 828 /* 829 * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care 830 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 831 */ 832 #if 0 833 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 834 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 835 #endif 836 /* Compile VTL */ 837 838 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 839 &Subtable, TRUE); 840 if (ACPI_FAILURE (Status)) 841 { 842 return (Status); 843 } 844 845 DtInsertSubtable (ParentTable, Subtable); 846 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 847 848 DtPushSubtable (Subtable); 849 ParentTable = DtPeekSubtable (); 850 Count = 0; 851 852 while (*PFieldList) 853 { 854 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 855 &Subtable, TRUE); 856 if (ACPI_FAILURE (Status)) 857 { 858 return (Status); 859 } 860 if (!Subtable) 861 { 862 break; 863 } 864 DtInsertSubtable (ParentTable, Subtable); 865 Count++; 866 } 867 868 DrtmVtl->ValidatedTableCount = Count; 869 DtPopSubtable (); 870 ParentTable = DtPeekSubtable (); 871 872 /* Compile RL */ 873 874 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 875 &Subtable, TRUE); 876 if (ACPI_FAILURE (Status)) 877 { 878 return (Status); 879 } 880 881 DtInsertSubtable (ParentTable, Subtable); 882 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 883 884 DtPushSubtable (Subtable); 885 ParentTable = DtPeekSubtable (); 886 Count = 0; 887 888 while (*PFieldList) 889 { 890 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 891 &Subtable, TRUE); 892 if (ACPI_FAILURE (Status)) 893 { 894 return (Status); 895 } 896 897 if (!Subtable) 898 { 899 break; 900 } 901 902 DtInsertSubtable (ParentTable, Subtable); 903 Count++; 904 } 905 906 DrtmRl->ResourceCount = Count; 907 DtPopSubtable (); 908 ParentTable = DtPeekSubtable (); 909 910 /* Compile DPS */ 911 912 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 913 &Subtable, TRUE); 914 if (ACPI_FAILURE (Status)) 915 { 916 return (Status); 917 } 918 DtInsertSubtable (ParentTable, Subtable); 919 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 920 921 922 return (AE_OK); 923 } 924 925 926 /****************************************************************************** 927 * 928 * FUNCTION: DtCompileEinj 929 * 930 * PARAMETERS: List - Current field list pointer 931 * 932 * RETURN: Status 933 * 934 * DESCRIPTION: Compile EINJ. 935 * 936 *****************************************************************************/ 937 938 ACPI_STATUS 939 DtCompileEinj ( 940 void **List) 941 { 942 ACPI_STATUS Status; 943 944 945 Status = DtCompileTwoSubtables (List, 946 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 947 return (Status); 948 } 949 950 951 /****************************************************************************** 952 * 953 * FUNCTION: DtCompileErst 954 * 955 * PARAMETERS: List - Current field list pointer 956 * 957 * RETURN: Status 958 * 959 * DESCRIPTION: Compile ERST. 960 * 961 *****************************************************************************/ 962 963 ACPI_STATUS 964 DtCompileErst ( 965 void **List) 966 { 967 ACPI_STATUS Status; 968 969 970 Status = DtCompileTwoSubtables (List, 971 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 972 return (Status); 973 } 974 975 976 /****************************************************************************** 977 * 978 * FUNCTION: DtCompileGtdt 979 * 980 * PARAMETERS: List - Current field list pointer 981 * 982 * RETURN: Status 983 * 984 * DESCRIPTION: Compile GTDT. 985 * 986 *****************************************************************************/ 987 988 ACPI_STATUS 989 DtCompileGtdt ( 990 void **List) 991 { 992 ACPI_STATUS Status; 993 DT_SUBTABLE *Subtable; 994 DT_SUBTABLE *ParentTable; 995 DT_FIELD **PFieldList = (DT_FIELD **) List; 996 DT_FIELD *SubtableStart; 997 ACPI_SUBTABLE_HEADER *GtdtHeader; 998 ACPI_DMTABLE_INFO *InfoTable; 999 UINT32 GtCount; 1000 1001 1002 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 1003 &Subtable, TRUE); 1004 if (ACPI_FAILURE (Status)) 1005 { 1006 return (Status); 1007 } 1008 1009 ParentTable = DtPeekSubtable (); 1010 DtInsertSubtable (ParentTable, Subtable); 1011 1012 while (*PFieldList) 1013 { 1014 SubtableStart = *PFieldList; 1015 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 1016 &Subtable, TRUE); 1017 if (ACPI_FAILURE (Status)) 1018 { 1019 return (Status); 1020 } 1021 1022 ParentTable = DtPeekSubtable (); 1023 DtInsertSubtable (ParentTable, Subtable); 1024 DtPushSubtable (Subtable); 1025 1026 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1027 1028 switch (GtdtHeader->Type) 1029 { 1030 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1031 1032 InfoTable = AcpiDmTableInfoGtdt0; 1033 break; 1034 1035 case ACPI_GTDT_TYPE_WATCHDOG: 1036 1037 InfoTable = AcpiDmTableInfoGtdt1; 1038 break; 1039 1040 default: 1041 1042 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 1043 return (AE_ERROR); 1044 } 1045 1046 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1047 if (ACPI_FAILURE (Status)) 1048 { 1049 return (Status); 1050 } 1051 1052 ParentTable = DtPeekSubtable (); 1053 DtInsertSubtable (ParentTable, Subtable); 1054 1055 /* 1056 * Additional GT block subtable data 1057 */ 1058 1059 switch (GtdtHeader->Type) 1060 { 1061 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1062 1063 DtPushSubtable (Subtable); 1064 ParentTable = DtPeekSubtable (); 1065 1066 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 1067 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 1068 1069 while (GtCount) 1070 { 1071 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 1072 &Subtable, TRUE); 1073 if (ACPI_FAILURE (Status)) 1074 { 1075 return (Status); 1076 } 1077 1078 DtInsertSubtable (ParentTable, Subtable); 1079 GtCount--; 1080 } 1081 1082 DtPopSubtable (); 1083 break; 1084 1085 default: 1086 1087 break; 1088 } 1089 1090 DtPopSubtable (); 1091 } 1092 1093 return (AE_OK); 1094 } 1095 1096 1097 /****************************************************************************** 1098 * 1099 * FUNCTION: DtCompileFpdt 1100 * 1101 * PARAMETERS: List - Current field list pointer 1102 * 1103 * RETURN: Status 1104 * 1105 * DESCRIPTION: Compile FPDT. 1106 * 1107 *****************************************************************************/ 1108 1109 ACPI_STATUS 1110 DtCompileFpdt ( 1111 void **List) 1112 { 1113 ACPI_STATUS Status; 1114 ACPI_FPDT_HEADER *FpdtHeader; 1115 DT_SUBTABLE *Subtable; 1116 DT_SUBTABLE *ParentTable; 1117 ACPI_DMTABLE_INFO *InfoTable; 1118 DT_FIELD **PFieldList = (DT_FIELD **) List; 1119 DT_FIELD *SubtableStart; 1120 1121 1122 while (*PFieldList) 1123 { 1124 SubtableStart = *PFieldList; 1125 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1126 &Subtable, TRUE); 1127 if (ACPI_FAILURE (Status)) 1128 { 1129 return (Status); 1130 } 1131 1132 ParentTable = DtPeekSubtable (); 1133 DtInsertSubtable (ParentTable, Subtable); 1134 DtPushSubtable (Subtable); 1135 1136 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1137 1138 switch (FpdtHeader->Type) 1139 { 1140 case ACPI_FPDT_TYPE_BOOT: 1141 1142 InfoTable = AcpiDmTableInfoFpdt0; 1143 break; 1144 1145 case ACPI_FPDT_TYPE_S3PERF: 1146 1147 InfoTable = AcpiDmTableInfoFpdt1; 1148 break; 1149 1150 default: 1151 1152 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1153 return (AE_ERROR); 1154 break; 1155 } 1156 1157 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1158 if (ACPI_FAILURE (Status)) 1159 { 1160 return (Status); 1161 } 1162 1163 ParentTable = DtPeekSubtable (); 1164 DtInsertSubtable (ParentTable, Subtable); 1165 DtPopSubtable (); 1166 } 1167 1168 return (AE_OK); 1169 } 1170 1171 1172 /****************************************************************************** 1173 * 1174 * FUNCTION: DtCompileHest 1175 * 1176 * PARAMETERS: List - Current field list pointer 1177 * 1178 * RETURN: Status 1179 * 1180 * DESCRIPTION: Compile HEST. 1181 * 1182 *****************************************************************************/ 1183 1184 ACPI_STATUS 1185 DtCompileHest ( 1186 void **List) 1187 { 1188 ACPI_STATUS Status; 1189 DT_SUBTABLE *Subtable; 1190 DT_SUBTABLE *ParentTable; 1191 DT_FIELD **PFieldList = (DT_FIELD **) List; 1192 DT_FIELD *SubtableStart; 1193 ACPI_DMTABLE_INFO *InfoTable; 1194 UINT16 Type; 1195 UINT32 BankCount; 1196 1197 1198 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1199 &Subtable, TRUE); 1200 if (ACPI_FAILURE (Status)) 1201 { 1202 return (Status); 1203 } 1204 1205 ParentTable = DtPeekSubtable (); 1206 DtInsertSubtable (ParentTable, Subtable); 1207 1208 while (*PFieldList) 1209 { 1210 /* Get subtable type */ 1211 1212 SubtableStart = *PFieldList; 1213 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1214 1215 switch (Type) 1216 { 1217 case ACPI_HEST_TYPE_IA32_CHECK: 1218 1219 InfoTable = AcpiDmTableInfoHest0; 1220 break; 1221 1222 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1223 1224 InfoTable = AcpiDmTableInfoHest1; 1225 break; 1226 1227 case ACPI_HEST_TYPE_IA32_NMI: 1228 1229 InfoTable = AcpiDmTableInfoHest2; 1230 break; 1231 1232 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1233 1234 InfoTable = AcpiDmTableInfoHest6; 1235 break; 1236 1237 case ACPI_HEST_TYPE_AER_ENDPOINT: 1238 1239 InfoTable = AcpiDmTableInfoHest7; 1240 break; 1241 1242 case ACPI_HEST_TYPE_AER_BRIDGE: 1243 1244 InfoTable = AcpiDmTableInfoHest8; 1245 break; 1246 1247 case ACPI_HEST_TYPE_GENERIC_ERROR: 1248 1249 InfoTable = AcpiDmTableInfoHest9; 1250 break; 1251 1252 case ACPI_HEST_TYPE_GENERIC_ERROR_V2: 1253 1254 InfoTable = AcpiDmTableInfoHest10; 1255 break; 1256 1257 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1258 1259 InfoTable = AcpiDmTableInfoHest11; 1260 break; 1261 1262 default: 1263 1264 /* Cannot continue on unknown type */ 1265 1266 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1267 return (AE_ERROR); 1268 } 1269 1270 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1271 if (ACPI_FAILURE (Status)) 1272 { 1273 return (Status); 1274 } 1275 1276 DtInsertSubtable (ParentTable, Subtable); 1277 1278 /* 1279 * Additional subtable data - IA32 Error Bank(s) 1280 */ 1281 BankCount = 0; 1282 switch (Type) 1283 { 1284 case ACPI_HEST_TYPE_IA32_CHECK: 1285 1286 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1287 Subtable->Buffer))->NumHardwareBanks; 1288 break; 1289 1290 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1291 1292 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1293 Subtable->Buffer))->NumHardwareBanks; 1294 break; 1295 1296 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: 1297 1298 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, 1299 Subtable->Buffer))->NumHardwareBanks; 1300 break; 1301 1302 default: 1303 1304 break; 1305 } 1306 1307 while (BankCount) 1308 { 1309 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1310 &Subtable, TRUE); 1311 if (ACPI_FAILURE (Status)) 1312 { 1313 return (Status); 1314 } 1315 1316 DtInsertSubtable (ParentTable, Subtable); 1317 BankCount--; 1318 } 1319 } 1320 1321 return (AE_OK); 1322 } 1323 1324 1325 /****************************************************************************** 1326 * 1327 * FUNCTION: DtCompileHmat 1328 * 1329 * PARAMETERS: List - Current field list pointer 1330 * 1331 * RETURN: Status 1332 * 1333 * DESCRIPTION: Compile HMAT. 1334 * 1335 *****************************************************************************/ 1336 1337 ACPI_STATUS 1338 DtCompileHmat ( 1339 void **List) 1340 { 1341 ACPI_STATUS Status; 1342 DT_SUBTABLE *Subtable; 1343 DT_SUBTABLE *ParentTable; 1344 DT_FIELD **PFieldList = (DT_FIELD **) List; 1345 DT_FIELD *SubtableStart; 1346 DT_FIELD *EntryStart; 1347 ACPI_HMAT_STRUCTURE *HmatStruct; 1348 ACPI_HMAT_LOCALITY *HmatLocality; 1349 ACPI_HMAT_CACHE *HmatCache; 1350 ACPI_DMTABLE_INFO *InfoTable; 1351 UINT32 IntPDNumber; 1352 UINT32 TgtPDNumber; 1353 UINT64 EntryNumber; 1354 UINT16 SMBIOSHandleNumber; 1355 1356 1357 ParentTable = DtPeekSubtable (); 1358 1359 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat, 1360 &Subtable, TRUE); 1361 if (ACPI_FAILURE (Status)) 1362 { 1363 return (Status); 1364 } 1365 DtInsertSubtable (ParentTable, Subtable); 1366 1367 while (*PFieldList) 1368 { 1369 /* Compile HMAT structure header */ 1370 1371 SubtableStart = *PFieldList; 1372 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr, 1373 &Subtable, TRUE); 1374 if (ACPI_FAILURE (Status)) 1375 { 1376 return (Status); 1377 } 1378 DtInsertSubtable (ParentTable, Subtable); 1379 1380 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer); 1381 HmatStruct->Length = Subtable->Length; 1382 1383 /* Compile HMAT structure body */ 1384 1385 switch (HmatStruct->Type) 1386 { 1387 case ACPI_HMAT_TYPE_ADDRESS_RANGE: 1388 1389 InfoTable = AcpiDmTableInfoHmat0; 1390 break; 1391 1392 case ACPI_HMAT_TYPE_LOCALITY: 1393 1394 InfoTable = AcpiDmTableInfoHmat1; 1395 break; 1396 1397 case ACPI_HMAT_TYPE_CACHE: 1398 1399 InfoTable = AcpiDmTableInfoHmat2; 1400 break; 1401 1402 default: 1403 1404 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT"); 1405 return (AE_ERROR); 1406 } 1407 1408 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1409 if (ACPI_FAILURE (Status)) 1410 { 1411 return (Status); 1412 } 1413 DtInsertSubtable (ParentTable, Subtable); 1414 HmatStruct->Length += Subtable->Length; 1415 1416 /* Compile HMAT structure additionals */ 1417 1418 switch (HmatStruct->Type) 1419 { 1420 case ACPI_HMAT_TYPE_LOCALITY: 1421 1422 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY, 1423 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1424 1425 /* Compile initiator proximity domain list */ 1426 1427 IntPDNumber = 0; 1428 while (*PFieldList) 1429 { 1430 Status = DtCompileTable (PFieldList, 1431 AcpiDmTableInfoHmat1a, &Subtable, TRUE); 1432 if (ACPI_FAILURE (Status)) 1433 { 1434 return (Status); 1435 } 1436 if (!Subtable) 1437 { 1438 break; 1439 } 1440 DtInsertSubtable (ParentTable, Subtable); 1441 HmatStruct->Length += Subtable->Length; 1442 IntPDNumber++; 1443 } 1444 HmatLocality->NumberOfInitiatorPDs = IntPDNumber; 1445 1446 /* Compile target proximity domain list */ 1447 1448 TgtPDNumber = 0; 1449 while (*PFieldList) 1450 { 1451 Status = DtCompileTable (PFieldList, 1452 AcpiDmTableInfoHmat1b, &Subtable, TRUE); 1453 if (ACPI_FAILURE (Status)) 1454 { 1455 return (Status); 1456 } 1457 if (!Subtable) 1458 { 1459 break; 1460 } 1461 DtInsertSubtable (ParentTable, Subtable); 1462 HmatStruct->Length += Subtable->Length; 1463 TgtPDNumber++; 1464 } 1465 HmatLocality->NumberOfTargetPDs = TgtPDNumber; 1466 1467 /* Save start of the entries for reporting errors */ 1468 1469 EntryStart = *PFieldList; 1470 1471 /* Compile latency/bandwidth entries */ 1472 1473 EntryNumber = 0; 1474 while (*PFieldList) 1475 { 1476 Status = DtCompileTable (PFieldList, 1477 AcpiDmTableInfoHmat1c, &Subtable, TRUE); 1478 if (ACPI_FAILURE (Status)) 1479 { 1480 return (Status); 1481 } 1482 if (!Subtable) 1483 { 1484 break; 1485 } 1486 DtInsertSubtable (ParentTable, Subtable); 1487 HmatStruct->Length += Subtable->Length; 1488 EntryNumber++; 1489 } 1490 1491 /* Validate number of entries */ 1492 1493 if (EntryNumber != 1494 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber)) 1495 { 1496 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT"); 1497 return (AE_ERROR); 1498 } 1499 break; 1500 1501 case ACPI_HMAT_TYPE_CACHE: 1502 1503 /* Compile SMBIOS handles */ 1504 1505 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE, 1506 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE)); 1507 SMBIOSHandleNumber = 0; 1508 while (*PFieldList) 1509 { 1510 Status = DtCompileTable (PFieldList, 1511 AcpiDmTableInfoHmat2a, &Subtable, TRUE); 1512 if (ACPI_FAILURE (Status)) 1513 { 1514 return (Status); 1515 } 1516 if (!Subtable) 1517 { 1518 break; 1519 } 1520 DtInsertSubtable (ParentTable, Subtable); 1521 HmatStruct->Length += Subtable->Length; 1522 SMBIOSHandleNumber++; 1523 } 1524 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber; 1525 break; 1526 1527 default: 1528 1529 break; 1530 } 1531 } 1532 1533 return (AE_OK); 1534 } 1535 1536 1537 /****************************************************************************** 1538 * 1539 * FUNCTION: DtCompileIort 1540 * 1541 * PARAMETERS: List - Current field list pointer 1542 * 1543 * RETURN: Status 1544 * 1545 * DESCRIPTION: Compile IORT. 1546 * 1547 *****************************************************************************/ 1548 1549 ACPI_STATUS 1550 DtCompileIort ( 1551 void **List) 1552 { 1553 ACPI_STATUS Status; 1554 DT_SUBTABLE *Subtable; 1555 DT_SUBTABLE *ParentTable; 1556 DT_FIELD **PFieldList = (DT_FIELD **) List; 1557 DT_FIELD *SubtableStart; 1558 ACPI_TABLE_IORT *Iort; 1559 ACPI_IORT_NODE *IortNode; 1560 ACPI_IORT_ITS_GROUP *IortItsGroup; 1561 ACPI_IORT_SMMU *IortSmmu; 1562 UINT32 NodeNumber; 1563 UINT32 NodeLength; 1564 UINT32 IdMappingNumber; 1565 UINT32 ItsNumber; 1566 UINT32 ContextIrptNumber; 1567 UINT32 PmuIrptNumber; 1568 UINT32 PaddingLength; 1569 1570 1571 ParentTable = DtPeekSubtable (); 1572 1573 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 1574 &Subtable, TRUE); 1575 if (ACPI_FAILURE (Status)) 1576 { 1577 return (Status); 1578 } 1579 DtInsertSubtable (ParentTable, Subtable); 1580 1581 /* 1582 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 1583 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 1584 */ 1585 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 1586 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1587 1588 /* 1589 * OptionalPadding - Variable-length data 1590 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 1591 * Optionally allows the generic data types to be used for filling 1592 * this field. 1593 */ 1594 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 1595 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 1596 &Subtable, TRUE); 1597 if (ACPI_FAILURE (Status)) 1598 { 1599 return (Status); 1600 } 1601 if (Subtable) 1602 { 1603 DtInsertSubtable (ParentTable, Subtable); 1604 Iort->NodeOffset += Subtable->Length; 1605 } 1606 else 1607 { 1608 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 1609 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 1610 if (ACPI_FAILURE (Status)) 1611 { 1612 return (Status); 1613 } 1614 Iort->NodeOffset += PaddingLength; 1615 } 1616 1617 NodeNumber = 0; 1618 while (*PFieldList) 1619 { 1620 SubtableStart = *PFieldList; 1621 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 1622 &Subtable, TRUE); 1623 if (ACPI_FAILURE (Status)) 1624 { 1625 return (Status); 1626 } 1627 1628 DtInsertSubtable (ParentTable, Subtable); 1629 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 1630 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 1631 1632 DtPushSubtable (Subtable); 1633 ParentTable = DtPeekSubtable (); 1634 1635 switch (IortNode->Type) 1636 { 1637 case ACPI_IORT_NODE_ITS_GROUP: 1638 1639 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 1640 &Subtable, TRUE); 1641 if (ACPI_FAILURE (Status)) 1642 { 1643 return (Status); 1644 } 1645 1646 DtInsertSubtable (ParentTable, Subtable); 1647 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 1648 NodeLength += Subtable->Length; 1649 1650 ItsNumber = 0; 1651 while (*PFieldList) 1652 { 1653 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 1654 &Subtable, TRUE); 1655 if (ACPI_FAILURE (Status)) 1656 { 1657 return (Status); 1658 } 1659 if (!Subtable) 1660 { 1661 break; 1662 } 1663 1664 DtInsertSubtable (ParentTable, Subtable); 1665 NodeLength += Subtable->Length; 1666 ItsNumber++; 1667 } 1668 1669 IortItsGroup->ItsCount = ItsNumber; 1670 break; 1671 1672 case ACPI_IORT_NODE_NAMED_COMPONENT: 1673 1674 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 1675 &Subtable, TRUE); 1676 if (ACPI_FAILURE (Status)) 1677 { 1678 return (Status); 1679 } 1680 1681 DtInsertSubtable (ParentTable, Subtable); 1682 NodeLength += Subtable->Length; 1683 1684 /* 1685 * Padding - Variable-length data 1686 * Optionally allows the offset of the ID mappings to be used 1687 * for filling this field. 1688 */ 1689 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 1690 &Subtable, TRUE); 1691 if (ACPI_FAILURE (Status)) 1692 { 1693 return (Status); 1694 } 1695 1696 if (Subtable) 1697 { 1698 DtInsertSubtable (ParentTable, Subtable); 1699 NodeLength += Subtable->Length; 1700 } 1701 else 1702 { 1703 if (NodeLength > IortNode->MappingOffset) 1704 { 1705 return (AE_BAD_DATA); 1706 } 1707 1708 if (NodeLength < IortNode->MappingOffset) 1709 { 1710 Status = DtCompilePadding ( 1711 IortNode->MappingOffset - NodeLength, 1712 &Subtable); 1713 if (ACPI_FAILURE (Status)) 1714 { 1715 return (Status); 1716 } 1717 1718 DtInsertSubtable (ParentTable, Subtable); 1719 NodeLength = IortNode->MappingOffset; 1720 } 1721 } 1722 break; 1723 1724 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 1725 1726 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 1727 &Subtable, TRUE); 1728 if (ACPI_FAILURE (Status)) 1729 { 1730 return (Status); 1731 } 1732 1733 DtInsertSubtable (ParentTable, Subtable); 1734 NodeLength += Subtable->Length; 1735 break; 1736 1737 case ACPI_IORT_NODE_SMMU: 1738 1739 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 1740 &Subtable, TRUE); 1741 if (ACPI_FAILURE (Status)) 1742 { 1743 return (Status); 1744 } 1745 1746 DtInsertSubtable (ParentTable, Subtable); 1747 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 1748 NodeLength += Subtable->Length; 1749 1750 /* Compile global interrupt array */ 1751 1752 IortSmmu->GlobalInterruptOffset = NodeLength; 1753 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 1754 &Subtable, TRUE); 1755 if (ACPI_FAILURE (Status)) 1756 { 1757 return (Status); 1758 } 1759 1760 DtInsertSubtable (ParentTable, Subtable); 1761 NodeLength += Subtable->Length; 1762 1763 /* Compile context interrupt array */ 1764 1765 ContextIrptNumber = 0; 1766 IortSmmu->ContextInterruptOffset = NodeLength; 1767 while (*PFieldList) 1768 { 1769 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 1770 &Subtable, TRUE); 1771 if (ACPI_FAILURE (Status)) 1772 { 1773 return (Status); 1774 } 1775 1776 if (!Subtable) 1777 { 1778 break; 1779 } 1780 1781 DtInsertSubtable (ParentTable, Subtable); 1782 NodeLength += Subtable->Length; 1783 ContextIrptNumber++; 1784 } 1785 1786 IortSmmu->ContextInterruptCount = ContextIrptNumber; 1787 1788 /* Compile PMU interrupt array */ 1789 1790 PmuIrptNumber = 0; 1791 IortSmmu->PmuInterruptOffset = NodeLength; 1792 while (*PFieldList) 1793 { 1794 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 1795 &Subtable, TRUE); 1796 if (ACPI_FAILURE (Status)) 1797 { 1798 return (Status); 1799 } 1800 1801 if (!Subtable) 1802 { 1803 break; 1804 } 1805 1806 DtInsertSubtable (ParentTable, Subtable); 1807 NodeLength += Subtable->Length; 1808 PmuIrptNumber++; 1809 } 1810 1811 IortSmmu->PmuInterruptCount = PmuIrptNumber; 1812 break; 1813 1814 case ACPI_IORT_NODE_SMMU_V3: 1815 1816 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4, 1817 &Subtable, TRUE); 1818 if (ACPI_FAILURE (Status)) 1819 { 1820 return (Status); 1821 } 1822 1823 DtInsertSubtable (ParentTable, Subtable); 1824 NodeLength += Subtable->Length; 1825 break; 1826 1827 default: 1828 1829 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 1830 return (AE_ERROR); 1831 } 1832 1833 /* Compile Array of ID mappings */ 1834 1835 IortNode->MappingOffset = NodeLength; 1836 IdMappingNumber = 0; 1837 while (*PFieldList) 1838 { 1839 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 1840 &Subtable, TRUE); 1841 if (ACPI_FAILURE (Status)) 1842 { 1843 return (Status); 1844 } 1845 1846 if (!Subtable) 1847 { 1848 break; 1849 } 1850 1851 DtInsertSubtable (ParentTable, Subtable); 1852 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 1853 IdMappingNumber++; 1854 } 1855 1856 IortNode->MappingCount = IdMappingNumber; 1857 if (!IdMappingNumber) 1858 { 1859 IortNode->MappingOffset = 0; 1860 } 1861 1862 /* 1863 * Node length can be determined by DT_LENGTH option 1864 * IortNode->Length = NodeLength; 1865 */ 1866 DtPopSubtable (); 1867 ParentTable = DtPeekSubtable (); 1868 NodeNumber++; 1869 } 1870 1871 Iort->NodeCount = NodeNumber; 1872 return (AE_OK); 1873 } 1874 1875 1876 /****************************************************************************** 1877 * 1878 * FUNCTION: DtCompileIvrs 1879 * 1880 * PARAMETERS: List - Current field list pointer 1881 * 1882 * RETURN: Status 1883 * 1884 * DESCRIPTION: Compile IVRS. 1885 * 1886 *****************************************************************************/ 1887 1888 ACPI_STATUS 1889 DtCompileIvrs ( 1890 void **List) 1891 { 1892 ACPI_STATUS Status; 1893 DT_SUBTABLE *Subtable; 1894 DT_SUBTABLE *ParentTable; 1895 DT_FIELD **PFieldList = (DT_FIELD **) List; 1896 DT_FIELD *SubtableStart; 1897 ACPI_DMTABLE_INFO *InfoTable; 1898 ACPI_IVRS_HEADER *IvrsHeader; 1899 UINT8 EntryType; 1900 1901 1902 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 1903 &Subtable, TRUE); 1904 if (ACPI_FAILURE (Status)) 1905 { 1906 return (Status); 1907 } 1908 1909 ParentTable = DtPeekSubtable (); 1910 DtInsertSubtable (ParentTable, Subtable); 1911 1912 while (*PFieldList) 1913 { 1914 SubtableStart = *PFieldList; 1915 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr, 1916 &Subtable, TRUE); 1917 if (ACPI_FAILURE (Status)) 1918 { 1919 return (Status); 1920 } 1921 1922 ParentTable = DtPeekSubtable (); 1923 DtInsertSubtable (ParentTable, Subtable); 1924 DtPushSubtable (Subtable); 1925 1926 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer); 1927 1928 switch (IvrsHeader->Type) 1929 { 1930 case ACPI_IVRS_TYPE_HARDWARE: 1931 1932 InfoTable = AcpiDmTableInfoIvrs0; 1933 break; 1934 1935 case ACPI_IVRS_TYPE_MEMORY1: 1936 case ACPI_IVRS_TYPE_MEMORY2: 1937 case ACPI_IVRS_TYPE_MEMORY3: 1938 1939 InfoTable = AcpiDmTableInfoIvrs1; 1940 break; 1941 1942 default: 1943 1944 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS"); 1945 return (AE_ERROR); 1946 } 1947 1948 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1949 if (ACPI_FAILURE (Status)) 1950 { 1951 return (Status); 1952 } 1953 1954 ParentTable = DtPeekSubtable (); 1955 DtInsertSubtable (ParentTable, Subtable); 1956 1957 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE) 1958 { 1959 while (*PFieldList && 1960 !strcmp ((*PFieldList)->Name, "Entry Type")) 1961 { 1962 SubtableStart = *PFieldList; 1963 DtCompileInteger (&EntryType, *PFieldList, 1, 0); 1964 1965 switch (EntryType) 1966 { 1967 /* 4-byte device entries */ 1968 1969 case ACPI_IVRS_TYPE_PAD4: 1970 case ACPI_IVRS_TYPE_ALL: 1971 case ACPI_IVRS_TYPE_SELECT: 1972 case ACPI_IVRS_TYPE_START: 1973 case ACPI_IVRS_TYPE_END: 1974 1975 InfoTable = AcpiDmTableInfoIvrs4; 1976 break; 1977 1978 /* 8-byte entries, type A */ 1979 1980 case ACPI_IVRS_TYPE_ALIAS_SELECT: 1981 case ACPI_IVRS_TYPE_ALIAS_START: 1982 1983 InfoTable = AcpiDmTableInfoIvrs8a; 1984 break; 1985 1986 /* 8-byte entries, type B */ 1987 1988 case ACPI_IVRS_TYPE_PAD8: 1989 case ACPI_IVRS_TYPE_EXT_SELECT: 1990 case ACPI_IVRS_TYPE_EXT_START: 1991 1992 InfoTable = AcpiDmTableInfoIvrs8b; 1993 break; 1994 1995 /* 8-byte entries, type C */ 1996 1997 case ACPI_IVRS_TYPE_SPECIAL: 1998 1999 InfoTable = AcpiDmTableInfoIvrs8c; 2000 break; 2001 2002 default: 2003 2004 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 2005 "IVRS Device Entry"); 2006 return (AE_ERROR); 2007 } 2008 2009 Status = DtCompileTable (PFieldList, InfoTable, 2010 &Subtable, TRUE); 2011 if (ACPI_FAILURE (Status)) 2012 { 2013 return (Status); 2014 } 2015 2016 DtInsertSubtable (ParentTable, Subtable); 2017 } 2018 } 2019 2020 DtPopSubtable (); 2021 } 2022 2023 return (AE_OK); 2024 } 2025