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 while (*PFieldList) 1638 { 1639 SubtableStart = *PFieldList; 1640 1641 /* Compile PPTT subtable header */ 1642 1643 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr, 1644 &Subtable); 1645 if (ACPI_FAILURE (Status)) 1646 { 1647 return (Status); 1648 } 1649 DtInsertSubtable (ParentTable, Subtable); 1650 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1651 PpttHeader->Length = (UINT8)(Subtable->Length); 1652 1653 switch (PpttHeader->Type) 1654 { 1655 case ACPI_PPTT_TYPE_PROCESSOR: 1656 1657 InfoTable = AcpiDmTableInfoPptt0; 1658 break; 1659 1660 case ACPI_PPTT_TYPE_CACHE: 1661 1662 InfoTable = AcpiDmTableInfoPptt1; 1663 break; 1664 1665 case ACPI_PPTT_TYPE_ID: 1666 1667 InfoTable = AcpiDmTableInfoPptt2; 1668 break; 1669 1670 default: 1671 1672 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT"); 1673 return (AE_ERROR); 1674 } 1675 1676 /* Compile PPTT subtable body */ 1677 1678 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1679 if (ACPI_FAILURE (Status)) 1680 { 1681 return (Status); 1682 } 1683 DtInsertSubtable (ParentTable, Subtable); 1684 PpttHeader->Length += (UINT8)(Subtable->Length); 1685 1686 /* Compile PPTT subtable additional */ 1687 1688 switch (PpttHeader->Type) 1689 { 1690 case ACPI_PPTT_TYPE_PROCESSOR: 1691 1692 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR, 1693 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER)); 1694 if (PpttProcessor) 1695 { 1696 /* Compile initiator proximity domain list */ 1697 1698 PpttProcessor->NumberOfPrivResources = 0; 1699 while (*PFieldList) 1700 { 1701 Status = DtCompileTable (PFieldList, 1702 AcpiDmTableInfoPptt0a, &Subtable); 1703 if (ACPI_FAILURE (Status)) 1704 { 1705 return (Status); 1706 } 1707 if (!Subtable) 1708 { 1709 break; 1710 } 1711 1712 DtInsertSubtable (ParentTable, Subtable); 1713 PpttHeader->Length += (UINT8)(Subtable->Length); 1714 PpttProcessor->NumberOfPrivResources++; 1715 } 1716 } 1717 break; 1718 1719 case ACPI_PPTT_TYPE_CACHE: 1720 1721 PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 1722 AslGbl_RootTable->Buffer); 1723 if (PpttAcpiHeader->Revision < 3) 1724 { 1725 break; 1726 } 1727 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a, 1728 &Subtable); 1729 DtInsertSubtable (ParentTable, Subtable); 1730 PpttHeader->Length += (UINT8)(Subtable->Length); 1731 break; 1732 1733 default: 1734 1735 break; 1736 } 1737 } 1738 1739 return (AE_OK); 1740 } 1741 1742 1743 /****************************************************************************** 1744 * 1745 * FUNCTION: DtCompilePrmt 1746 * 1747 * PARAMETERS: List - Current field list pointer 1748 * 1749 * RETURN: Status 1750 * 1751 * DESCRIPTION: Compile PRMT. 1752 * 1753 *****************************************************************************/ 1754 1755 ACPI_STATUS 1756 DtCompilePrmt ( 1757 void **List) 1758 { 1759 ACPI_STATUS Status; 1760 ACPI_TABLE_PRMT_HEADER *PrmtHeader; 1761 ACPI_PRMT_MODULE_INFO *PrmtModuleInfo; 1762 DT_SUBTABLE *Subtable; 1763 DT_SUBTABLE *ParentTable; 1764 DT_FIELD **PFieldList = (DT_FIELD **) List; 1765 UINT32 i, j; 1766 1767 ParentTable = DtPeekSubtable (); 1768 1769 /* Compile PRMT subtable header */ 1770 1771 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr, 1772 &Subtable); 1773 if (ACPI_FAILURE (Status)) 1774 { 1775 return (Status); 1776 } 1777 DtInsertSubtable (ParentTable, Subtable); 1778 PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer); 1779 1780 for (i = 0; i < PrmtHeader->ModuleInfoCount; i++) 1781 { 1782 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule, 1783 &Subtable); 1784 if (ACPI_FAILURE (Status)) 1785 { 1786 return (Status); 1787 } 1788 DtInsertSubtable (ParentTable, Subtable); 1789 PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer); 1790 1791 for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++) 1792 { 1793 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler, 1794 &Subtable); 1795 if (ACPI_FAILURE (Status)) 1796 { 1797 return (Status); 1798 } 1799 DtInsertSubtable (ParentTable, Subtable); 1800 } 1801 } 1802 1803 return (AE_OK); 1804 } 1805 1806 1807 /****************************************************************************** 1808 * 1809 * FUNCTION: DtCompileRas2 1810 * 1811 * PARAMETERS: List - Current field list pointer 1812 * 1813 * RETURN: Status 1814 * 1815 * DESCRIPTION: Compile RAS2. 1816 * 1817 *****************************************************************************/ 1818 1819 ACPI_STATUS 1820 DtCompileRas2 ( 1821 void **List) 1822 { 1823 ACPI_STATUS Status; 1824 DT_SUBTABLE *Subtable; 1825 DT_SUBTABLE *ParentTable; 1826 DT_FIELD **PFieldList = (DT_FIELD **) List; 1827 ACPI_TABLE_RAS2 *Ras2Header; 1828 UINT32 Count = 0; 1829 1830 1831 /* Main table */ 1832 1833 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2, &Subtable); 1834 if (ACPI_FAILURE (Status)) 1835 { 1836 return (Status); 1837 } 1838 1839 ParentTable = DtPeekSubtable (); 1840 DtInsertSubtable (ParentTable, Subtable); 1841 1842 Ras2Header = ACPI_CAST_PTR (ACPI_TABLE_RAS2, ParentTable->Buffer); 1843 1844 /* There is only one type of subtable at this time, no need to decode */ 1845 1846 while (*PFieldList) 1847 { 1848 /* List of RAS2 PCC descriptors, each 8 bytes */ 1849 1850 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2PccDesc, 1851 &Subtable); 1852 if (ACPI_FAILURE (Status)) 1853 { 1854 return (Status); 1855 } 1856 1857 DtInsertSubtable (ParentTable, Subtable); 1858 Count++; 1859 } 1860 1861 Ras2Header->NumPccDescs = (UINT8) Count; 1862 return (AE_OK); 1863 } 1864 1865 1866 /****************************************************************************** 1867 * 1868 * FUNCTION: DtCompileRgrt 1869 * 1870 * PARAMETERS: List - Current field list pointer 1871 * 1872 * RETURN: Status 1873 * 1874 * DESCRIPTION: Compile RGRT. 1875 * 1876 *****************************************************************************/ 1877 1878 ACPI_STATUS 1879 DtCompileRgrt ( 1880 void **List) 1881 { 1882 ACPI_STATUS Status; 1883 DT_SUBTABLE *Subtable; 1884 DT_SUBTABLE *ParentTable; 1885 DT_FIELD **PFieldList = (DT_FIELD **) List; 1886 1887 1888 /* Compile the main table */ 1889 1890 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt, 1891 &Subtable); 1892 if (ACPI_FAILURE (Status)) 1893 { 1894 return (Status); 1895 } 1896 1897 ParentTable = DtPeekSubtable (); 1898 DtInsertSubtable (ParentTable, Subtable); 1899 1900 /* Compile the "Subtable" -- actually just the binary (PNG) image */ 1901 1902 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0, 1903 &Subtable); 1904 if (ACPI_FAILURE (Status)) 1905 { 1906 return (Status); 1907 } 1908 1909 DtInsertSubtable (ParentTable, Subtable); 1910 return (AE_OK); 1911 } 1912 1913 1914 /****************************************************************************** 1915 * 1916 * FUNCTION: DtCompileRhct 1917 * 1918 * PARAMETERS: List - Current field list pointer 1919 * 1920 * RETURN: Status 1921 * 1922 * DESCRIPTION: Compile RHCT. 1923 * 1924 *****************************************************************************/ 1925 1926 ACPI_STATUS 1927 DtCompileRhct ( 1928 void **List) 1929 { 1930 ACPI_STATUS Status; 1931 ACPI_RHCT_NODE_HEADER *RhctHeader; 1932 ACPI_RHCT_HART_INFO *RhctHartInfo = NULL; 1933 DT_SUBTABLE *Subtable; 1934 DT_SUBTABLE *ParentTable; 1935 ACPI_DMTABLE_INFO *InfoTable; 1936 DT_FIELD **PFieldList = (DT_FIELD **) List; 1937 DT_FIELD *SubtableStart; 1938 1939 1940 /* Compile the main table */ 1941 1942 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct, 1943 &Subtable); 1944 if (ACPI_FAILURE (Status)) 1945 { 1946 return (Status); 1947 } 1948 1949 ParentTable = DtPeekSubtable (); 1950 while (*PFieldList) 1951 { 1952 SubtableStart = *PFieldList; 1953 1954 /* Compile RHCT subtable header */ 1955 1956 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr, 1957 &Subtable); 1958 if (ACPI_FAILURE (Status)) 1959 { 1960 return (Status); 1961 } 1962 DtInsertSubtable (ParentTable, Subtable); 1963 RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer); 1964 RhctHeader->Length = (UINT16)(Subtable->Length); 1965 1966 switch (RhctHeader->Type) 1967 { 1968 case ACPI_RHCT_NODE_TYPE_ISA_STRING: 1969 1970 InfoTable = AcpiDmTableInfoRhctIsa1; 1971 break; 1972 1973 case ACPI_RHCT_NODE_TYPE_HART_INFO: 1974 1975 InfoTable = AcpiDmTableInfoRhctHartInfo1; 1976 break; 1977 1978 case ACPI_RHCT_NODE_TYPE_CMO: 1979 1980 InfoTable = AcpiDmTableInfoRhctCmo1; 1981 break; 1982 1983 case ACPI_RHCT_NODE_TYPE_MMU: 1984 1985 InfoTable = AcpiDmTableInfoRhctMmu1; 1986 break; 1987 1988 default: 1989 1990 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT"); 1991 return (AE_ERROR); 1992 } 1993 1994 /* Compile RHCT subtable body */ 1995 1996 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1997 if (ACPI_FAILURE (Status)) 1998 { 1999 return (Status); 2000 } 2001 DtInsertSubtable (ParentTable, Subtable); 2002 RhctHeader->Length += (UINT16)(Subtable->Length); 2003 2004 /* Compile RHCT subtable additionals */ 2005 2006 switch (RhctHeader->Type) 2007 { 2008 case ACPI_RHCT_NODE_TYPE_HART_INFO: 2009 2010 RhctHartInfo = ACPI_SUB_PTR (ACPI_RHCT_HART_INFO, 2011 Subtable->Buffer, sizeof (ACPI_RHCT_NODE_HEADER)); 2012 if (RhctHartInfo) 2013 { 2014 2015 RhctHartInfo->NumOffsets = 0; 2016 while (*PFieldList) 2017 { 2018 Status = DtCompileTable (PFieldList, 2019 AcpiDmTableInfoRhctHartInfo2, &Subtable); 2020 if (ACPI_FAILURE (Status)) 2021 { 2022 return (Status); 2023 } 2024 if (!Subtable) 2025 { 2026 break; 2027 } 2028 2029 DtInsertSubtable (ParentTable, Subtable); 2030 RhctHeader->Length += (UINT16)(Subtable->Length); 2031 RhctHartInfo->NumOffsets++; 2032 } 2033 } 2034 break; 2035 2036 default: 2037 2038 break; 2039 } 2040 } 2041 2042 return (AE_OK); 2043 } 2044 2045 2046 /****************************************************************************** 2047 * 2048 * FUNCTION: DtCompileRsdt 2049 * 2050 * PARAMETERS: List - Current field list pointer 2051 * 2052 * RETURN: Status 2053 * 2054 * DESCRIPTION: Compile RSDT. 2055 * 2056 *****************************************************************************/ 2057 2058 ACPI_STATUS 2059 DtCompileRsdt ( 2060 void **List) 2061 { 2062 DT_SUBTABLE *Subtable; 2063 DT_SUBTABLE *ParentTable; 2064 DT_FIELD *FieldList = *(DT_FIELD **) List; 2065 UINT32 Address; 2066 2067 2068 ParentTable = DtPeekSubtable (); 2069 2070 while (FieldList) 2071 { 2072 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 2073 2074 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 2075 DtInsertSubtable (ParentTable, Subtable); 2076 FieldList = FieldList->Next; 2077 } 2078 2079 return (AE_OK); 2080 } 2081 2082 2083 /****************************************************************************** 2084 * 2085 * FUNCTION: DtCompileS3pt 2086 * 2087 * PARAMETERS: PFieldList - Current field list pointer 2088 * 2089 * RETURN: Status 2090 * 2091 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 2092 * 2093 *****************************************************************************/ 2094 2095 ACPI_STATUS 2096 DtCompileS3pt ( 2097 DT_FIELD **PFieldList) 2098 { 2099 ACPI_STATUS Status; 2100 ACPI_FPDT_HEADER *S3ptHeader; 2101 DT_SUBTABLE *Subtable; 2102 DT_SUBTABLE *ParentTable; 2103 ACPI_DMTABLE_INFO *InfoTable; 2104 DT_FIELD *SubtableStart; 2105 2106 2107 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 2108 &AslGbl_RootTable); 2109 if (ACPI_FAILURE (Status)) 2110 { 2111 return (Status); 2112 } 2113 2114 DtPushSubtable (AslGbl_RootTable); 2115 2116 while (*PFieldList) 2117 { 2118 SubtableStart = *PFieldList; 2119 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 2120 &Subtable); 2121 if (ACPI_FAILURE (Status)) 2122 { 2123 return (Status); 2124 } 2125 2126 ParentTable = DtPeekSubtable (); 2127 DtInsertSubtable (ParentTable, Subtable); 2128 DtPushSubtable (Subtable); 2129 2130 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 2131 2132 switch (S3ptHeader->Type) 2133 { 2134 case ACPI_S3PT_TYPE_RESUME: 2135 2136 InfoTable = AcpiDmTableInfoS3pt0; 2137 break; 2138 2139 case ACPI_S3PT_TYPE_SUSPEND: 2140 2141 InfoTable = AcpiDmTableInfoS3pt1; 2142 break; 2143 2144 default: 2145 2146 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 2147 return (AE_ERROR); 2148 } 2149 2150 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2151 if (ACPI_FAILURE (Status)) 2152 { 2153 return (Status); 2154 } 2155 2156 ParentTable = DtPeekSubtable (); 2157 DtInsertSubtable (ParentTable, Subtable); 2158 DtPopSubtable (); 2159 } 2160 2161 return (AE_OK); 2162 } 2163 2164 2165 /****************************************************************************** 2166 * 2167 * FUNCTION: DtCompileSdev 2168 * 2169 * PARAMETERS: List - Current field list pointer 2170 * 2171 * RETURN: Status 2172 * 2173 * DESCRIPTION: Compile SDEV. 2174 * 2175 *****************************************************************************/ 2176 2177 ACPI_STATUS 2178 DtCompileSdev ( 2179 void **List) 2180 { 2181 ACPI_STATUS Status; 2182 ACPI_SDEV_HEADER *SdevHeader; 2183 ACPI_SDEV_HEADER *SecureComponentHeader; 2184 DT_SUBTABLE *Subtable; 2185 DT_SUBTABLE *ParentTable; 2186 ACPI_DMTABLE_INFO *InfoTable; 2187 ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL; 2188 DT_FIELD **PFieldList = (DT_FIELD **) List; 2189 DT_FIELD *SubtableStart; 2190 ACPI_SDEV_PCIE *Pcie = NULL; 2191 ACPI_SDEV_NAMESPACE *Namesp = NULL; 2192 UINT32 EntryCount; 2193 ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL; 2194 UINT16 ComponentLength = 0; 2195 2196 2197 /* Subtables */ 2198 2199 while (*PFieldList) 2200 { 2201 /* Compile common SDEV subtable header */ 2202 2203 SubtableStart = *PFieldList; 2204 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr, 2205 &Subtable); 2206 if (ACPI_FAILURE (Status)) 2207 { 2208 return (Status); 2209 } 2210 2211 ParentTable = DtPeekSubtable (); 2212 DtInsertSubtable (ParentTable, Subtable); 2213 DtPushSubtable (Subtable); 2214 2215 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2216 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER)); 2217 2218 switch (SdevHeader->Type) 2219 { 2220 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2221 2222 InfoTable = AcpiDmTableInfoSdev0; 2223 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer); 2224 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT, 2225 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE))); 2226 break; 2227 2228 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2229 2230 InfoTable = AcpiDmTableInfoSdev1; 2231 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer); 2232 break; 2233 2234 default: 2235 2236 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2237 return (AE_ERROR); 2238 } 2239 2240 /* Compile SDEV subtable body */ 2241 2242 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2243 if (ACPI_FAILURE (Status)) 2244 { 2245 return (Status); 2246 } 2247 2248 ParentTable = DtPeekSubtable (); 2249 DtInsertSubtable (ParentTable, Subtable); 2250 2251 /* Optional data fields are appended to the main subtable body */ 2252 2253 switch (SdevHeader->Type) 2254 { 2255 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2256 2257 /* 2258 * Device Id Offset will be be calculated differently depending on 2259 * the presence of secure access components. 2260 */ 2261 Namesp->DeviceIdOffset = 0; 2262 ComponentLength = 0; 2263 2264 /* If the secure access component exists, get the structures */ 2265 2266 if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT) 2267 { 2268 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b, 2269 &Subtable); 2270 if (ACPI_FAILURE (Status)) 2271 { 2272 return (Status); 2273 } 2274 ParentTable = DtPeekSubtable (); 2275 DtInsertSubtable (ParentTable, Subtable); 2276 2277 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2278 2279 /* Compile a secure access component header */ 2280 2281 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr, 2282 &Subtable); 2283 if (ACPI_FAILURE (Status)) 2284 { 2285 return (Status); 2286 } 2287 ParentTable = DtPeekSubtable (); 2288 DtInsertSubtable (ParentTable, Subtable); 2289 2290 /* Compile the secure access component */ 2291 2292 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2293 switch (SecureComponentHeader->Type) 2294 { 2295 case ACPI_SDEV_TYPE_ID_COMPONENT: 2296 2297 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId; 2298 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT); 2299 ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT); 2300 break; 2301 2302 case ACPI_SDEV_TYPE_MEM_COMPONENT: 2303 2304 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem; 2305 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT); 2306 ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT); 2307 break; 2308 2309 default: 2310 2311 /* Any other secure component types are undefined */ 2312 2313 return (AE_ERROR); 2314 } 2315 2316 Status = DtCompileTable (PFieldList, SecureComponentInfoTable, 2317 &Subtable); 2318 if (ACPI_FAILURE (Status)) 2319 { 2320 return (Status); 2321 } 2322 ParentTable = DtPeekSubtable (); 2323 DtInsertSubtable (ParentTable, Subtable); 2324 2325 SecureComponent->SecureComponentOffset = 2326 sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT); 2327 SecureComponent->SecureComponentLength = ComponentLength; 2328 2329 2330 /* 2331 * Add the secure component to the subtable to be added for the 2332 * the namespace subtable's length 2333 */ 2334 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2335 } 2336 2337 /* Append DeviceId namespace string */ 2338 2339 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a, 2340 &Subtable); 2341 if (ACPI_FAILURE (Status)) 2342 { 2343 return (Status); 2344 } 2345 2346 if (!Subtable) 2347 { 2348 break; 2349 } 2350 2351 ParentTable = DtPeekSubtable (); 2352 DtInsertSubtable (ParentTable, Subtable); 2353 2354 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE); 2355 2356 Namesp->DeviceIdLength = (UINT16) Subtable->Length; 2357 2358 /* Append Vendor data */ 2359 2360 Namesp->VendorDataLength = 0; 2361 Namesp->VendorDataOffset = 0; 2362 2363 if (*PFieldList) 2364 { 2365 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2366 &Subtable); 2367 if (ACPI_FAILURE (Status)) 2368 { 2369 return (Status); 2370 } 2371 2372 if (Subtable) 2373 { 2374 ParentTable = DtPeekSubtable (); 2375 DtInsertSubtable (ParentTable, Subtable); 2376 2377 Namesp->VendorDataOffset = 2378 Namesp->DeviceIdOffset + Namesp->DeviceIdLength; 2379 Namesp->VendorDataLength = 2380 (UINT16) Subtable->Length; 2381 2382 /* Final size of entire namespace structure */ 2383 2384 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) + 2385 Subtable->Length + Namesp->DeviceIdLength) + ComponentLength; 2386 } 2387 } 2388 2389 break; 2390 2391 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2392 2393 /* Append the PCIe path info first */ 2394 2395 EntryCount = 0; 2396 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) 2397 { 2398 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, 2399 &Subtable); 2400 if (ACPI_FAILURE (Status)) 2401 { 2402 return (Status); 2403 } 2404 2405 if (!Subtable) 2406 { 2407 DtPopSubtable (); 2408 break; 2409 } 2410 2411 ParentTable = DtPeekSubtable (); 2412 DtInsertSubtable (ParentTable, Subtable); 2413 EntryCount++; 2414 } 2415 2416 /* Path offset will point immediately after the main subtable */ 2417 2418 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); 2419 Pcie->PathLength = (UINT16) 2420 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); 2421 2422 /* Append the Vendor Data last */ 2423 2424 Pcie->VendorDataLength = 0; 2425 Pcie->VendorDataOffset = 0; 2426 2427 if (*PFieldList) 2428 { 2429 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2430 &Subtable); 2431 if (ACPI_FAILURE (Status)) 2432 { 2433 return (Status); 2434 } 2435 2436 if (Subtable) 2437 { 2438 ParentTable = DtPeekSubtable (); 2439 DtInsertSubtable (ParentTable, Subtable); 2440 2441 Pcie->VendorDataOffset = 2442 Pcie->PathOffset + Pcie->PathLength; 2443 Pcie->VendorDataLength = (UINT16) 2444 Subtable->Length; 2445 } 2446 } 2447 2448 SdevHeader->Length = 2449 sizeof (ACPI_SDEV_PCIE) + 2450 Pcie->PathLength + Pcie->VendorDataLength; 2451 break; 2452 2453 default: 2454 2455 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2456 return (AE_ERROR); 2457 } 2458 2459 DtPopSubtable (); 2460 } 2461 2462 return (AE_OK); 2463 } 2464 2465 2466 /****************************************************************************** 2467 * 2468 * FUNCTION: DtCompileSlic 2469 * 2470 * PARAMETERS: List - Current field list pointer 2471 * 2472 * RETURN: Status 2473 * 2474 * DESCRIPTION: Compile SLIC. 2475 * 2476 *****************************************************************************/ 2477 2478 ACPI_STATUS 2479 DtCompileSlic ( 2480 void **List) 2481 { 2482 ACPI_STATUS Status; 2483 DT_SUBTABLE *Subtable; 2484 DT_SUBTABLE *ParentTable; 2485 DT_FIELD **PFieldList = (DT_FIELD **) List; 2486 2487 2488 while (*PFieldList) 2489 { 2490 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, 2491 &Subtable); 2492 if (ACPI_FAILURE (Status)) 2493 { 2494 return (Status); 2495 } 2496 2497 ParentTable = DtPeekSubtable (); 2498 DtInsertSubtable (ParentTable, Subtable); 2499 DtPushSubtable (Subtable); 2500 DtPopSubtable (); 2501 } 2502 2503 return (AE_OK); 2504 } 2505 2506 2507 /****************************************************************************** 2508 * 2509 * FUNCTION: DtCompileSlit 2510 * 2511 * PARAMETERS: List - Current field list pointer 2512 * 2513 * RETURN: Status 2514 * 2515 * DESCRIPTION: Compile SLIT. 2516 * 2517 *****************************************************************************/ 2518 2519 ACPI_STATUS 2520 DtCompileSlit ( 2521 void **List) 2522 { 2523 ACPI_STATUS Status; 2524 DT_SUBTABLE *Subtable; 2525 DT_SUBTABLE *ParentTable; 2526 DT_FIELD **PFieldList = (DT_FIELD **) List; 2527 DT_FIELD *FieldList; 2528 DT_FIELD *EndOfFieldList = NULL; 2529 UINT32 Localities; 2530 UINT32 LocalityListLength; 2531 UINT8 *LocalityBuffer; 2532 2533 2534 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 2535 &Subtable); 2536 if (ACPI_FAILURE (Status)) 2537 { 2538 return (Status); 2539 } 2540 2541 ParentTable = DtPeekSubtable (); 2542 DtInsertSubtable (ParentTable, Subtable); 2543 2544 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 2545 LocalityBuffer = UtLocalCalloc (Localities); 2546 LocalityListLength = 0; 2547 2548 /* Compile each locality buffer */ 2549 2550 FieldList = *PFieldList; 2551 while (FieldList) 2552 { 2553 DtCompileBuffer (LocalityBuffer, 2554 FieldList->Value, FieldList, Localities); 2555 2556 LocalityListLength++; 2557 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 2558 DtInsertSubtable (ParentTable, Subtable); 2559 EndOfFieldList = FieldList; 2560 FieldList = FieldList->Next; 2561 } 2562 2563 if (LocalityListLength != Localities) 2564 { 2565 sprintf(AslGbl_MsgBuffer, 2566 "Found %u entries, must match LocalityCount: %u", 2567 LocalityListLength, Localities); 2568 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer); 2569 ACPI_FREE (LocalityBuffer); 2570 return (AE_LIMIT); 2571 } 2572 2573 ACPI_FREE (LocalityBuffer); 2574 return (AE_OK); 2575 } 2576 2577 2578 /****************************************************************************** 2579 * 2580 * FUNCTION: DtCompileSrat 2581 * 2582 * PARAMETERS: List - Current field list pointer 2583 * 2584 * RETURN: Status 2585 * 2586 * DESCRIPTION: Compile SRAT. 2587 * 2588 *****************************************************************************/ 2589 2590 ACPI_STATUS 2591 DtCompileSrat ( 2592 void **List) 2593 { 2594 ACPI_STATUS Status; 2595 DT_SUBTABLE *Subtable; 2596 DT_SUBTABLE *ParentTable; 2597 DT_FIELD **PFieldList = (DT_FIELD **) List; 2598 DT_FIELD *SubtableStart; 2599 ACPI_SUBTABLE_HEADER *SratHeader; 2600 ACPI_DMTABLE_INFO *InfoTable; 2601 2602 2603 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 2604 &Subtable); 2605 if (ACPI_FAILURE (Status)) 2606 { 2607 return (Status); 2608 } 2609 2610 ParentTable = DtPeekSubtable (); 2611 DtInsertSubtable (ParentTable, Subtable); 2612 2613 while (*PFieldList) 2614 { 2615 SubtableStart = *PFieldList; 2616 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 2617 &Subtable); 2618 if (ACPI_FAILURE (Status)) 2619 { 2620 return (Status); 2621 } 2622 2623 ParentTable = DtPeekSubtable (); 2624 DtInsertSubtable (ParentTable, Subtable); 2625 DtPushSubtable (Subtable); 2626 2627 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2628 2629 switch (SratHeader->Type) 2630 { 2631 case ACPI_SRAT_TYPE_CPU_AFFINITY: 2632 2633 InfoTable = AcpiDmTableInfoSrat0; 2634 break; 2635 2636 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 2637 2638 InfoTable = AcpiDmTableInfoSrat1; 2639 break; 2640 2641 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 2642 2643 InfoTable = AcpiDmTableInfoSrat2; 2644 break; 2645 2646 case ACPI_SRAT_TYPE_GICC_AFFINITY: 2647 2648 InfoTable = AcpiDmTableInfoSrat3; 2649 break; 2650 2651 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: 2652 2653 InfoTable = AcpiDmTableInfoSrat4; 2654 break; 2655 2656 case ACPI_SRAT_TYPE_GENERIC_AFFINITY: 2657 2658 InfoTable = AcpiDmTableInfoSrat5; 2659 break; 2660 2661 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY: 2662 2663 InfoTable = AcpiDmTableInfoSrat6; 2664 break; 2665 2666 case ACPI_SRAT_TYPE_RINTC_AFFINITY: 2667 2668 InfoTable = AcpiDmTableInfoSrat7; 2669 break; 2670 2671 default: 2672 2673 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 2674 return (AE_ERROR); 2675 } 2676 2677 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2678 if (ACPI_FAILURE (Status)) 2679 { 2680 return (Status); 2681 } 2682 2683 ParentTable = DtPeekSubtable (); 2684 DtInsertSubtable (ParentTable, Subtable); 2685 DtPopSubtable (); 2686 } 2687 2688 return (AE_OK); 2689 } 2690 2691 2692 /****************************************************************************** 2693 * 2694 * FUNCTION: DtCompileStao 2695 * 2696 * PARAMETERS: PFieldList - Current field list pointer 2697 * 2698 * RETURN: Status 2699 * 2700 * DESCRIPTION: Compile STAO. 2701 * 2702 *****************************************************************************/ 2703 2704 ACPI_STATUS 2705 DtCompileStao ( 2706 void **List) 2707 { 2708 DT_FIELD **PFieldList = (DT_FIELD **) List; 2709 DT_SUBTABLE *Subtable; 2710 DT_SUBTABLE *ParentTable; 2711 ACPI_STATUS Status; 2712 2713 2714 /* Compile the main table */ 2715 2716 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 2717 &Subtable); 2718 if (ACPI_FAILURE (Status)) 2719 { 2720 return (Status); 2721 } 2722 2723 ParentTable = DtPeekSubtable (); 2724 DtInsertSubtable (ParentTable, Subtable); 2725 2726 /* Compile each ASCII namestring as a subtable */ 2727 2728 while (*PFieldList) 2729 { 2730 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 2731 &Subtable); 2732 if (ACPI_FAILURE (Status)) 2733 { 2734 return (Status); 2735 } 2736 2737 ParentTable = DtPeekSubtable (); 2738 DtInsertSubtable (ParentTable, Subtable); 2739 } 2740 2741 return (AE_OK); 2742 } 2743 2744 2745 /****************************************************************************** 2746 * 2747 * FUNCTION: DtCompileSvkl 2748 * 2749 * PARAMETERS: PFieldList - Current field list pointer 2750 * 2751 * RETURN: Status 2752 * 2753 * DESCRIPTION: Compile SVKL. 2754 * 2755 * NOTES: SVKL is essentially a flat table, with a small main table and 2756 * a variable number of a single type of subtable. 2757 * 2758 *****************************************************************************/ 2759 2760 ACPI_STATUS 2761 DtCompileSvkl ( 2762 void **List) 2763 { 2764 DT_FIELD **PFieldList = (DT_FIELD **) List; 2765 DT_SUBTABLE *Subtable; 2766 DT_SUBTABLE *ParentTable; 2767 ACPI_STATUS Status; 2768 2769 2770 /* Compile the main table */ 2771 2772 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl, 2773 &Subtable); 2774 if (ACPI_FAILURE (Status)) 2775 { 2776 return (Status); 2777 } 2778 2779 ParentTable = DtPeekSubtable (); 2780 DtInsertSubtable (ParentTable, Subtable); 2781 2782 /* Compile each subtable */ 2783 2784 while (*PFieldList) 2785 { 2786 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0, 2787 &Subtable); 2788 if (ACPI_FAILURE (Status)) 2789 { 2790 return (Status); 2791 } 2792 2793 ParentTable = DtPeekSubtable (); 2794 DtInsertSubtable (ParentTable, Subtable); 2795 } 2796 2797 return (AE_OK); 2798 } 2799 2800 2801 /****************************************************************************** 2802 * 2803 * FUNCTION: DtCompileTcpa 2804 * 2805 * PARAMETERS: PFieldList - Current field list pointer 2806 * 2807 * RETURN: Status 2808 * 2809 * DESCRIPTION: Compile TCPA. 2810 * 2811 *****************************************************************************/ 2812 2813 ACPI_STATUS 2814 DtCompileTcpa ( 2815 void **List) 2816 { 2817 DT_FIELD **PFieldList = (DT_FIELD **) List; 2818 DT_SUBTABLE *Subtable; 2819 ACPI_TABLE_TCPA_HDR *TcpaHeader; 2820 DT_SUBTABLE *ParentTable; 2821 ACPI_STATUS Status; 2822 2823 2824 /* Compile the main table */ 2825 2826 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 2827 &Subtable); 2828 if (ACPI_FAILURE (Status)) 2829 { 2830 return (Status); 2831 } 2832 2833 ParentTable = DtPeekSubtable (); 2834 DtInsertSubtable (ParentTable, Subtable); 2835 2836 /* 2837 * Examine the PlatformClass field to determine the table type. 2838 * Either a client or server table. Only one. 2839 */ 2840 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 2841 2842 switch (TcpaHeader->PlatformClass) 2843 { 2844 case ACPI_TCPA_CLIENT_TABLE: 2845 2846 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 2847 &Subtable); 2848 break; 2849 2850 case ACPI_TCPA_SERVER_TABLE: 2851 2852 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 2853 &Subtable); 2854 break; 2855 2856 default: 2857 2858 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 2859 TcpaHeader->PlatformClass); 2860 Status = AE_ERROR; 2861 break; 2862 } 2863 2864 ParentTable = DtPeekSubtable (); 2865 DtInsertSubtable (ParentTable, Subtable); 2866 return (Status); 2867 } 2868 2869 2870 /****************************************************************************** 2871 * 2872 * FUNCTION: DtCompileTpm2Rev3 2873 * 2874 * PARAMETERS: PFieldList - Current field list pointer 2875 * 2876 * RETURN: Status 2877 * 2878 * DESCRIPTION: Compile TPM2 revision 3 2879 * 2880 *****************************************************************************/ 2881 static ACPI_STATUS 2882 DtCompileTpm2Rev3 ( 2883 void **List) 2884 { 2885 DT_FIELD **PFieldList = (DT_FIELD **) List; 2886 DT_SUBTABLE *Subtable; 2887 ACPI_TABLE_TPM23 *Tpm23Header; 2888 DT_SUBTABLE *ParentTable; 2889 ACPI_STATUS Status = AE_OK; 2890 2891 2892 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23, 2893 &Subtable); 2894 2895 ParentTable = DtPeekSubtable (); 2896 DtInsertSubtable (ParentTable, Subtable); 2897 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer); 2898 2899 /* Subtable type depends on the StartMethod */ 2900 2901 switch (Tpm23Header->StartMethod) 2902 { 2903 case ACPI_TPM23_ACPI_START_METHOD: 2904 2905 /* Subtable specific to to ARM_SMC */ 2906 2907 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a, 2908 &Subtable); 2909 if (ACPI_FAILURE (Status)) 2910 { 2911 return (Status); 2912 } 2913 2914 ParentTable = DtPeekSubtable (); 2915 DtInsertSubtable (ParentTable, Subtable); 2916 break; 2917 2918 default: 2919 break; 2920 } 2921 2922 return (Status); 2923 } 2924 2925 2926 /****************************************************************************** 2927 * 2928 * FUNCTION: DtCompileTpm2 2929 * 2930 * PARAMETERS: PFieldList - Current field list pointer 2931 * 2932 * RETURN: Status 2933 * 2934 * DESCRIPTION: Compile TPM2. 2935 * 2936 *****************************************************************************/ 2937 2938 ACPI_STATUS 2939 DtCompileTpm2 ( 2940 void **List) 2941 { 2942 DT_FIELD **PFieldList = (DT_FIELD **) List; 2943 DT_SUBTABLE *Subtable; 2944 ACPI_TABLE_TPM2 *Tpm2Header; 2945 DT_SUBTABLE *ParentTable; 2946 ACPI_STATUS Status = AE_OK; 2947 ACPI_TABLE_HEADER *Header; 2948 2949 2950 ParentTable = DtPeekSubtable (); 2951 2952 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2953 2954 if (Header->Revision == 3) 2955 { 2956 return (DtCompileTpm2Rev3 (List)); 2957 } 2958 2959 /* Compile the main table */ 2960 2961 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, 2962 &Subtable); 2963 if (ACPI_FAILURE (Status)) 2964 { 2965 return (Status); 2966 } 2967 2968 ParentTable = DtPeekSubtable (); 2969 DtInsertSubtable (ParentTable, Subtable); 2970 2971 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); 2972 2973 /* Method parameters */ 2974 /* Optional: Log area minimum length */ 2975 /* Optional: Log area start address */ 2976 /* TBD: Optional fields above not fully implemented (not optional at this time) */ 2977 2978 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, 2979 &Subtable); 2980 if (ACPI_FAILURE (Status)) 2981 { 2982 return (Status); 2983 } 2984 2985 ParentTable = DtPeekSubtable (); 2986 DtInsertSubtable (ParentTable, Subtable); 2987 2988 2989 /* Subtable type depends on the StartMethod */ 2990 2991 switch (Tpm2Header->StartMethod) 2992 { 2993 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 2994 2995 /* Subtable specific to to ARM_SMC */ 2996 2997 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, 2998 &Subtable); 2999 if (ACPI_FAILURE (Status)) 3000 { 3001 return (Status); 3002 } 3003 3004 ParentTable = DtPeekSubtable (); 3005 DtInsertSubtable (ParentTable, Subtable); 3006 break; 3007 3008 case ACPI_TPM2_START_METHOD: 3009 case ACPI_TPM2_MEMORY_MAPPED: 3010 case ACPI_TPM2_COMMAND_BUFFER: 3011 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: 3012 break; 3013 3014 case ACPI_TPM2_RESERVED1: 3015 case ACPI_TPM2_RESERVED3: 3016 case ACPI_TPM2_RESERVED4: 3017 case ACPI_TPM2_RESERVED5: 3018 case ACPI_TPM2_RESERVED9: 3019 case ACPI_TPM2_RESERVED10: 3020 3021 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", 3022 Tpm2Header->StartMethod); 3023 Status = AE_ERROR; 3024 break; 3025 3026 case ACPI_TPM2_NOT_ALLOWED: 3027 default: 3028 3029 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", 3030 Tpm2Header->StartMethod); 3031 Status = AE_ERROR; 3032 break; 3033 } 3034 3035 return (Status); 3036 } 3037 3038 3039 /****************************************************************************** 3040 * 3041 * FUNCTION: DtGetGenericTableInfo 3042 * 3043 * PARAMETERS: Name - Generic type name 3044 * 3045 * RETURN: Info entry 3046 * 3047 * DESCRIPTION: Obtain table info for a generic name entry 3048 * 3049 *****************************************************************************/ 3050 3051 ACPI_DMTABLE_INFO * 3052 DtGetGenericTableInfo ( 3053 char *Name) 3054 { 3055 ACPI_DMTABLE_INFO *Info; 3056 UINT32 i; 3057 3058 3059 if (!Name) 3060 { 3061 return (NULL); 3062 } 3063 3064 /* Search info table for name match */ 3065 3066 for (i = 0; ; i++) 3067 { 3068 Info = AcpiDmTableInfoGeneric[i]; 3069 if (Info->Opcode == ACPI_DMT_EXIT) 3070 { 3071 Info = NULL; 3072 break; 3073 } 3074 3075 /* Use caseless compare for generic keywords */ 3076 3077 if (!AcpiUtStricmp (Name, Info->Name)) 3078 { 3079 break; 3080 } 3081 } 3082 3083 return (Info); 3084 } 3085 3086 3087 /****************************************************************************** 3088 * 3089 * FUNCTION: DtCompileUefi 3090 * 3091 * PARAMETERS: List - Current field list pointer 3092 * 3093 * RETURN: Status 3094 * 3095 * DESCRIPTION: Compile UEFI. 3096 * 3097 *****************************************************************************/ 3098 3099 ACPI_STATUS 3100 DtCompileUefi ( 3101 void **List) 3102 { 3103 ACPI_STATUS Status; 3104 DT_SUBTABLE *Subtable; 3105 DT_SUBTABLE *ParentTable; 3106 DT_FIELD **PFieldList = (DT_FIELD **) List; 3107 UINT16 *DataOffset; 3108 3109 3110 /* Compile the predefined portion of the UEFI table */ 3111 3112 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 3113 &Subtable); 3114 if (ACPI_FAILURE (Status)) 3115 { 3116 return (Status); 3117 } 3118 3119 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 3120 *DataOffset = sizeof (ACPI_TABLE_UEFI); 3121 3122 ParentTable = DtPeekSubtable (); 3123 DtInsertSubtable (ParentTable, Subtable); 3124 3125 /* 3126 * Compile the "generic" portion of the UEFI table. This 3127 * part of the table is not predefined and any of the generic 3128 * operators may be used. 3129 */ 3130 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 3131 return (AE_OK); 3132 } 3133 3134 3135 /****************************************************************************** 3136 * 3137 * FUNCTION: DtCompileViot 3138 * 3139 * PARAMETERS: List - Current field list pointer 3140 * 3141 * RETURN: Status 3142 * 3143 * DESCRIPTION: Compile VIOT. 3144 * 3145 *****************************************************************************/ 3146 3147 ACPI_STATUS 3148 DtCompileViot ( 3149 void **List) 3150 { 3151 ACPI_STATUS Status; 3152 DT_SUBTABLE *Subtable; 3153 DT_SUBTABLE *ParentTable; 3154 DT_FIELD **PFieldList = (DT_FIELD **) List; 3155 DT_FIELD *SubtableStart; 3156 ACPI_TABLE_VIOT *Viot; 3157 ACPI_VIOT_HEADER *ViotHeader; 3158 ACPI_DMTABLE_INFO *InfoTable; 3159 UINT16 NodeCount; 3160 3161 ParentTable = DtPeekSubtable (); 3162 3163 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable); 3164 if (ACPI_FAILURE (Status)) 3165 { 3166 return (Status); 3167 } 3168 DtInsertSubtable (ParentTable, Subtable); 3169 3170 /* 3171 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 3172 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 3173 */ 3174 Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer, 3175 sizeof (ACPI_TABLE_HEADER)); 3176 3177 Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT); 3178 3179 NodeCount = 0; 3180 while (*PFieldList) { 3181 SubtableStart = *PFieldList; 3182 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader, 3183 &Subtable); 3184 if (ACPI_FAILURE (Status)) 3185 { 3186 return (Status); 3187 } 3188 3189 ParentTable = DtPeekSubtable (); 3190 DtInsertSubtable (ParentTable, Subtable); 3191 DtPushSubtable (Subtable); 3192 3193 ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer); 3194 3195 switch (ViotHeader->Type) 3196 { 3197 case ACPI_VIOT_NODE_PCI_RANGE: 3198 3199 InfoTable = AcpiDmTableInfoViot1; 3200 break; 3201 3202 case ACPI_VIOT_NODE_MMIO: 3203 3204 InfoTable = AcpiDmTableInfoViot2; 3205 break; 3206 3207 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI: 3208 3209 InfoTable = AcpiDmTableInfoViot3; 3210 break; 3211 3212 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO: 3213 3214 InfoTable = AcpiDmTableInfoViot4; 3215 break; 3216 3217 default: 3218 3219 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT"); 3220 return (AE_ERROR); 3221 } 3222 3223 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 3224 if (ACPI_FAILURE (Status)) 3225 { 3226 return (Status); 3227 } 3228 3229 ParentTable = DtPeekSubtable (); 3230 DtInsertSubtable (ParentTable, Subtable); 3231 DtPopSubtable (); 3232 NodeCount++; 3233 } 3234 3235 Viot->NodeCount = NodeCount; 3236 return (AE_OK); 3237 } 3238 3239 3240 /****************************************************************************** 3241 * 3242 * FUNCTION: DtCompileWdat 3243 * 3244 * PARAMETERS: List - Current field list pointer 3245 * 3246 * RETURN: Status 3247 * 3248 * DESCRIPTION: Compile WDAT. 3249 * 3250 *****************************************************************************/ 3251 3252 ACPI_STATUS 3253 DtCompileWdat ( 3254 void **List) 3255 { 3256 ACPI_STATUS Status; 3257 3258 3259 Status = DtCompileTwoSubtables (List, 3260 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 3261 return (Status); 3262 } 3263 3264 3265 /****************************************************************************** 3266 * 3267 * FUNCTION: DtCompileWpbt 3268 * 3269 * PARAMETERS: List - Current field list pointer 3270 * 3271 * RETURN: Status 3272 * 3273 * DESCRIPTION: Compile WPBT. 3274 * 3275 *****************************************************************************/ 3276 3277 ACPI_STATUS 3278 DtCompileWpbt ( 3279 void **List) 3280 { 3281 DT_FIELD **PFieldList = (DT_FIELD **) List; 3282 DT_SUBTABLE *Subtable; 3283 DT_SUBTABLE *ParentTable; 3284 ACPI_TABLE_WPBT *Table; 3285 ACPI_STATUS Status; 3286 3287 3288 /* Compile the main table */ 3289 3290 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable); 3291 if (ACPI_FAILURE (Status)) 3292 { 3293 return (Status); 3294 } 3295 3296 ParentTable = DtPeekSubtable (); 3297 DtInsertSubtable (ParentTable, Subtable); 3298 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 3299 3300 /* 3301 * Exit now if there are no arguments specified. This is indicated by: 3302 * The "Command-line Arguments" field has not been specified (if specified, 3303 * it will be the last field in the field list -- after the main table). 3304 * Set the Argument Length in the main table to zero. 3305 */ 3306 if (!*PFieldList) 3307 { 3308 Table->ArgumentsLength = 0; 3309 return (AE_OK); 3310 } 3311 3312 /* Compile the argument list subtable */ 3313 3314 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable); 3315 if (ACPI_FAILURE (Status)) 3316 { 3317 return (Status); 3318 } 3319 3320 /* Extract the length of the Arguments buffer, insert into main table */ 3321 3322 Table->ArgumentsLength = (UINT16) Subtable->TotalLength; 3323 DtInsertSubtable (ParentTable, Subtable); 3324 return (AE_OK); 3325 } 3326 3327 3328 /****************************************************************************** 3329 * 3330 * FUNCTION: DtCompileXsdt 3331 * 3332 * PARAMETERS: List - Current field list pointer 3333 * 3334 * RETURN: Status 3335 * 3336 * DESCRIPTION: Compile XSDT. 3337 * 3338 *****************************************************************************/ 3339 3340 ACPI_STATUS 3341 DtCompileXsdt ( 3342 void **List) 3343 { 3344 DT_SUBTABLE *Subtable; 3345 DT_SUBTABLE *ParentTable; 3346 DT_FIELD *FieldList = *(DT_FIELD **) List; 3347 UINT64 Address; 3348 3349 3350 ParentTable = DtPeekSubtable (); 3351 3352 while (FieldList) 3353 { 3354 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 3355 3356 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 3357 DtInsertSubtable (ParentTable, Subtable); 3358 FieldList = FieldList->Next; 3359 } 3360 3361 return (AE_OK); 3362 } 3363 3364 3365 /****************************************************************************** 3366 * 3367 * FUNCTION: DtCompileGeneric 3368 * 3369 * PARAMETERS: List - Current field list pointer 3370 * Name - Field name to end generic compiling 3371 * Length - Compiled table length to return 3372 * 3373 * RETURN: Status 3374 * 3375 * DESCRIPTION: Compile generic unknown table. 3376 * 3377 *****************************************************************************/ 3378 3379 ACPI_STATUS 3380 DtCompileGeneric ( 3381 void **List, 3382 char *Name, 3383 UINT32 *Length) 3384 { 3385 ACPI_STATUS Status; 3386 DT_SUBTABLE *Subtable; 3387 DT_SUBTABLE *ParentTable; 3388 DT_FIELD **PFieldList = (DT_FIELD **) List; 3389 ACPI_DMTABLE_INFO *Info; 3390 3391 3392 ParentTable = DtPeekSubtable (); 3393 3394 /* 3395 * Compile the "generic" portion of the table. This 3396 * part of the table is not predefined and any of the generic 3397 * operators may be used. 3398 */ 3399 3400 /* Find any and all labels in the entire generic portion */ 3401 3402 DtDetectAllLabels (*PFieldList); 3403 3404 /* Now we can actually compile the parse tree */ 3405 3406 if (Length && *Length) 3407 { 3408 *Length = 0; 3409 } 3410 while (*PFieldList) 3411 { 3412 if (Name && !strcmp ((*PFieldList)->Name, Name)) 3413 { 3414 break; 3415 } 3416 3417 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 3418 if (!Info) 3419 { 3420 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3421 (*PFieldList)->Name); 3422 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3423 (*PFieldList), AslGbl_MsgBuffer); 3424 3425 *PFieldList = (*PFieldList)->Next; 3426 continue; 3427 } 3428 3429 Status = DtCompileTable (PFieldList, Info, 3430 &Subtable); 3431 if (ACPI_SUCCESS (Status)) 3432 { 3433 DtInsertSubtable (ParentTable, Subtable); 3434 if (Length) 3435 { 3436 *Length += Subtable->Length; 3437 } 3438 } 3439 else 3440 { 3441 *PFieldList = (*PFieldList)->Next; 3442 3443 if (Status == AE_NOT_FOUND) 3444 { 3445 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3446 (*PFieldList)->Name); 3447 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3448 (*PFieldList), AslGbl_MsgBuffer); 3449 } 3450 } 3451 } 3452 3453 return (AE_OK); 3454 } 3455