1 /****************************************************************************** 2 * 3 * Module Name: dttable2.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 /* Compile all complex data tables, signatures starting with L-Z */ 153 154 #include <contrib/dev/acpica/compiler/aslcompiler.h> 155 156 #define _COMPONENT DT_COMPILER 157 ACPI_MODULE_NAME ("dttable2") 158 159 160 /****************************************************************************** 161 * 162 * FUNCTION: DtCompileLpit 163 * 164 * PARAMETERS: List - Current field list pointer 165 * 166 * RETURN: Status 167 * 168 * DESCRIPTION: Compile LPIT. 169 * 170 *****************************************************************************/ 171 172 ACPI_STATUS 173 DtCompileLpit ( 174 void **List) 175 { 176 ACPI_STATUS Status; 177 DT_SUBTABLE *Subtable; 178 DT_SUBTABLE *ParentTable; 179 DT_FIELD **PFieldList = (DT_FIELD **) List; 180 DT_FIELD *SubtableStart; 181 ACPI_DMTABLE_INFO *InfoTable; 182 ACPI_LPIT_HEADER *LpitHeader; 183 184 185 /* Note: Main table consists only of the standard ACPI table header */ 186 187 while (*PFieldList) 188 { 189 SubtableStart = *PFieldList; 190 191 /* LPIT Subtable header */ 192 193 Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr, 194 &Subtable); 195 if (ACPI_FAILURE (Status)) 196 { 197 return (Status); 198 } 199 200 ParentTable = DtPeekSubtable (); 201 DtInsertSubtable (ParentTable, Subtable); 202 DtPushSubtable (Subtable); 203 204 LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer); 205 206 switch (LpitHeader->Type) 207 { 208 case ACPI_LPIT_TYPE_NATIVE_CSTATE: 209 210 InfoTable = AcpiDmTableInfoLpit0; 211 break; 212 213 default: 214 215 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT"); 216 return (AE_ERROR); 217 } 218 219 /* LPIT Subtable */ 220 221 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 222 if (ACPI_FAILURE (Status)) 223 { 224 return (Status); 225 } 226 227 ParentTable = DtPeekSubtable (); 228 DtInsertSubtable (ParentTable, Subtable); 229 DtPopSubtable (); 230 } 231 232 return (AE_OK); 233 } 234 235 236 /****************************************************************************** 237 * 238 * FUNCTION: DtCompileMadt 239 * 240 * PARAMETERS: List - Current field list pointer 241 * 242 * RETURN: Status 243 * 244 * DESCRIPTION: Compile MADT. 245 * 246 *****************************************************************************/ 247 248 ACPI_STATUS 249 DtCompileMadt ( 250 void **List) 251 { 252 ACPI_STATUS Status; 253 DT_SUBTABLE *Subtable; 254 DT_SUBTABLE *ParentTable; 255 DT_FIELD **PFieldList = (DT_FIELD **) List; 256 DT_FIELD *SubtableStart; 257 ACPI_TABLE_HEADER *Table; 258 ACPI_SUBTABLE_HEADER *MadtHeader; 259 ACPI_DMTABLE_INFO *InfoTable; 260 UINT8 Revision; 261 262 263 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, 264 &Subtable); 265 if (ACPI_FAILURE (Status)) 266 { 267 return (Status); 268 } 269 270 ParentTable = DtPeekSubtable (); 271 DtInsertSubtable (ParentTable, Subtable); 272 273 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 274 Revision = Table->Revision; 275 276 while (*PFieldList) 277 { 278 SubtableStart = *PFieldList; 279 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, 280 &Subtable); 281 if (ACPI_FAILURE (Status)) 282 { 283 return (Status); 284 } 285 286 ParentTable = DtPeekSubtable (); 287 DtInsertSubtable (ParentTable, Subtable); 288 DtPushSubtable (Subtable); 289 290 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 291 292 switch (MadtHeader->Type) 293 { 294 case ACPI_MADT_TYPE_LOCAL_APIC: 295 296 InfoTable = AcpiDmTableInfoMadt0; 297 break; 298 299 case ACPI_MADT_TYPE_IO_APIC: 300 301 InfoTable = AcpiDmTableInfoMadt1; 302 break; 303 304 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 305 306 InfoTable = AcpiDmTableInfoMadt2; 307 break; 308 309 case ACPI_MADT_TYPE_NMI_SOURCE: 310 311 InfoTable = AcpiDmTableInfoMadt3; 312 break; 313 314 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 315 316 InfoTable = AcpiDmTableInfoMadt4; 317 break; 318 319 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 320 321 InfoTable = AcpiDmTableInfoMadt5; 322 break; 323 324 case ACPI_MADT_TYPE_IO_SAPIC: 325 326 InfoTable = AcpiDmTableInfoMadt6; 327 break; 328 329 case ACPI_MADT_TYPE_LOCAL_SAPIC: 330 331 InfoTable = AcpiDmTableInfoMadt7; 332 break; 333 334 case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 335 336 InfoTable = AcpiDmTableInfoMadt8; 337 break; 338 339 case ACPI_MADT_TYPE_LOCAL_X2APIC: 340 341 InfoTable = AcpiDmTableInfoMadt9; 342 break; 343 344 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 345 346 InfoTable = AcpiDmTableInfoMadt10; 347 break; 348 349 case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 350 351 if (Revision > 6) 352 InfoTable = AcpiDmTableInfoMadt11b; 353 else if (Revision == 6) 354 InfoTable = AcpiDmTableInfoMadt11a; 355 else 356 InfoTable = AcpiDmTableInfoMadt11; 357 break; 358 359 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 360 361 InfoTable = AcpiDmTableInfoMadt12; 362 break; 363 364 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME: 365 366 InfoTable = AcpiDmTableInfoMadt13; 367 break; 368 369 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 370 371 InfoTable = Revision > 6 ? AcpiDmTableInfoMadt14a 372 : AcpiDmTableInfoMadt14; 373 break; 374 375 case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: 376 377 InfoTable = Revision > 6 ? AcpiDmTableInfoMadt15a 378 : AcpiDmTableInfoMadt15; 379 380 break; 381 382 case ACPI_MADT_TYPE_MULTIPROC_WAKEUP: 383 384 InfoTable = AcpiDmTableInfoMadt16; 385 break; 386 387 case ACPI_MADT_TYPE_CORE_PIC: 388 389 InfoTable = AcpiDmTableInfoMadt17; 390 break; 391 392 case ACPI_MADT_TYPE_LIO_PIC: 393 394 InfoTable = AcpiDmTableInfoMadt18; 395 break; 396 397 case ACPI_MADT_TYPE_HT_PIC: 398 399 InfoTable = AcpiDmTableInfoMadt19; 400 break; 401 402 case ACPI_MADT_TYPE_EIO_PIC: 403 404 InfoTable = AcpiDmTableInfoMadt20; 405 break; 406 407 case ACPI_MADT_TYPE_MSI_PIC: 408 409 InfoTable = AcpiDmTableInfoMadt21; 410 break; 411 412 case ACPI_MADT_TYPE_BIO_PIC: 413 414 InfoTable = AcpiDmTableInfoMadt22; 415 break; 416 417 case ACPI_MADT_TYPE_LPC_PIC: 418 419 InfoTable = AcpiDmTableInfoMadt23; 420 break; 421 422 case ACPI_MADT_TYPE_RINTC: 423 424 InfoTable = AcpiDmTableInfoMadt24; 425 break; 426 427 case ACPI_MADT_TYPE_IMSIC: 428 429 InfoTable = AcpiDmTableInfoMadt25; 430 break; 431 432 case ACPI_MADT_TYPE_APLIC: 433 434 InfoTable = AcpiDmTableInfoMadt26; 435 break; 436 437 case ACPI_MADT_TYPE_PLIC: 438 439 InfoTable = AcpiDmTableInfoMadt27; 440 break; 441 442 default: 443 444 if (MadtHeader->Type >= ACPI_MADT_TYPE_OEM_RESERVED) 445 { 446 InfoTable = AcpiDmTableInfoMadt128; 447 } 448 else 449 { 450 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 451 return (AE_ERROR); 452 } 453 454 break; 455 } 456 457 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 458 if (ACPI_FAILURE (Status)) 459 { 460 return (Status); 461 } 462 463 ParentTable = DtPeekSubtable (); 464 DtInsertSubtable (ParentTable, Subtable); 465 DtPopSubtable (); 466 } 467 468 return (AE_OK); 469 } 470 471 472 /****************************************************************************** 473 * 474 * FUNCTION: DtCompileMcfg 475 * 476 * PARAMETERS: List - Current field list pointer 477 * 478 * RETURN: Status 479 * 480 * DESCRIPTION: Compile MCFG. 481 * 482 *****************************************************************************/ 483 484 ACPI_STATUS 485 DtCompileMcfg ( 486 void **List) 487 { 488 ACPI_STATUS Status; 489 490 491 Status = DtCompileTwoSubtables (List, 492 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 493 return (Status); 494 } 495 496 /****************************************************************************** 497 * 498 * FUNCTION: DtCompileMpam 499 * 500 * PARAMETERS: List - Current field list pointer 501 * 502 * RETURN: Status 503 * 504 * DESCRIPTION: Compile MPAM. 505 * 506 *****************************************************************************/ 507 508 ACPI_STATUS 509 DtCompileMpam ( 510 void **List) 511 { 512 ACPI_STATUS Status; 513 DT_SUBTABLE *ParentTable; 514 DT_SUBTABLE *Subtable; 515 DT_FIELD *SubtableStart; 516 DT_FIELD **PFieldList = (DT_FIELD **) List; 517 ACPI_MPAM_MSC_NODE *MpamMscNode; 518 ACPI_MPAM_RESOURCE_NODE *MpamResourceNode; 519 UINT32 FuncDepsCount; 520 UINT32 RisLength; 521 ACPI_DMTABLE_INFO *InfoTable; 522 523 ParentTable = DtPeekSubtable (); 524 525 while (*PFieldList) 526 { 527 SubtableStart = *PFieldList; 528 529 /* Main MSC Node table */ 530 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam0, 531 &Subtable); 532 if (ACPI_FAILURE (Status)) 533 { 534 return (Status); 535 } 536 537 MpamMscNode = ACPI_CAST_PTR (ACPI_MPAM_MSC_NODE, Subtable->Buffer); 538 539 ParentTable = DtPeekSubtable (); 540 DtInsertSubtable (ParentTable, Subtable); 541 DtPushSubtable (Subtable); 542 543 ParentTable = DtPeekSubtable (); 544 545 /* 546 * RIS(es) per MSC node have variable lengths depending on how many RISes there and 547 * any how many functional dependencies per RIS. Calculate it in order 548 * to properly set the overall MSC length. 549 */ 550 RisLength = 0; 551 552 /* Iterate over RIS subtables per MSC node */ 553 for (UINT32 ris = 0; ris < MpamMscNode->NumResourceNodes; ris++) 554 { 555 /* Compile RIS subtable */ 556 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1, 557 &Subtable); 558 if (ACPI_FAILURE (Status)) 559 { 560 return (Status); 561 } 562 563 MpamResourceNode = ACPI_CAST_PTR (ACPI_MPAM_RESOURCE_NODE, Subtable->Buffer); 564 DtInsertSubtable (ParentTable, Subtable); 565 DtPushSubtable (Subtable); 566 567 ParentTable = DtPeekSubtable (); 568 569 switch (MpamResourceNode->LocatorType) 570 { 571 case ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE: 572 InfoTable = AcpiDmTableInfoMpam1A; 573 break; 574 case ACPI_MPAM_LOCATION_TYPE_MEMORY: 575 InfoTable = AcpiDmTableInfoMpam1B; 576 break; 577 case ACPI_MPAM_LOCATION_TYPE_SMMU: 578 InfoTable = AcpiDmTableInfoMpam1C; 579 break; 580 case ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE: 581 InfoTable = AcpiDmTableInfoMpam1D; 582 break; 583 case ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE: 584 InfoTable = AcpiDmTableInfoMpam1E; 585 break; 586 case ACPI_MPAM_LOCATION_TYPE_INTERCONNECT: 587 InfoTable = AcpiDmTableInfoMpam1F; 588 break; 589 case ACPI_MPAM_LOCATION_TYPE_UNKNOWN: 590 InfoTable = AcpiDmTableInfoMpam1G; 591 default: 592 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "Resource Locator Type"); 593 return (AE_ERROR); 594 } 595 596 /* Compile Resource Locator Table */ 597 Status = DtCompileTable (PFieldList, InfoTable, 598 &Subtable); 599 600 if (ACPI_FAILURE (Status)) 601 { 602 return (Status); 603 } 604 605 DtInsertSubtable (ParentTable, Subtable); 606 607 /* Compile the number of functional dependencies per RIS */ 608 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1Deps, 609 &Subtable); 610 611 if (ACPI_FAILURE (Status)) 612 { 613 return (Status); 614 } 615 616 DtInsertSubtable (ParentTable, Subtable); 617 FuncDepsCount = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 618 619 RisLength += sizeof(ACPI_MPAM_RESOURCE_NODE) + 620 FuncDepsCount * sizeof(ACPI_MPAM_FUNC_DEPS); 621 622 /* Iterate over functional dependencies per RIS */ 623 for (UINT32 funcDep = 0; funcDep < FuncDepsCount; funcDep++) 624 { 625 /* Compiler functional dependencies table */ 626 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam2, 627 &Subtable); 628 629 if (ACPI_FAILURE (Status)) 630 { 631 return (Status); 632 } 633 634 DtInsertSubtable (ParentTable, Subtable); 635 } 636 637 DtPopSubtable (); 638 } 639 640 /* Check if the length of the MSC is correct and override with the correct length */ 641 if (MpamMscNode->Length != sizeof(ACPI_MPAM_MSC_NODE) + RisLength) 642 { 643 MpamMscNode->Length = (UINT16) (sizeof(ACPI_MPAM_MSC_NODE) + RisLength); 644 DbgPrint (ASL_DEBUG_OUTPUT, "Overriding MSC->Length: %X\n", MpamMscNode->Length); 645 } 646 647 DtPopSubtable (); 648 } 649 650 return (AE_OK); 651 } 652 653 654 /****************************************************************************** 655 * 656 * FUNCTION: DtCompileMpst 657 * 658 * PARAMETERS: List - Current field list pointer 659 * 660 * RETURN: Status 661 * 662 * DESCRIPTION: Compile MPST. 663 * 664 *****************************************************************************/ 665 666 ACPI_STATUS 667 DtCompileMpst ( 668 void **List) 669 { 670 ACPI_STATUS Status; 671 DT_SUBTABLE *Subtable; 672 DT_SUBTABLE *ParentTable; 673 DT_FIELD **PFieldList = (DT_FIELD **) List; 674 ACPI_MPST_CHANNEL *MpstChannelInfo; 675 ACPI_MPST_POWER_NODE *MpstPowerNode; 676 ACPI_MPST_DATA_HDR *MpstDataHeader; 677 UINT16 SubtableCount; 678 UINT32 PowerStateCount; 679 UINT32 ComponentCount; 680 681 682 /* Main table */ 683 684 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable); 685 if (ACPI_FAILURE (Status)) 686 { 687 return (Status); 688 } 689 690 ParentTable = DtPeekSubtable (); 691 DtInsertSubtable (ParentTable, Subtable); 692 DtPushSubtable (Subtable); 693 694 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer); 695 SubtableCount = MpstChannelInfo->PowerNodeCount; 696 697 while (*PFieldList && SubtableCount) 698 { 699 /* Subtable: Memory Power Node(s) */ 700 701 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0, 702 &Subtable); 703 if (ACPI_FAILURE (Status)) 704 { 705 return (Status); 706 } 707 708 ParentTable = DtPeekSubtable (); 709 DtInsertSubtable (ParentTable, Subtable); 710 DtPushSubtable (Subtable); 711 712 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer); 713 PowerStateCount = MpstPowerNode->NumPowerStates; 714 ComponentCount = MpstPowerNode->NumPhysicalComponents; 715 716 ParentTable = DtPeekSubtable (); 717 718 /* Sub-subtables - Memory Power State Structure(s) */ 719 720 while (*PFieldList && PowerStateCount) 721 { 722 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A, 723 &Subtable); 724 if (ACPI_FAILURE (Status)) 725 { 726 return (Status); 727 } 728 729 DtInsertSubtable (ParentTable, Subtable); 730 PowerStateCount--; 731 } 732 733 /* Sub-subtables - Physical Component ID Structure(s) */ 734 735 while (*PFieldList && ComponentCount) 736 { 737 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B, 738 &Subtable); 739 if (ACPI_FAILURE (Status)) 740 { 741 return (Status); 742 } 743 744 DtInsertSubtable (ParentTable, Subtable); 745 ComponentCount--; 746 } 747 748 SubtableCount--; 749 DtPopSubtable (); 750 } 751 752 /* Subtable: Count of Memory Power State Characteristic structures */ 753 754 DtPopSubtable (); 755 756 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable); 757 if (ACPI_FAILURE (Status)) 758 { 759 return (Status); 760 } 761 762 ParentTable = DtPeekSubtable (); 763 DtInsertSubtable (ParentTable, Subtable); 764 DtPushSubtable (Subtable); 765 766 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer); 767 SubtableCount = MpstDataHeader->CharacteristicsCount; 768 769 ParentTable = DtPeekSubtable (); 770 771 /* Subtable: Memory Power State Characteristics structure(s) */ 772 773 while (*PFieldList && SubtableCount) 774 { 775 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2, 776 &Subtable); 777 if (ACPI_FAILURE (Status)) 778 { 779 return (Status); 780 } 781 782 DtInsertSubtable (ParentTable, Subtable); 783 SubtableCount--; 784 } 785 786 DtPopSubtable (); 787 return (AE_OK); 788 } 789 790 791 /****************************************************************************** 792 * 793 * FUNCTION: DtCompileMrrm 794 * 795 * PARAMETERS: List - Current field list pointer 796 * 797 * RETURN: Status 798 * 799 * DESCRIPTION: Compile MRRM. 800 * 801 *****************************************************************************/ 802 803 ACPI_STATUS 804 DtCompileMrrm ( 805 void **List) 806 { 807 ACPI_STATUS Status; 808 DT_SUBTABLE *Subtable; 809 DT_SUBTABLE *ParentTable; 810 DT_FIELD **PFieldList = (DT_FIELD **) List; 811 812 /* Main table */ 813 814 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMrrm, 815 &Subtable); 816 if (ACPI_FAILURE (Status)) 817 { 818 return (Status); 819 } 820 821 ParentTable = DtPeekSubtable (); 822 DtInsertSubtable (ParentTable, Subtable); 823 824 /* Subtables (all are same type) */ 825 826 while (*PFieldList) 827 { 828 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMrrm0, 829 &Subtable); 830 if (ACPI_FAILURE (Status)) 831 { 832 return (Status); 833 } 834 835 DtInsertSubtable (ParentTable, Subtable); 836 } 837 838 return (AE_OK); 839 } 840 841 842 /****************************************************************************** 843 * 844 * FUNCTION: DtCompileMsct 845 * 846 * PARAMETERS: List - Current field list pointer 847 * 848 * RETURN: Status 849 * 850 * DESCRIPTION: Compile MSCT. 851 * 852 *****************************************************************************/ 853 854 ACPI_STATUS 855 DtCompileMsct ( 856 void **List) 857 { 858 ACPI_STATUS Status; 859 860 861 Status = DtCompileTwoSubtables (List, 862 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 863 return (Status); 864 } 865 866 867 /****************************************************************************** 868 * 869 * FUNCTION: DtCompileNfit 870 * 871 * PARAMETERS: List - Current field list pointer 872 * 873 * RETURN: Status 874 * 875 * DESCRIPTION: Compile NFIT. 876 * 877 *****************************************************************************/ 878 879 ACPI_STATUS 880 DtCompileNfit ( 881 void **List) 882 { 883 ACPI_STATUS Status; 884 DT_SUBTABLE *Subtable; 885 DT_SUBTABLE *ParentTable; 886 DT_FIELD **PFieldList = (DT_FIELD **) List; 887 DT_FIELD *SubtableStart; 888 ACPI_NFIT_HEADER *NfitHeader; 889 ACPI_DMTABLE_INFO *InfoTable; 890 UINT32 Count; 891 ACPI_NFIT_INTERLEAVE *Interleave = NULL; 892 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL; 893 894 895 /* Main table */ 896 897 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit, 898 &Subtable); 899 if (ACPI_FAILURE (Status)) 900 { 901 return (Status); 902 } 903 904 ParentTable = DtPeekSubtable (); 905 DtInsertSubtable (ParentTable, Subtable); 906 DtPushSubtable (Subtable); 907 908 /* Subtables */ 909 910 while (*PFieldList) 911 { 912 SubtableStart = *PFieldList; 913 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr, 914 &Subtable); 915 if (ACPI_FAILURE (Status)) 916 { 917 return (Status); 918 } 919 920 ParentTable = DtPeekSubtable (); 921 DtInsertSubtable (ParentTable, Subtable); 922 DtPushSubtable (Subtable); 923 924 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer); 925 926 switch (NfitHeader->Type) 927 { 928 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 929 930 InfoTable = AcpiDmTableInfoNfit0; 931 break; 932 933 case ACPI_NFIT_TYPE_MEMORY_MAP: 934 935 InfoTable = AcpiDmTableInfoNfit1; 936 break; 937 938 case ACPI_NFIT_TYPE_INTERLEAVE: 939 940 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer); 941 InfoTable = AcpiDmTableInfoNfit2; 942 break; 943 944 case ACPI_NFIT_TYPE_SMBIOS: 945 946 InfoTable = AcpiDmTableInfoNfit3; 947 break; 948 949 case ACPI_NFIT_TYPE_CONTROL_REGION: 950 951 InfoTable = AcpiDmTableInfoNfit4; 952 break; 953 954 case ACPI_NFIT_TYPE_DATA_REGION: 955 956 InfoTable = AcpiDmTableInfoNfit5; 957 break; 958 959 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 960 961 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer); 962 InfoTable = AcpiDmTableInfoNfit6; 963 break; 964 965 case ACPI_NFIT_TYPE_CAPABILITIES: 966 967 InfoTable = AcpiDmTableInfoNfit7; 968 break; 969 970 default: 971 972 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT"); 973 return (AE_ERROR); 974 } 975 976 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 977 if (ACPI_FAILURE (Status)) 978 { 979 return (Status); 980 } 981 982 ParentTable = DtPeekSubtable (); 983 DtInsertSubtable (ParentTable, Subtable); 984 DtPopSubtable (); 985 986 switch (NfitHeader->Type) 987 { 988 case ACPI_NFIT_TYPE_INTERLEAVE: 989 990 Count = 0; 991 DtPushSubtable (Subtable); 992 while (*PFieldList) 993 { 994 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a, 995 &Subtable); 996 if (ACPI_FAILURE (Status)) 997 { 998 return (Status); 999 } 1000 1001 if (!Subtable) 1002 { 1003 DtPopSubtable (); 1004 break; 1005 } 1006 1007 ParentTable = DtPeekSubtable (); 1008 DtInsertSubtable (ParentTable, Subtable); 1009 Count++; 1010 } 1011 1012 Interleave->LineCount = Count; 1013 break; 1014 1015 case ACPI_NFIT_TYPE_SMBIOS: 1016 1017 if (*PFieldList) 1018 { 1019 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a, 1020 &Subtable); 1021 if (ACPI_FAILURE (Status)) 1022 { 1023 return (Status); 1024 } 1025 1026 if (Subtable) 1027 { 1028 DtInsertSubtable (ParentTable, Subtable); 1029 } 1030 } 1031 break; 1032 1033 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 1034 1035 Count = 0; 1036 DtPushSubtable (Subtable); 1037 while (*PFieldList) 1038 { 1039 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a, 1040 &Subtable); 1041 if (ACPI_FAILURE (Status)) 1042 { 1043 return (Status); 1044 } 1045 1046 if (!Subtable) 1047 { 1048 DtPopSubtable (); 1049 break; 1050 } 1051 1052 ParentTable = DtPeekSubtable (); 1053 DtInsertSubtable (ParentTable, Subtable); 1054 Count++; 1055 } 1056 1057 Hint->HintCount = (UINT16) Count; 1058 break; 1059 1060 default: 1061 break; 1062 } 1063 } 1064 1065 return (AE_OK); 1066 } 1067 1068 1069 /****************************************************************************** 1070 * 1071 * FUNCTION: DtCompilePcct 1072 * 1073 * PARAMETERS: List - Current field list pointer 1074 * 1075 * RETURN: Status 1076 * 1077 * DESCRIPTION: Compile PCCT. 1078 * 1079 *****************************************************************************/ 1080 1081 ACPI_STATUS 1082 DtCompilePcct ( 1083 void **List) 1084 { 1085 ACPI_STATUS Status; 1086 DT_SUBTABLE *Subtable; 1087 DT_SUBTABLE *ParentTable; 1088 DT_FIELD **PFieldList = (DT_FIELD **) List; 1089 DT_FIELD *SubtableStart; 1090 ACPI_SUBTABLE_HEADER *PcctHeader; 1091 ACPI_DMTABLE_INFO *InfoTable; 1092 1093 1094 /* Main table */ 1095 1096 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct, 1097 &Subtable); 1098 if (ACPI_FAILURE (Status)) 1099 { 1100 return (Status); 1101 } 1102 1103 ParentTable = DtPeekSubtable (); 1104 DtInsertSubtable (ParentTable, Subtable); 1105 1106 /* Subtables */ 1107 1108 while (*PFieldList) 1109 { 1110 SubtableStart = *PFieldList; 1111 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, 1112 &Subtable); 1113 if (ACPI_FAILURE (Status)) 1114 { 1115 return (Status); 1116 } 1117 1118 ParentTable = DtPeekSubtable (); 1119 DtInsertSubtable (ParentTable, Subtable); 1120 DtPushSubtable (Subtable); 1121 1122 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1123 1124 switch (PcctHeader->Type) 1125 { 1126 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: 1127 1128 InfoTable = AcpiDmTableInfoPcct0; 1129 break; 1130 1131 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE: 1132 1133 InfoTable = AcpiDmTableInfoPcct1; 1134 break; 1135 1136 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2: 1137 1138 InfoTable = AcpiDmTableInfoPcct2; 1139 break; 1140 1141 case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE: 1142 1143 InfoTable = AcpiDmTableInfoPcct3; 1144 break; 1145 1146 case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE: 1147 1148 InfoTable = AcpiDmTableInfoPcct4; 1149 break; 1150 1151 case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE: 1152 1153 InfoTable = AcpiDmTableInfoPcct5; 1154 break; 1155 1156 default: 1157 1158 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); 1159 return (AE_ERROR); 1160 } 1161 1162 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1163 if (ACPI_FAILURE (Status)) 1164 { 1165 return (Status); 1166 } 1167 1168 ParentTable = DtPeekSubtable (); 1169 DtInsertSubtable (ParentTable, Subtable); 1170 DtPopSubtable (); 1171 } 1172 1173 return (AE_OK); 1174 } 1175 1176 1177 /****************************************************************************** 1178 * 1179 * FUNCTION: DtCompilePdtt 1180 * 1181 * PARAMETERS: List - Current field list pointer 1182 * 1183 * RETURN: Status 1184 * 1185 * DESCRIPTION: Compile PDTT. 1186 * 1187 *****************************************************************************/ 1188 1189 ACPI_STATUS 1190 DtCompilePdtt ( 1191 void **List) 1192 { 1193 ACPI_STATUS Status; 1194 DT_SUBTABLE *Subtable; 1195 DT_SUBTABLE *ParentTable; 1196 DT_FIELD **PFieldList = (DT_FIELD **) List; 1197 ACPI_TABLE_PDTT *PdttHeader; 1198 UINT32 Count = 0; 1199 1200 1201 /* Main table */ 1202 1203 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable); 1204 if (ACPI_FAILURE (Status)) 1205 { 1206 return (Status); 1207 } 1208 1209 ParentTable = DtPeekSubtable (); 1210 DtInsertSubtable (ParentTable, Subtable); 1211 1212 PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer); 1213 PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT); 1214 1215 /* There is only one type of subtable at this time, no need to decode */ 1216 1217 while (*PFieldList) 1218 { 1219 /* List of subchannel IDs, each 2 bytes */ 1220 1221 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0, 1222 &Subtable); 1223 if (ACPI_FAILURE (Status)) 1224 { 1225 return (Status); 1226 } 1227 1228 DtInsertSubtable (ParentTable, Subtable); 1229 Count++; 1230 } 1231 1232 PdttHeader->TriggerCount = (UINT8) Count; 1233 return (AE_OK); 1234 } 1235 1236 1237 /****************************************************************************** 1238 * 1239 * FUNCTION: DtCompilePhat 1240 * 1241 * PARAMETERS: List - Current field list pointer 1242 * 1243 * RETURN: Status 1244 * 1245 * DESCRIPTION: Compile Phat. 1246 * 1247 *****************************************************************************/ 1248 1249 ACPI_STATUS 1250 DtCompilePhat ( 1251 void **List) 1252 { 1253 ACPI_STATUS Status = AE_OK; 1254 DT_SUBTABLE *Subtable; 1255 DT_SUBTABLE *ParentTable; 1256 DT_FIELD **PFieldList = (DT_FIELD **) List; 1257 ACPI_PHAT_HEADER *PhatHeader; 1258 ACPI_DMTABLE_INFO *Info; 1259 ACPI_PHAT_VERSION_DATA *VersionData; 1260 UINT32 DeviceDataLength; 1261 UINT32 RecordCount; 1262 DT_FIELD *DataOffsetField; 1263 DT_FIELD *DevicePathField; 1264 UINT32 TableOffset = 0; 1265 UINT32 DataOffsetValue; 1266 UINT32 i; 1267 1268 1269 /* The table consists of subtables */ 1270 1271 while (*PFieldList) 1272 { 1273 /* Compile the common subtable header */ 1274 1275 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable); 1276 if (ACPI_FAILURE (Status)) 1277 { 1278 return (Status); 1279 } 1280 1281 TableOffset += Subtable->Length; 1282 DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length); 1283 1284 ParentTable = DtPeekSubtable (); 1285 DtInsertSubtable (ParentTable, Subtable); 1286 DtPushSubtable (Subtable); 1287 1288 PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer); 1289 1290 switch (PhatHeader->Type) 1291 { 1292 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 1293 1294 /* Compile the middle portion of the Firmware Version Data */ 1295 1296 Info = AcpiDmTableInfoPhat0; 1297 PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA); 1298 DataOffsetField = NULL; 1299 break; 1300 1301 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 1302 1303 DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n", 1304 (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length); 1305 1306 DataOffsetField = *PFieldList; 1307 1308 /* Walk the field list to get to the "Device-specific data Offset" field */ 1309 1310 TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA); 1311 for (i = 0; i < 3; i++) 1312 { 1313 DataOffsetField = DataOffsetField->Next; 1314 DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n", 1315 TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); 1316 } 1317 1318 /* Convert DataOffsetField->Value (a char * string) to an integer value */ 1319 1320 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); 1321 1322 /* 1323 * Get the next field (Device Path): 1324 * DataOffsetField points to "Device-Specific Offset", next field is 1325 * "Device Path". 1326 */ 1327 DevicePathField = DataOffsetField->Next; 1328 1329 /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */ 1330 1331 DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2; 1332 TableOffset += DevicePathField->StringLength; 1333 1334 DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n", 1335 TableOffset, Subtable->Length, DevicePathField->StringLength); 1336 1337 /* Set the DataOffsetField to the current TableOffset */ 1338 /* Must set the DataOffsetField here (not later) */ 1339 1340 if (DataOffsetValue != 0) 1341 { 1342 snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset); 1343 } 1344 1345 DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length); 1346 1347 DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: " 1348 "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n", 1349 TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength, 1350 DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset); 1351 1352 /* Compile the middle portion of the Health Data Record */ 1353 1354 Info = AcpiDmTableInfoPhat1; 1355 PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA); 1356 break; 1357 1358 default: 1359 1360 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 1361 return (AE_ERROR); 1362 } 1363 1364 /* Compile either the Version Data or the Health Data */ 1365 1366 Status = DtCompileTable (PFieldList, Info, &Subtable); 1367 if (ACPI_FAILURE (Status)) 1368 { 1369 return (Status); 1370 } 1371 1372 DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n", 1373 TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length); 1374 1375 ParentTable = DtPeekSubtable (); 1376 DtInsertSubtable (ParentTable, Subtable); 1377 1378 switch (PhatHeader->Type) 1379 { 1380 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 1381 1382 VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, 1383 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER))); 1384 RecordCount = VersionData->ElementCount; 1385 1386 /* Compile all of the Version Elements */ 1387 1388 while (RecordCount) 1389 { 1390 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a, 1391 &Subtable); 1392 if (ACPI_FAILURE (Status)) 1393 { 1394 return (Status); 1395 } 1396 1397 ParentTable = DtPeekSubtable (); 1398 DtInsertSubtable (ParentTable, Subtable); 1399 1400 TableOffset += Subtable->Length; 1401 RecordCount--; 1402 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT); 1403 } 1404 1405 DtPopSubtable (); 1406 break; 1407 1408 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 1409 1410 /* Compile the Device Path */ 1411 1412 DeviceDataLength = Subtable->Length; 1413 TableOffset += Subtable->Length; 1414 1415 DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: " 1416 "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength, 1417 (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value, 1418 Subtable->Length, TableOffset); 1419 1420 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable); 1421 if (ACPI_FAILURE (Status)) 1422 { 1423 return (Status); 1424 } 1425 ParentTable = DtPeekSubtable (); 1426 DtInsertSubtable (ParentTable, Subtable); 1427 1428 /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */ 1429 1430 if (!*PFieldList) 1431 { 1432 DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n"); 1433 return (AE_OK); 1434 } 1435 1436 DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s" 1437 " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n", 1438 DeviceDataLength, (*PFieldList)->Name, TableOffset, 1439 (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length); 1440 1441 PhatHeader->Length += (UINT16) Subtable->Length; 1442 1443 /* Convert DataOffsetField->Value (a hex char * string) to an integer value */ 1444 1445 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); 1446 1447 DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n", 1448 DataOffsetValue, TableOffset); 1449 if (DataOffsetValue != 0) 1450 { 1451 /* Compile Device-Specific Data - only if the Data Offset is non-zero */ 1452 1453 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable); 1454 if (ACPI_FAILURE (Status)) 1455 { 1456 return (Status); 1457 } 1458 1459 DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n", 1460 Subtable, TableOffset); 1461 if (Subtable) 1462 { 1463 DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: " 1464 "%X FieldName \"%s\" SubtableLength %X\n", 1465 DeviceDataLength, DataOffsetField->Name, Subtable->Length); 1466 1467 DeviceDataLength += Subtable->Length; 1468 1469 ParentTable = DtPeekSubtable (); 1470 DtInsertSubtable (ParentTable, Subtable); 1471 1472 PhatHeader->Length += (UINT16) Subtable->Length; 1473 } 1474 } 1475 1476 DtPopSubtable (); 1477 1478 DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n", 1479 DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); 1480 break; 1481 1482 default: 1483 1484 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 1485 return (AE_ERROR); 1486 } 1487 } 1488 1489 return (Status); 1490 } 1491 1492 1493 /****************************************************************************** 1494 * 1495 * FUNCTION: DtCompilePmtt 1496 * 1497 * PARAMETERS: List - Current field list pointer 1498 * 1499 * RETURN: Status 1500 * 1501 * DESCRIPTION: Compile PMTT. 1502 * 1503 *****************************************************************************/ 1504 1505 ACPI_STATUS 1506 DtCompilePmtt ( 1507 void **List) 1508 { 1509 ACPI_STATUS Status; 1510 DT_SUBTABLE *Subtable; 1511 DT_SUBTABLE *ParentTable; 1512 DT_FIELD **PFieldList = (DT_FIELD **) List; 1513 DT_FIELD *SubtableStart; 1514 UINT16 Type; 1515 1516 1517 /* Main table */ 1518 1519 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable); 1520 if (ACPI_FAILURE (Status)) 1521 { 1522 return (Status); 1523 } 1524 1525 ParentTable = DtPeekSubtable (); 1526 DtInsertSubtable (ParentTable, Subtable); 1527 DtPushSubtable (Subtable); 1528 1529 /* Subtables */ 1530 1531 while (*PFieldList) 1532 { 1533 SubtableStart = *PFieldList; 1534 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1535 1536 switch (Type) 1537 { 1538 case ACPI_PMTT_TYPE_SOCKET: 1539 1540 /* Subtable: Socket Structure */ 1541 1542 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n"); 1543 1544 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, 1545 &Subtable); 1546 if (ACPI_FAILURE (Status)) 1547 { 1548 return (Status); 1549 } 1550 1551 break; 1552 1553 case ACPI_PMTT_TYPE_CONTROLLER: 1554 1555 /* Subtable: Memory Controller Structure */ 1556 1557 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n"); 1558 1559 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, 1560 &Subtable); 1561 if (ACPI_FAILURE (Status)) 1562 { 1563 return (Status); 1564 } 1565 1566 break; 1567 1568 case ACPI_PMTT_TYPE_DIMM: 1569 1570 /* Subtable: Physical Component (DIMM) Structure */ 1571 1572 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n"); 1573 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, 1574 &Subtable); 1575 if (ACPI_FAILURE (Status)) 1576 { 1577 return (Status); 1578 } 1579 1580 break; 1581 1582 case ACPI_PMTT_TYPE_VENDOR: 1583 1584 /* Subtable: Vendor-specific Structure */ 1585 1586 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n"); 1587 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor, 1588 &Subtable); 1589 if (ACPI_FAILURE (Status)) 1590 { 1591 return (Status); 1592 } 1593 1594 break; 1595 1596 default: 1597 1598 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); 1599 return (AE_ERROR); 1600 } 1601 1602 DtInsertSubtable (ParentTable, Subtable); 1603 } 1604 1605 return (Status); 1606 } 1607 1608 1609 /****************************************************************************** 1610 * 1611 * FUNCTION: DtCompilePptt 1612 * 1613 * PARAMETERS: List - Current field list pointer 1614 * 1615 * RETURN: Status 1616 * 1617 * DESCRIPTION: Compile PPTT. 1618 * 1619 *****************************************************************************/ 1620 1621 ACPI_STATUS 1622 DtCompilePptt ( 1623 void **List) 1624 { 1625 ACPI_STATUS Status; 1626 ACPI_SUBTABLE_HEADER *PpttHeader; 1627 ACPI_PPTT_PROCESSOR *PpttProcessor = NULL; 1628 DT_SUBTABLE *Subtable; 1629 DT_SUBTABLE *ParentTable; 1630 ACPI_DMTABLE_INFO *InfoTable; 1631 DT_FIELD **PFieldList = (DT_FIELD **) List; 1632 DT_FIELD *SubtableStart; 1633 ACPI_TABLE_HEADER *PpttAcpiHeader; 1634 1635 1636 ParentTable = DtPeekSubtable (); 1637 1638 PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1639 1640 while (*PFieldList) 1641 { 1642 SubtableStart = *PFieldList; 1643 1644 /* Compile PPTT subtable header */ 1645 1646 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr, 1647 &Subtable); 1648 if (ACPI_FAILURE (Status)) 1649 { 1650 return (Status); 1651 } 1652 DtInsertSubtable (ParentTable, Subtable); 1653 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1654 PpttHeader->Length = (UINT8)(Subtable->Length); 1655 1656 switch (PpttHeader->Type) 1657 { 1658 case ACPI_PPTT_TYPE_PROCESSOR: 1659 1660 InfoTable = AcpiDmTableInfoPptt0; 1661 break; 1662 1663 case ACPI_PPTT_TYPE_CACHE: 1664 1665 if (PpttAcpiHeader->Revision < 3) 1666 { 1667 InfoTable = AcpiDmTableInfoPptt1; 1668 } 1669 else 1670 { 1671 InfoTable = AcpiDmTableInfoPptt1a; 1672 } 1673 break; 1674 1675 case ACPI_PPTT_TYPE_ID: 1676 1677 InfoTable = AcpiDmTableInfoPptt2; 1678 break; 1679 1680 default: 1681 1682 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT"); 1683 return (AE_ERROR); 1684 } 1685 1686 /* Compile PPTT subtable body */ 1687 1688 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1689 if (ACPI_FAILURE (Status)) 1690 { 1691 return (Status); 1692 } 1693 DtInsertSubtable (ParentTable, Subtable); 1694 PpttHeader->Length += (UINT8)(Subtable->Length); 1695 1696 /* Compile PPTT subtable additional */ 1697 1698 switch (PpttHeader->Type) 1699 { 1700 case ACPI_PPTT_TYPE_PROCESSOR: 1701 1702 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR, 1703 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER)); 1704 if (PpttProcessor) 1705 { 1706 /* Compile initiator proximity domain list */ 1707 1708 PpttProcessor->NumberOfPrivResources = 0; 1709 while (*PFieldList) 1710 { 1711 Status = DtCompileTable (PFieldList, 1712 AcpiDmTableInfoPptt0a, &Subtable); 1713 if (ACPI_FAILURE (Status)) 1714 { 1715 return (Status); 1716 } 1717 if (!Subtable) 1718 { 1719 break; 1720 } 1721 1722 DtInsertSubtable (ParentTable, Subtable); 1723 PpttHeader->Length += (UINT8)(Subtable->Length); 1724 PpttProcessor->NumberOfPrivResources++; 1725 } 1726 } 1727 break; 1728 default: 1729 1730 break; 1731 } 1732 } 1733 1734 return (AE_OK); 1735 } 1736 1737 1738 /****************************************************************************** 1739 * 1740 * FUNCTION: DtCompilePrmt 1741 * 1742 * PARAMETERS: List - Current field list pointer 1743 * 1744 * RETURN: Status 1745 * 1746 * DESCRIPTION: Compile PRMT. 1747 * 1748 *****************************************************************************/ 1749 1750 ACPI_STATUS 1751 DtCompilePrmt ( 1752 void **List) 1753 { 1754 ACPI_STATUS Status; 1755 ACPI_TABLE_PRMT_HEADER *PrmtHeader; 1756 ACPI_PRMT_MODULE_INFO *PrmtModuleInfo; 1757 DT_SUBTABLE *Subtable; 1758 DT_SUBTABLE *ParentTable; 1759 DT_FIELD **PFieldList = (DT_FIELD **) List; 1760 UINT32 i, j; 1761 1762 ParentTable = DtPeekSubtable (); 1763 1764 /* Compile PRMT subtable header */ 1765 1766 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr, 1767 &Subtable); 1768 if (ACPI_FAILURE (Status)) 1769 { 1770 return (Status); 1771 } 1772 DtInsertSubtable (ParentTable, Subtable); 1773 PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer); 1774 1775 for (i = 0; i < PrmtHeader->ModuleInfoCount; i++) 1776 { 1777 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule, 1778 &Subtable); 1779 if (ACPI_FAILURE (Status)) 1780 { 1781 return (Status); 1782 } 1783 DtInsertSubtable (ParentTable, Subtable); 1784 PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer); 1785 1786 for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++) 1787 { 1788 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler, 1789 &Subtable); 1790 if (ACPI_FAILURE (Status)) 1791 { 1792 return (Status); 1793 } 1794 DtInsertSubtable (ParentTable, Subtable); 1795 } 1796 } 1797 1798 return (AE_OK); 1799 } 1800 1801 1802 /****************************************************************************** 1803 * 1804 * FUNCTION: DtCompileRas2 1805 * 1806 * PARAMETERS: List - Current field list pointer 1807 * 1808 * RETURN: Status 1809 * 1810 * DESCRIPTION: Compile RAS2. 1811 * 1812 *****************************************************************************/ 1813 1814 ACPI_STATUS 1815 DtCompileRas2 ( 1816 void **List) 1817 { 1818 ACPI_STATUS Status; 1819 DT_SUBTABLE *Subtable; 1820 DT_SUBTABLE *ParentTable; 1821 DT_FIELD **PFieldList = (DT_FIELD **) List; 1822 ACPI_TABLE_RAS2 *Ras2Header; 1823 UINT32 Count = 0; 1824 1825 1826 /* Main table */ 1827 1828 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2, &Subtable); 1829 if (ACPI_FAILURE (Status)) 1830 { 1831 return (Status); 1832 } 1833 1834 ParentTable = DtPeekSubtable (); 1835 DtInsertSubtable (ParentTable, Subtable); 1836 1837 Ras2Header = ACPI_CAST_PTR (ACPI_TABLE_RAS2, ParentTable->Buffer); 1838 1839 /* There is only one type of subtable at this time, no need to decode */ 1840 1841 while (*PFieldList) 1842 { 1843 /* List of RAS2 PCC descriptors, each 8 bytes */ 1844 1845 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2PccDesc, 1846 &Subtable); 1847 if (ACPI_FAILURE (Status)) 1848 { 1849 return (Status); 1850 } 1851 1852 DtInsertSubtable (ParentTable, Subtable); 1853 Count++; 1854 } 1855 1856 Ras2Header->NumPccDescs = (UINT8) Count; 1857 return (AE_OK); 1858 } 1859 1860 1861 /****************************************************************************** 1862 * 1863 * FUNCTION: DtCompileRgrt 1864 * 1865 * PARAMETERS: List - Current field list pointer 1866 * 1867 * RETURN: Status 1868 * 1869 * DESCRIPTION: Compile RGRT. 1870 * 1871 *****************************************************************************/ 1872 1873 ACPI_STATUS 1874 DtCompileRgrt ( 1875 void **List) 1876 { 1877 ACPI_STATUS Status; 1878 DT_SUBTABLE *Subtable; 1879 DT_SUBTABLE *ParentTable; 1880 DT_FIELD **PFieldList = (DT_FIELD **) List; 1881 1882 1883 /* Compile the main table */ 1884 1885 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt, 1886 &Subtable); 1887 if (ACPI_FAILURE (Status)) 1888 { 1889 return (Status); 1890 } 1891 1892 ParentTable = DtPeekSubtable (); 1893 DtInsertSubtable (ParentTable, Subtable); 1894 1895 /* Compile the "Subtable" -- actually just the binary (PNG) image */ 1896 1897 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0, 1898 &Subtable); 1899 if (ACPI_FAILURE (Status)) 1900 { 1901 return (Status); 1902 } 1903 1904 DtInsertSubtable (ParentTable, Subtable); 1905 return (AE_OK); 1906 } 1907 1908 1909 /****************************************************************************** 1910 * 1911 * FUNCTION: DtCompileRhct 1912 * 1913 * PARAMETERS: List - Current field list pointer 1914 * 1915 * RETURN: Status 1916 * 1917 * DESCRIPTION: Compile RHCT. 1918 * 1919 *****************************************************************************/ 1920 1921 ACPI_STATUS 1922 DtCompileRhct ( 1923 void **List) 1924 { 1925 ACPI_STATUS Status; 1926 ACPI_RHCT_NODE_HEADER *RhctHeader; 1927 ACPI_RHCT_HART_INFO *RhctHartInfo; 1928 DT_SUBTABLE *Subtable; 1929 DT_SUBTABLE *ParentTable; 1930 ACPI_DMTABLE_INFO *InfoTable; 1931 DT_FIELD **PFieldList = (DT_FIELD **) List; 1932 DT_FIELD *SubtableStart; 1933 ACPI_TABLE_RHCT *Table; 1934 BOOLEAN FirstNode = TRUE; 1935 1936 1937 /* Compile the main table */ 1938 1939 ParentTable = DtPeekSubtable (); 1940 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct, 1941 &Subtable); 1942 if (ACPI_FAILURE (Status)) 1943 { 1944 return (Status); 1945 } 1946 DtInsertSubtable (ParentTable, Subtable); 1947 Table = ACPI_CAST_PTR (ACPI_TABLE_RHCT, ParentTable->Buffer); 1948 Table->NodeCount = 0; 1949 Table->NodeOffset = sizeof (ACPI_TABLE_RHCT); 1950 1951 while (*PFieldList) 1952 { 1953 SubtableStart = *PFieldList; 1954 1955 /* Compile RHCT subtable header */ 1956 1957 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr, 1958 &Subtable); 1959 if (ACPI_FAILURE (Status)) 1960 { 1961 return (Status); 1962 } 1963 DtInsertSubtable (ParentTable, Subtable); 1964 RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer); 1965 1966 DtPushSubtable (Subtable); 1967 ParentTable = DtPeekSubtable (); 1968 Table->NodeCount++; 1969 1970 switch (RhctHeader->Type) 1971 { 1972 case ACPI_RHCT_NODE_TYPE_ISA_STRING: 1973 1974 InfoTable = AcpiDmTableInfoRhctIsa1; 1975 break; 1976 1977 case ACPI_RHCT_NODE_TYPE_HART_INFO: 1978 1979 InfoTable = AcpiDmTableInfoRhctHartInfo1; 1980 break; 1981 1982 case ACPI_RHCT_NODE_TYPE_CMO: 1983 1984 InfoTable = AcpiDmTableInfoRhctCmo1; 1985 break; 1986 1987 case ACPI_RHCT_NODE_TYPE_MMU: 1988 1989 InfoTable = AcpiDmTableInfoRhctMmu1; 1990 break; 1991 1992 default: 1993 1994 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT"); 1995 return (AE_ERROR); 1996 } 1997 1998 /* Compile RHCT subtable body */ 1999 2000 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2001 if (ACPI_FAILURE (Status)) 2002 { 2003 return (Status); 2004 } 2005 DtInsertSubtable (ParentTable, Subtable); 2006 if (FirstNode) 2007 { 2008 Table->NodeOffset = ACPI_PTR_DIFF(ParentTable->Buffer, Table); 2009 FirstNode = FALSE; 2010 } 2011 2012 /* Compile RHCT subtable additionals */ 2013 2014 switch (RhctHeader->Type) 2015 { 2016 case ACPI_RHCT_NODE_TYPE_ISA_STRING: 2017 2018 /* 2019 * Padding - Variable-length data 2020 * Optionally allows the padding of the ISA string to be used 2021 * for filling this field. 2022 */ 2023 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctIsaPad, 2024 &Subtable); 2025 if (ACPI_FAILURE (Status)) 2026 { 2027 return (Status); 2028 } 2029 if (Subtable) 2030 { 2031 DtInsertSubtable (ParentTable, Subtable); 2032 } 2033 break; 2034 2035 case ACPI_RHCT_NODE_TYPE_HART_INFO: 2036 2037 RhctHartInfo = ACPI_CAST_PTR (ACPI_RHCT_HART_INFO, 2038 Subtable->Buffer); 2039 RhctHartInfo->NumOffsets = 0; 2040 while (*PFieldList) 2041 { 2042 Status = DtCompileTable (PFieldList, 2043 AcpiDmTableInfoRhctHartInfo2, &Subtable); 2044 if (ACPI_FAILURE (Status)) 2045 { 2046 return (Status); 2047 } 2048 if (!Subtable) 2049 { 2050 break; 2051 } 2052 DtInsertSubtable (ParentTable, Subtable); 2053 RhctHartInfo->NumOffsets++; 2054 } 2055 break; 2056 2057 default: 2058 2059 break; 2060 } 2061 2062 DtPopSubtable (); 2063 ParentTable = DtPeekSubtable (); 2064 } 2065 2066 return (AE_OK); 2067 } 2068 2069 2070 /****************************************************************************** 2071 * 2072 * FUNCTION: DtCompileRsdt 2073 * 2074 * PARAMETERS: List - Current field list pointer 2075 * 2076 * RETURN: Status 2077 * 2078 * DESCRIPTION: Compile RSDT. 2079 * 2080 *****************************************************************************/ 2081 2082 ACPI_STATUS 2083 DtCompileRsdt ( 2084 void **List) 2085 { 2086 DT_SUBTABLE *Subtable; 2087 DT_SUBTABLE *ParentTable; 2088 DT_FIELD *FieldList = *(DT_FIELD **) List; 2089 UINT32 Address; 2090 2091 2092 ParentTable = DtPeekSubtable (); 2093 2094 while (FieldList) 2095 { 2096 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 2097 2098 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 2099 DtInsertSubtable (ParentTable, Subtable); 2100 FieldList = FieldList->Next; 2101 } 2102 2103 return (AE_OK); 2104 } 2105 2106 2107 /****************************************************************************** 2108 * 2109 * FUNCTION: DtCompileS3pt 2110 * 2111 * PARAMETERS: PFieldList - Current field list pointer 2112 * 2113 * RETURN: Status 2114 * 2115 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 2116 * 2117 *****************************************************************************/ 2118 2119 ACPI_STATUS 2120 DtCompileS3pt ( 2121 DT_FIELD **PFieldList) 2122 { 2123 ACPI_STATUS Status; 2124 ACPI_FPDT_HEADER *S3ptHeader; 2125 DT_SUBTABLE *Subtable; 2126 DT_SUBTABLE *ParentTable; 2127 ACPI_DMTABLE_INFO *InfoTable; 2128 DT_FIELD *SubtableStart; 2129 2130 2131 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 2132 &AslGbl_RootTable); 2133 if (ACPI_FAILURE (Status)) 2134 { 2135 return (Status); 2136 } 2137 2138 DtPushSubtable (AslGbl_RootTable); 2139 2140 while (*PFieldList) 2141 { 2142 SubtableStart = *PFieldList; 2143 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 2144 &Subtable); 2145 if (ACPI_FAILURE (Status)) 2146 { 2147 return (Status); 2148 } 2149 2150 ParentTable = DtPeekSubtable (); 2151 DtInsertSubtable (ParentTable, Subtable); 2152 DtPushSubtable (Subtable); 2153 2154 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 2155 2156 switch (S3ptHeader->Type) 2157 { 2158 case ACPI_S3PT_TYPE_RESUME: 2159 2160 InfoTable = AcpiDmTableInfoS3pt0; 2161 break; 2162 2163 case ACPI_S3PT_TYPE_SUSPEND: 2164 2165 InfoTable = AcpiDmTableInfoS3pt1; 2166 break; 2167 2168 default: 2169 2170 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 2171 return (AE_ERROR); 2172 } 2173 2174 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2175 if (ACPI_FAILURE (Status)) 2176 { 2177 return (Status); 2178 } 2179 2180 ParentTable = DtPeekSubtable (); 2181 DtInsertSubtable (ParentTable, Subtable); 2182 DtPopSubtable (); 2183 } 2184 2185 return (AE_OK); 2186 } 2187 2188 2189 /****************************************************************************** 2190 * 2191 * FUNCTION: DtCompileSdev 2192 * 2193 * PARAMETERS: List - Current field list pointer 2194 * 2195 * RETURN: Status 2196 * 2197 * DESCRIPTION: Compile SDEV. 2198 * 2199 *****************************************************************************/ 2200 2201 ACPI_STATUS 2202 DtCompileSdev ( 2203 void **List) 2204 { 2205 ACPI_STATUS Status; 2206 ACPI_SDEV_HEADER *SdevHeader; 2207 ACPI_SDEV_HEADER *SecureComponentHeader; 2208 DT_SUBTABLE *Subtable; 2209 DT_SUBTABLE *ParentTable; 2210 ACPI_DMTABLE_INFO *InfoTable; 2211 ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL; 2212 DT_FIELD **PFieldList = (DT_FIELD **) List; 2213 DT_FIELD *SubtableStart; 2214 ACPI_SDEV_PCIE *Pcie = NULL; 2215 ACPI_SDEV_NAMESPACE *Namesp = NULL; 2216 UINT32 EntryCount; 2217 ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL; 2218 UINT16 ComponentLength = 0; 2219 2220 2221 /* Subtables */ 2222 2223 while (*PFieldList) 2224 { 2225 /* Compile common SDEV subtable header */ 2226 2227 SubtableStart = *PFieldList; 2228 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr, 2229 &Subtable); 2230 if (ACPI_FAILURE (Status)) 2231 { 2232 return (Status); 2233 } 2234 2235 ParentTable = DtPeekSubtable (); 2236 DtInsertSubtable (ParentTable, Subtable); 2237 DtPushSubtable (Subtable); 2238 2239 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2240 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER)); 2241 2242 switch (SdevHeader->Type) 2243 { 2244 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2245 2246 InfoTable = AcpiDmTableInfoSdev0; 2247 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer); 2248 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT, 2249 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE))); 2250 break; 2251 2252 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2253 2254 InfoTable = AcpiDmTableInfoSdev1; 2255 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer); 2256 break; 2257 2258 default: 2259 2260 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2261 return (AE_ERROR); 2262 } 2263 2264 /* Compile SDEV subtable body */ 2265 2266 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2267 if (ACPI_FAILURE (Status)) 2268 { 2269 return (Status); 2270 } 2271 2272 ParentTable = DtPeekSubtable (); 2273 DtInsertSubtable (ParentTable, Subtable); 2274 2275 /* Optional data fields are appended to the main subtable body */ 2276 2277 switch (SdevHeader->Type) 2278 { 2279 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2280 2281 /* 2282 * Device Id Offset will be be calculated differently depending on 2283 * the presence of secure access components. 2284 */ 2285 Namesp->DeviceIdOffset = 0; 2286 ComponentLength = 0; 2287 2288 /* If the secure access component exists, get the structures */ 2289 2290 if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT) 2291 { 2292 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b, 2293 &Subtable); 2294 if (ACPI_FAILURE (Status)) 2295 { 2296 return (Status); 2297 } 2298 ParentTable = DtPeekSubtable (); 2299 DtInsertSubtable (ParentTable, Subtable); 2300 2301 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2302 2303 /* Compile a secure access component header */ 2304 2305 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr, 2306 &Subtable); 2307 if (ACPI_FAILURE (Status)) 2308 { 2309 return (Status); 2310 } 2311 ParentTable = DtPeekSubtable (); 2312 DtInsertSubtable (ParentTable, Subtable); 2313 2314 /* Compile the secure access component */ 2315 2316 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2317 switch (SecureComponentHeader->Type) 2318 { 2319 case ACPI_SDEV_TYPE_ID_COMPONENT: 2320 2321 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId; 2322 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT); 2323 ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT); 2324 break; 2325 2326 case ACPI_SDEV_TYPE_MEM_COMPONENT: 2327 2328 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem; 2329 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT); 2330 ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT); 2331 break; 2332 2333 default: 2334 2335 /* Any other secure component types are undefined */ 2336 2337 return (AE_ERROR); 2338 } 2339 2340 Status = DtCompileTable (PFieldList, SecureComponentInfoTable, 2341 &Subtable); 2342 if (ACPI_FAILURE (Status)) 2343 { 2344 return (Status); 2345 } 2346 ParentTable = DtPeekSubtable (); 2347 DtInsertSubtable (ParentTable, Subtable); 2348 2349 SecureComponent->SecureComponentOffset = 2350 sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT); 2351 SecureComponent->SecureComponentLength = ComponentLength; 2352 2353 2354 /* 2355 * Add the secure component to the subtable to be added for the 2356 * the namespace subtable's length 2357 */ 2358 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2359 } 2360 2361 /* Append DeviceId namespace string */ 2362 2363 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a, 2364 &Subtable); 2365 if (ACPI_FAILURE (Status)) 2366 { 2367 return (Status); 2368 } 2369 2370 if (!Subtable) 2371 { 2372 break; 2373 } 2374 2375 ParentTable = DtPeekSubtable (); 2376 DtInsertSubtable (ParentTable, Subtable); 2377 2378 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE); 2379 2380 Namesp->DeviceIdLength = (UINT16) Subtable->Length; 2381 2382 /* Append Vendor data */ 2383 2384 Namesp->VendorDataLength = 0; 2385 Namesp->VendorDataOffset = 0; 2386 2387 if (*PFieldList) 2388 { 2389 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2390 &Subtable); 2391 if (ACPI_FAILURE (Status)) 2392 { 2393 return (Status); 2394 } 2395 2396 if (Subtable) 2397 { 2398 ParentTable = DtPeekSubtable (); 2399 DtInsertSubtable (ParentTable, Subtable); 2400 2401 Namesp->VendorDataOffset = 2402 Namesp->DeviceIdOffset + Namesp->DeviceIdLength; 2403 Namesp->VendorDataLength = 2404 (UINT16) Subtable->Length; 2405 2406 /* Final size of entire namespace structure */ 2407 2408 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) + 2409 Subtable->Length + Namesp->DeviceIdLength) + ComponentLength; 2410 } 2411 } 2412 2413 break; 2414 2415 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2416 2417 /* Append the PCIe path info first */ 2418 2419 EntryCount = 0; 2420 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) 2421 { 2422 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, 2423 &Subtable); 2424 if (ACPI_FAILURE (Status)) 2425 { 2426 return (Status); 2427 } 2428 2429 if (!Subtable) 2430 { 2431 DtPopSubtable (); 2432 break; 2433 } 2434 2435 ParentTable = DtPeekSubtable (); 2436 DtInsertSubtable (ParentTable, Subtable); 2437 EntryCount++; 2438 } 2439 2440 /* Path offset will point immediately after the main subtable */ 2441 2442 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); 2443 Pcie->PathLength = (UINT16) 2444 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); 2445 2446 /* Append the Vendor Data last */ 2447 2448 Pcie->VendorDataLength = 0; 2449 Pcie->VendorDataOffset = 0; 2450 2451 if (*PFieldList) 2452 { 2453 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2454 &Subtable); 2455 if (ACPI_FAILURE (Status)) 2456 { 2457 return (Status); 2458 } 2459 2460 if (Subtable) 2461 { 2462 ParentTable = DtPeekSubtable (); 2463 DtInsertSubtable (ParentTable, Subtable); 2464 2465 Pcie->VendorDataOffset = 2466 Pcie->PathOffset + Pcie->PathLength; 2467 Pcie->VendorDataLength = (UINT16) 2468 Subtable->Length; 2469 } 2470 } 2471 2472 SdevHeader->Length = 2473 sizeof (ACPI_SDEV_PCIE) + 2474 Pcie->PathLength + Pcie->VendorDataLength; 2475 break; 2476 2477 default: 2478 2479 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2480 return (AE_ERROR); 2481 } 2482 2483 DtPopSubtable (); 2484 } 2485 2486 return (AE_OK); 2487 } 2488 2489 2490 /****************************************************************************** 2491 * 2492 * FUNCTION: DtCompileSlic 2493 * 2494 * PARAMETERS: List - Current field list pointer 2495 * 2496 * RETURN: Status 2497 * 2498 * DESCRIPTION: Compile SLIC. 2499 * 2500 *****************************************************************************/ 2501 2502 ACPI_STATUS 2503 DtCompileSlic ( 2504 void **List) 2505 { 2506 ACPI_STATUS Status; 2507 DT_SUBTABLE *Subtable; 2508 DT_SUBTABLE *ParentTable; 2509 DT_FIELD **PFieldList = (DT_FIELD **) List; 2510 2511 2512 while (*PFieldList) 2513 { 2514 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, 2515 &Subtable); 2516 if (ACPI_FAILURE (Status)) 2517 { 2518 return (Status); 2519 } 2520 2521 ParentTable = DtPeekSubtable (); 2522 DtInsertSubtable (ParentTable, Subtable); 2523 DtPushSubtable (Subtable); 2524 DtPopSubtable (); 2525 } 2526 2527 return (AE_OK); 2528 } 2529 2530 2531 /****************************************************************************** 2532 * 2533 * FUNCTION: DtCompileSlit 2534 * 2535 * PARAMETERS: List - Current field list pointer 2536 * 2537 * RETURN: Status 2538 * 2539 * DESCRIPTION: Compile SLIT. 2540 * 2541 *****************************************************************************/ 2542 2543 ACPI_STATUS 2544 DtCompileSlit ( 2545 void **List) 2546 { 2547 ACPI_STATUS Status; 2548 DT_SUBTABLE *Subtable; 2549 DT_SUBTABLE *ParentTable; 2550 DT_FIELD **PFieldList = (DT_FIELD **) List; 2551 DT_FIELD *FieldList; 2552 DT_FIELD *EndOfFieldList = NULL; 2553 UINT32 Localities; 2554 UINT32 LocalityListLength; 2555 UINT8 *LocalityBuffer; 2556 2557 2558 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 2559 &Subtable); 2560 if (ACPI_FAILURE (Status)) 2561 { 2562 return (Status); 2563 } 2564 2565 ParentTable = DtPeekSubtable (); 2566 DtInsertSubtable (ParentTable, Subtable); 2567 2568 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 2569 LocalityBuffer = UtLocalCalloc (Localities); 2570 LocalityListLength = 0; 2571 2572 /* Compile each locality buffer */ 2573 2574 FieldList = *PFieldList; 2575 while (FieldList) 2576 { 2577 DtCompileBuffer (LocalityBuffer, 2578 FieldList->Value, FieldList, Localities); 2579 2580 LocalityListLength++; 2581 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 2582 DtInsertSubtable (ParentTable, Subtable); 2583 EndOfFieldList = FieldList; 2584 FieldList = FieldList->Next; 2585 } 2586 2587 if (LocalityListLength != Localities) 2588 { 2589 sprintf(AslGbl_MsgBuffer, 2590 "Found %u entries, must match LocalityCount: %u", 2591 LocalityListLength, Localities); 2592 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer); 2593 ACPI_FREE (LocalityBuffer); 2594 return (AE_LIMIT); 2595 } 2596 2597 ACPI_FREE (LocalityBuffer); 2598 return (AE_OK); 2599 } 2600 2601 2602 /****************************************************************************** 2603 * 2604 * FUNCTION: DtCompileSrat 2605 * 2606 * PARAMETERS: List - Current field list pointer 2607 * 2608 * RETURN: Status 2609 * 2610 * DESCRIPTION: Compile SRAT. 2611 * 2612 *****************************************************************************/ 2613 2614 ACPI_STATUS 2615 DtCompileSrat ( 2616 void **List) 2617 { 2618 ACPI_STATUS Status; 2619 DT_SUBTABLE *Subtable; 2620 DT_SUBTABLE *ParentTable; 2621 DT_FIELD **PFieldList = (DT_FIELD **) List; 2622 DT_FIELD *SubtableStart; 2623 ACPI_SUBTABLE_HEADER *SratHeader; 2624 ACPI_DMTABLE_INFO *InfoTable; 2625 2626 2627 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 2628 &Subtable); 2629 if (ACPI_FAILURE (Status)) 2630 { 2631 return (Status); 2632 } 2633 2634 ParentTable = DtPeekSubtable (); 2635 DtInsertSubtable (ParentTable, Subtable); 2636 2637 while (*PFieldList) 2638 { 2639 SubtableStart = *PFieldList; 2640 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 2641 &Subtable); 2642 if (ACPI_FAILURE (Status)) 2643 { 2644 return (Status); 2645 } 2646 2647 ParentTable = DtPeekSubtable (); 2648 DtInsertSubtable (ParentTable, Subtable); 2649 DtPushSubtable (Subtable); 2650 2651 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2652 2653 switch (SratHeader->Type) 2654 { 2655 case ACPI_SRAT_TYPE_CPU_AFFINITY: 2656 2657 InfoTable = AcpiDmTableInfoSrat0; 2658 break; 2659 2660 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 2661 2662 InfoTable = AcpiDmTableInfoSrat1; 2663 break; 2664 2665 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 2666 2667 InfoTable = AcpiDmTableInfoSrat2; 2668 break; 2669 2670 case ACPI_SRAT_TYPE_GICC_AFFINITY: 2671 2672 InfoTable = AcpiDmTableInfoSrat3; 2673 break; 2674 2675 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: 2676 2677 InfoTable = AcpiDmTableInfoSrat4; 2678 break; 2679 2680 case ACPI_SRAT_TYPE_GENERIC_AFFINITY: 2681 2682 InfoTable = AcpiDmTableInfoSrat5; 2683 break; 2684 2685 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY: 2686 2687 InfoTable = AcpiDmTableInfoSrat6; 2688 break; 2689 2690 case ACPI_SRAT_TYPE_RINTC_AFFINITY: 2691 2692 InfoTable = AcpiDmTableInfoSrat7; 2693 break; 2694 2695 default: 2696 2697 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 2698 return (AE_ERROR); 2699 } 2700 2701 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2702 if (ACPI_FAILURE (Status)) 2703 { 2704 return (Status); 2705 } 2706 2707 ParentTable = DtPeekSubtable (); 2708 DtInsertSubtable (ParentTable, Subtable); 2709 DtPopSubtable (); 2710 } 2711 2712 return (AE_OK); 2713 } 2714 2715 2716 /****************************************************************************** 2717 * 2718 * FUNCTION: DtCompileStao 2719 * 2720 * PARAMETERS: PFieldList - Current field list pointer 2721 * 2722 * RETURN: Status 2723 * 2724 * DESCRIPTION: Compile STAO. 2725 * 2726 *****************************************************************************/ 2727 2728 ACPI_STATUS 2729 DtCompileStao ( 2730 void **List) 2731 { 2732 DT_FIELD **PFieldList = (DT_FIELD **) List; 2733 DT_SUBTABLE *Subtable; 2734 DT_SUBTABLE *ParentTable; 2735 ACPI_STATUS Status; 2736 2737 2738 /* Compile the main table */ 2739 2740 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 2741 &Subtable); 2742 if (ACPI_FAILURE (Status)) 2743 { 2744 return (Status); 2745 } 2746 2747 ParentTable = DtPeekSubtable (); 2748 DtInsertSubtable (ParentTable, Subtable); 2749 2750 /* Compile each ASCII namestring as a subtable */ 2751 2752 while (*PFieldList) 2753 { 2754 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 2755 &Subtable); 2756 if (ACPI_FAILURE (Status)) 2757 { 2758 return (Status); 2759 } 2760 2761 ParentTable = DtPeekSubtable (); 2762 DtInsertSubtable (ParentTable, Subtable); 2763 } 2764 2765 return (AE_OK); 2766 } 2767 2768 2769 /****************************************************************************** 2770 * 2771 * FUNCTION: DtCompileSvkl 2772 * 2773 * PARAMETERS: PFieldList - Current field list pointer 2774 * 2775 * RETURN: Status 2776 * 2777 * DESCRIPTION: Compile SVKL. 2778 * 2779 * NOTES: SVKL is essentially a flat table, with a small main table and 2780 * a variable number of a single type of subtable. 2781 * 2782 *****************************************************************************/ 2783 2784 ACPI_STATUS 2785 DtCompileSvkl ( 2786 void **List) 2787 { 2788 DT_FIELD **PFieldList = (DT_FIELD **) List; 2789 DT_SUBTABLE *Subtable; 2790 DT_SUBTABLE *ParentTable; 2791 ACPI_STATUS Status; 2792 2793 2794 /* Compile the main table */ 2795 2796 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl, 2797 &Subtable); 2798 if (ACPI_FAILURE (Status)) 2799 { 2800 return (Status); 2801 } 2802 2803 ParentTable = DtPeekSubtable (); 2804 DtInsertSubtable (ParentTable, Subtable); 2805 2806 /* Compile each subtable */ 2807 2808 while (*PFieldList) 2809 { 2810 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0, 2811 &Subtable); 2812 if (ACPI_FAILURE (Status)) 2813 { 2814 return (Status); 2815 } 2816 2817 ParentTable = DtPeekSubtable (); 2818 DtInsertSubtable (ParentTable, Subtable); 2819 } 2820 2821 return (AE_OK); 2822 } 2823 2824 2825 /****************************************************************************** 2826 * 2827 * FUNCTION: DtCompileSwft 2828 * 2829 * PARAMETERS: PFieldList - Current field list pointer 2830 * 2831 * RETURN: Status 2832 * 2833 * DESCRIPTION: Compile SWFT. 2834 * 2835 *****************************************************************************/ 2836 2837 ACPI_STATUS 2838 DtCompileSwft ( 2839 void **List) 2840 { 2841 DT_FIELD **PFieldList = (DT_FIELD **) List; 2842 DT_SUBTABLE *HdrSub; 2843 DT_SUBTABLE *DataSub; 2844 DT_SUBTABLE *ParentTable; 2845 ACPI_STATUS Status; 2846 2847 /* Main SWFT header */ 2848 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSwft, &HdrSub); 2849 if (ACPI_FAILURE (Status)) 2850 { 2851 return (Status); 2852 } 2853 2854 ParentTable = DtPeekSubtable (); 2855 DtInsertSubtable (ParentTable, HdrSub); 2856 2857 while (*PFieldList) 2858 { 2859 /* File header */ 2860 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSwftFileHdr, 2861 &HdrSub); 2862 if (ACPI_FAILURE (Status)) 2863 { 2864 return (Status); 2865 } 2866 2867 DtInsertSubtable (ParentTable, HdrSub); 2868 2869 /* File data */ 2870 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSwftFileData, 2871 &DataSub); 2872 if (ACPI_FAILURE (Status)) 2873 { 2874 return (Status); 2875 } 2876 2877 DtInsertSubtable (ParentTable, DataSub); 2878 } 2879 2880 return (AE_OK); 2881 } 2882 2883 /****************************************************************************** 2884 * 2885 * FUNCTION: DtCompileTcpa 2886 * 2887 * PARAMETERS: PFieldList - Current field list pointer 2888 * 2889 * RETURN: Status 2890 * 2891 * DESCRIPTION: Compile TCPA. 2892 * 2893 *****************************************************************************/ 2894 2895 ACPI_STATUS 2896 DtCompileTcpa ( 2897 void **List) 2898 { 2899 DT_FIELD **PFieldList = (DT_FIELD **) List; 2900 DT_SUBTABLE *Subtable; 2901 ACPI_TABLE_TCPA_HDR *TcpaHeader; 2902 DT_SUBTABLE *ParentTable; 2903 ACPI_STATUS Status; 2904 2905 2906 /* Compile the main table */ 2907 2908 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 2909 &Subtable); 2910 if (ACPI_FAILURE (Status)) 2911 { 2912 return (Status); 2913 } 2914 2915 ParentTable = DtPeekSubtable (); 2916 DtInsertSubtable (ParentTable, Subtable); 2917 2918 /* 2919 * Examine the PlatformClass field to determine the table type. 2920 * Either a client or server table. Only one. 2921 */ 2922 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 2923 2924 switch (TcpaHeader->PlatformClass) 2925 { 2926 case ACPI_TCPA_CLIENT_TABLE: 2927 2928 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 2929 &Subtable); 2930 break; 2931 2932 case ACPI_TCPA_SERVER_TABLE: 2933 2934 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 2935 &Subtable); 2936 break; 2937 2938 default: 2939 2940 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 2941 TcpaHeader->PlatformClass); 2942 Status = AE_ERROR; 2943 break; 2944 } 2945 2946 ParentTable = DtPeekSubtable (); 2947 DtInsertSubtable (ParentTable, Subtable); 2948 return (Status); 2949 } 2950 2951 2952 /****************************************************************************** 2953 * 2954 * FUNCTION: DtCompileTpm2Rev3 2955 * 2956 * PARAMETERS: PFieldList - Current field list pointer 2957 * 2958 * RETURN: Status 2959 * 2960 * DESCRIPTION: Compile TPM2 revision 3 2961 * 2962 *****************************************************************************/ 2963 static ACPI_STATUS 2964 DtCompileTpm2Rev3 ( 2965 void **List) 2966 { 2967 DT_FIELD **PFieldList = (DT_FIELD **) List; 2968 DT_SUBTABLE *Subtable; 2969 ACPI_TABLE_TPM23 *Tpm23Header; 2970 DT_SUBTABLE *ParentTable; 2971 ACPI_STATUS Status = AE_OK; 2972 2973 2974 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23, 2975 &Subtable); 2976 2977 ParentTable = DtPeekSubtable (); 2978 DtInsertSubtable (ParentTable, Subtable); 2979 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer); 2980 2981 /* Subtable type depends on the StartMethod */ 2982 2983 switch (Tpm23Header->StartMethod) 2984 { 2985 case ACPI_TPM23_ACPI_START_METHOD: 2986 2987 /* Subtable specific to to ARM_SMC */ 2988 2989 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a, 2990 &Subtable); 2991 if (ACPI_FAILURE (Status)) 2992 { 2993 return (Status); 2994 } 2995 2996 ParentTable = DtPeekSubtable (); 2997 DtInsertSubtable (ParentTable, Subtable); 2998 break; 2999 3000 default: 3001 break; 3002 } 3003 3004 return (Status); 3005 } 3006 3007 3008 /****************************************************************************** 3009 * 3010 * FUNCTION: DtCompileTpm2 3011 * 3012 * PARAMETERS: PFieldList - Current field list pointer 3013 * 3014 * RETURN: Status 3015 * 3016 * DESCRIPTION: Compile TPM2. 3017 * 3018 *****************************************************************************/ 3019 3020 ACPI_STATUS 3021 DtCompileTpm2 ( 3022 void **List) 3023 { 3024 DT_FIELD **PFieldList = (DT_FIELD **) List; 3025 DT_SUBTABLE *Subtable; 3026 ACPI_TABLE_TPM2 *Tpm2Header; 3027 DT_SUBTABLE *ParentTable; 3028 ACPI_STATUS Status = AE_OK; 3029 ACPI_TABLE_HEADER *Header; 3030 3031 3032 ParentTable = DtPeekSubtable (); 3033 3034 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 3035 3036 if (Header->Revision == 3) 3037 { 3038 return (DtCompileTpm2Rev3 (List)); 3039 } 3040 3041 /* Compile the main table */ 3042 3043 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, 3044 &Subtable); 3045 if (ACPI_FAILURE (Status)) 3046 { 3047 return (Status); 3048 } 3049 3050 ParentTable = DtPeekSubtable (); 3051 DtInsertSubtable (ParentTable, Subtable); 3052 3053 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); 3054 3055 /* Method parameters */ 3056 /* Optional: Log area minimum length */ 3057 /* Optional: Log area start address */ 3058 /* TBD: Optional fields above not fully implemented (not optional at this time) */ 3059 3060 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, 3061 &Subtable); 3062 if (ACPI_FAILURE (Status)) 3063 { 3064 return (Status); 3065 } 3066 3067 ParentTable = DtPeekSubtable (); 3068 DtInsertSubtable (ParentTable, Subtable); 3069 3070 3071 /* Subtable type depends on the StartMethod */ 3072 3073 switch (Tpm2Header->StartMethod) 3074 { 3075 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 3076 3077 /* Subtable specific to to ARM_SMC */ 3078 3079 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, 3080 &Subtable); 3081 if (ACPI_FAILURE (Status)) 3082 { 3083 return (Status); 3084 } 3085 3086 ParentTable = DtPeekSubtable (); 3087 DtInsertSubtable (ParentTable, Subtable); 3088 break; 3089 3090 case ACPI_TPM2_START_METHOD: 3091 case ACPI_TPM2_MEMORY_MAPPED: 3092 case ACPI_TPM2_COMMAND_BUFFER: 3093 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: 3094 break; 3095 3096 case ACPI_TPM2_RESERVED1: 3097 case ACPI_TPM2_RESERVED3: 3098 case ACPI_TPM2_RESERVED4: 3099 case ACPI_TPM2_RESERVED5: 3100 case ACPI_TPM2_RESERVED9: 3101 case ACPI_TPM2_RESERVED10: 3102 3103 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", 3104 Tpm2Header->StartMethod); 3105 Status = AE_ERROR; 3106 break; 3107 3108 case ACPI_TPM2_NOT_ALLOWED: 3109 default: 3110 3111 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", 3112 Tpm2Header->StartMethod); 3113 Status = AE_ERROR; 3114 break; 3115 } 3116 3117 return (Status); 3118 } 3119 3120 3121 /****************************************************************************** 3122 * 3123 * FUNCTION: DtGetGenericTableInfo 3124 * 3125 * PARAMETERS: Name - Generic type name 3126 * 3127 * RETURN: Info entry 3128 * 3129 * DESCRIPTION: Obtain table info for a generic name entry 3130 * 3131 *****************************************************************************/ 3132 3133 ACPI_DMTABLE_INFO * 3134 DtGetGenericTableInfo ( 3135 char *Name) 3136 { 3137 ACPI_DMTABLE_INFO *Info; 3138 UINT32 i; 3139 3140 3141 if (!Name) 3142 { 3143 return (NULL); 3144 } 3145 3146 /* Search info table for name match */ 3147 3148 for (i = 0; ; i++) 3149 { 3150 Info = AcpiDmTableInfoGeneric[i]; 3151 if (Info->Opcode == ACPI_DMT_EXIT) 3152 { 3153 Info = NULL; 3154 break; 3155 } 3156 3157 /* Use caseless compare for generic keywords */ 3158 3159 if (!AcpiUtStricmp (Name, Info->Name)) 3160 { 3161 break; 3162 } 3163 } 3164 3165 return (Info); 3166 } 3167 3168 3169 /****************************************************************************** 3170 * 3171 * FUNCTION: DtCompileUefi 3172 * 3173 * PARAMETERS: List - Current field list pointer 3174 * 3175 * RETURN: Status 3176 * 3177 * DESCRIPTION: Compile UEFI. 3178 * 3179 *****************************************************************************/ 3180 3181 ACPI_STATUS 3182 DtCompileUefi ( 3183 void **List) 3184 { 3185 ACPI_STATUS Status; 3186 DT_SUBTABLE *Subtable; 3187 DT_SUBTABLE *ParentTable; 3188 DT_FIELD **PFieldList = (DT_FIELD **) List; 3189 UINT16 *DataOffset; 3190 3191 3192 /* Compile the predefined portion of the UEFI table */ 3193 3194 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 3195 &Subtable); 3196 if (ACPI_FAILURE (Status)) 3197 { 3198 return (Status); 3199 } 3200 3201 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 3202 *DataOffset = sizeof (ACPI_TABLE_UEFI); 3203 3204 ParentTable = DtPeekSubtable (); 3205 DtInsertSubtable (ParentTable, Subtable); 3206 3207 /* 3208 * Compile the "generic" portion of the UEFI table. This 3209 * part of the table is not predefined and any of the generic 3210 * operators may be used. 3211 */ 3212 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 3213 return (AE_OK); 3214 } 3215 3216 3217 /****************************************************************************** 3218 * 3219 * FUNCTION: DtCompileViot 3220 * 3221 * PARAMETERS: List - Current field list pointer 3222 * 3223 * RETURN: Status 3224 * 3225 * DESCRIPTION: Compile VIOT. 3226 * 3227 *****************************************************************************/ 3228 3229 ACPI_STATUS 3230 DtCompileViot ( 3231 void **List) 3232 { 3233 ACPI_STATUS Status; 3234 DT_SUBTABLE *Subtable; 3235 DT_SUBTABLE *ParentTable; 3236 DT_FIELD **PFieldList = (DT_FIELD **) List; 3237 DT_FIELD *SubtableStart; 3238 ACPI_TABLE_VIOT *Viot; 3239 ACPI_VIOT_HEADER *ViotHeader; 3240 ACPI_DMTABLE_INFO *InfoTable; 3241 UINT16 NodeCount; 3242 3243 ParentTable = DtPeekSubtable (); 3244 3245 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable); 3246 if (ACPI_FAILURE (Status)) 3247 { 3248 return (Status); 3249 } 3250 DtInsertSubtable (ParentTable, Subtable); 3251 3252 /* 3253 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 3254 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 3255 */ 3256 Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer, 3257 sizeof (ACPI_TABLE_HEADER)); 3258 3259 Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT); 3260 3261 NodeCount = 0; 3262 while (*PFieldList) { 3263 SubtableStart = *PFieldList; 3264 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader, 3265 &Subtable); 3266 if (ACPI_FAILURE (Status)) 3267 { 3268 return (Status); 3269 } 3270 3271 ParentTable = DtPeekSubtable (); 3272 DtInsertSubtable (ParentTable, Subtable); 3273 DtPushSubtable (Subtable); 3274 3275 ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer); 3276 3277 switch (ViotHeader->Type) 3278 { 3279 case ACPI_VIOT_NODE_PCI_RANGE: 3280 3281 InfoTable = AcpiDmTableInfoViot1; 3282 break; 3283 3284 case ACPI_VIOT_NODE_MMIO: 3285 3286 InfoTable = AcpiDmTableInfoViot2; 3287 break; 3288 3289 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI: 3290 3291 InfoTable = AcpiDmTableInfoViot3; 3292 break; 3293 3294 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO: 3295 3296 InfoTable = AcpiDmTableInfoViot4; 3297 break; 3298 3299 default: 3300 3301 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT"); 3302 return (AE_ERROR); 3303 } 3304 3305 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 3306 if (ACPI_FAILURE (Status)) 3307 { 3308 return (Status); 3309 } 3310 3311 ParentTable = DtPeekSubtable (); 3312 DtInsertSubtable (ParentTable, Subtable); 3313 DtPopSubtable (); 3314 NodeCount++; 3315 } 3316 3317 Viot->NodeCount = NodeCount; 3318 return (AE_OK); 3319 } 3320 3321 3322 /****************************************************************************** 3323 * 3324 * FUNCTION: DtCompileWdat 3325 * 3326 * PARAMETERS: List - Current field list pointer 3327 * 3328 * RETURN: Status 3329 * 3330 * DESCRIPTION: Compile WDAT. 3331 * 3332 *****************************************************************************/ 3333 3334 ACPI_STATUS 3335 DtCompileWdat ( 3336 void **List) 3337 { 3338 ACPI_STATUS Status; 3339 3340 3341 Status = DtCompileTwoSubtables (List, 3342 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 3343 return (Status); 3344 } 3345 3346 3347 /****************************************************************************** 3348 * 3349 * FUNCTION: DtCompileWpbt 3350 * 3351 * PARAMETERS: List - Current field list pointer 3352 * 3353 * RETURN: Status 3354 * 3355 * DESCRIPTION: Compile WPBT. 3356 * 3357 *****************************************************************************/ 3358 3359 ACPI_STATUS 3360 DtCompileWpbt ( 3361 void **List) 3362 { 3363 DT_FIELD **PFieldList = (DT_FIELD **) List; 3364 DT_SUBTABLE *Subtable; 3365 DT_SUBTABLE *ParentTable; 3366 ACPI_TABLE_WPBT *Table; 3367 ACPI_STATUS Status; 3368 3369 3370 /* Compile the main table */ 3371 3372 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable); 3373 if (ACPI_FAILURE (Status)) 3374 { 3375 return (Status); 3376 } 3377 3378 ParentTable = DtPeekSubtable (); 3379 DtInsertSubtable (ParentTable, Subtable); 3380 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 3381 3382 /* 3383 * Exit now if there are no arguments specified. This is indicated by: 3384 * The "Command-line Arguments" field has not been specified (if specified, 3385 * it will be the last field in the field list -- after the main table). 3386 * Set the Argument Length in the main table to zero. 3387 */ 3388 if (!*PFieldList) 3389 { 3390 Table->ArgumentsLength = 0; 3391 return (AE_OK); 3392 } 3393 3394 /* Compile the argument list subtable */ 3395 3396 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable); 3397 if (ACPI_FAILURE (Status)) 3398 { 3399 return (Status); 3400 } 3401 3402 /* Extract the length of the Arguments buffer, insert into main table */ 3403 3404 Table->ArgumentsLength = (UINT16) Subtable->TotalLength; 3405 DtInsertSubtable (ParentTable, Subtable); 3406 return (AE_OK); 3407 } 3408 3409 3410 /****************************************************************************** 3411 * 3412 * FUNCTION: DtCompileXsdt 3413 * 3414 * PARAMETERS: List - Current field list pointer 3415 * 3416 * RETURN: Status 3417 * 3418 * DESCRIPTION: Compile XSDT. 3419 * 3420 *****************************************************************************/ 3421 3422 ACPI_STATUS 3423 DtCompileXsdt ( 3424 void **List) 3425 { 3426 DT_SUBTABLE *Subtable; 3427 DT_SUBTABLE *ParentTable; 3428 DT_FIELD *FieldList = *(DT_FIELD **) List; 3429 UINT64 Address; 3430 3431 3432 ParentTable = DtPeekSubtable (); 3433 3434 while (FieldList) 3435 { 3436 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 3437 3438 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 3439 DtInsertSubtable (ParentTable, Subtable); 3440 FieldList = FieldList->Next; 3441 } 3442 3443 return (AE_OK); 3444 } 3445 3446 3447 /****************************************************************************** 3448 * 3449 * FUNCTION: DtCompileGeneric 3450 * 3451 * PARAMETERS: List - Current field list pointer 3452 * Name - Field name to end generic compiling 3453 * Length - Compiled table length to return 3454 * 3455 * RETURN: Status 3456 * 3457 * DESCRIPTION: Compile generic unknown table. 3458 * 3459 *****************************************************************************/ 3460 3461 ACPI_STATUS 3462 DtCompileGeneric ( 3463 void **List, 3464 char *Name, 3465 UINT32 *Length) 3466 { 3467 ACPI_STATUS Status; 3468 DT_SUBTABLE *Subtable; 3469 DT_SUBTABLE *ParentTable; 3470 DT_FIELD **PFieldList = (DT_FIELD **) List; 3471 ACPI_DMTABLE_INFO *Info; 3472 3473 3474 ParentTable = DtPeekSubtable (); 3475 3476 /* 3477 * Compile the "generic" portion of the table. This 3478 * part of the table is not predefined and any of the generic 3479 * operators may be used. 3480 */ 3481 3482 /* Find any and all labels in the entire generic portion */ 3483 3484 DtDetectAllLabels (*PFieldList); 3485 3486 /* Now we can actually compile the parse tree */ 3487 3488 if (Length && *Length) 3489 { 3490 *Length = 0; 3491 } 3492 while (*PFieldList) 3493 { 3494 if (Name && !strcmp ((*PFieldList)->Name, Name)) 3495 { 3496 break; 3497 } 3498 3499 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 3500 if (!Info) 3501 { 3502 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3503 (*PFieldList)->Name); 3504 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3505 (*PFieldList), AslGbl_MsgBuffer); 3506 3507 *PFieldList = (*PFieldList)->Next; 3508 continue; 3509 } 3510 3511 Status = DtCompileTable (PFieldList, Info, 3512 &Subtable); 3513 if (ACPI_SUCCESS (Status)) 3514 { 3515 DtInsertSubtable (ParentTable, Subtable); 3516 if (Length) 3517 { 3518 *Length += Subtable->Length; 3519 } 3520 } 3521 else 3522 { 3523 *PFieldList = (*PFieldList)->Next; 3524 3525 if (Status == AE_NOT_FOUND) 3526 { 3527 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3528 (*PFieldList)->Name); 3529 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3530 (*PFieldList), AslGbl_MsgBuffer); 3531 } 3532 } 3533 } 3534 3535 return (AE_OK); 3536 } 3537