1 /******************************************************************************
   2  *
   3  * Module Name: dttable.c - handling for specific ACPI tables
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2013, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 #define __DTTABLE_C__
  45 
  46 /* Compile all complex data tables */
  47 
  48 #include "aslcompiler.h"
  49 #include "dtcompiler.h"
  50 
  51 #define _COMPONENT          DT_COMPILER
  52         ACPI_MODULE_NAME    ("dttable")
  53 
  54 
  55 /* TBD: merge these into dmtbinfo.c? */
  56 
  57 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
  58 {
  59     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
  60     {ACPI_DMT_EXIT,     0,               NULL, 0}
  61 };
  62 
  63 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
  64 {
  65     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
  66     {ACPI_DMT_EXIT,     0,               NULL, 0}
  67 };
  68 
  69 
  70 /* TBD: move to acmacros.h */
  71 
  72 #define ACPI_SUB_PTR(t, a, b) \
  73     ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
  74 
  75 
  76 /* Local prototypes */
  77 
  78 static ACPI_STATUS
  79 DtCompileTwoSubtables (
  80     void                    **List,
  81     ACPI_DMTABLE_INFO       *TableInfo1,
  82     ACPI_DMTABLE_INFO       *TableInfo2);
  83 
  84 
  85 /******************************************************************************
  86  *
  87  * FUNCTION:    DtCompileTwoSubtables
  88  *
  89  * PARAMETERS:  List                - Current field list pointer
  90  *              TableInfo1          - Info table 1
  91  *              TableInfo1          - Info table 2
  92  *
  93  * RETURN:      Status
  94  *
  95  * DESCRIPTION: Compile tables with a header and one or more same subtables.
  96  *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
  97  *
  98  *****************************************************************************/
  99 
 100 static ACPI_STATUS
 101 DtCompileTwoSubtables (
 102     void                    **List,
 103     ACPI_DMTABLE_INFO       *TableInfo1,
 104     ACPI_DMTABLE_INFO       *TableInfo2)
 105 {
 106     ACPI_STATUS             Status;
 107     DT_SUBTABLE             *Subtable;
 108     DT_SUBTABLE             *ParentTable;
 109     DT_FIELD                **PFieldList = (DT_FIELD **) List;
 110 
 111 
 112     Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
 113     if (ACPI_FAILURE (Status))
 114     {
 115         return (Status);
 116     }
 117 
 118     ParentTable = DtPeekSubtable ();
 119     DtInsertSubtable (ParentTable, Subtable);
 120 
 121     while (*PFieldList)
 122     {
 123         Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
 124         if (ACPI_FAILURE (Status))
 125         {
 126             return (Status);
 127         }
 128 
 129         DtInsertSubtable (ParentTable, Subtable);
 130     }
 131 
 132     return (AE_OK);
 133 }
 134 
 135 
 136 /******************************************************************************
 137  *
 138  * FUNCTION:    DtCompileFacs
 139  *
 140  * PARAMETERS:  PFieldList          - Current field list pointer
 141  *
 142  * RETURN:      Status
 143  *
 144  * DESCRIPTION: Compile FACS.
 145  *
 146  *****************************************************************************/
 147 
 148 ACPI_STATUS
 149 DtCompileFacs (
 150     DT_FIELD                **PFieldList)
 151 {
 152     DT_SUBTABLE             *Subtable;
 153     UINT8                   *ReservedBuffer;
 154     ACPI_STATUS             Status;
 155     UINT32                  ReservedSize;
 156 
 157 
 158     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
 159                 &Gbl_RootTable, TRUE);
 160     if (ACPI_FAILURE (Status))
 161     {
 162         return (Status);
 163     }
 164 
 165     /* Large FACS reserved area at the end of the table */
 166 
 167     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
 168     ReservedBuffer = UtLocalCalloc (ReservedSize);
 169 
 170     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
 171 
 172     ACPI_FREE (ReservedBuffer);
 173     DtInsertSubtable (Gbl_RootTable, Subtable);
 174     return (AE_OK);
 175 }
 176 
 177 
 178 /******************************************************************************
 179  *
 180  * FUNCTION:    DtCompileRsdp
 181  *
 182  * PARAMETERS:  PFieldList          - Current field list pointer
 183  *
 184  * RETURN:      Status
 185  *
 186  * DESCRIPTION: Compile RSDP.
 187  *
 188  *****************************************************************************/
 189 
 190 ACPI_STATUS
 191 DtCompileRsdp (
 192     DT_FIELD                **PFieldList)
 193 {
 194     DT_SUBTABLE             *Subtable;
 195     ACPI_TABLE_RSDP         *Rsdp;
 196     ACPI_RSDP_EXTENSION     *RsdpExtension;
 197     ACPI_STATUS             Status;
 198 
 199 
 200     /* Compile the "common" RSDP (ACPI 1.0) */
 201 
 202     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
 203                 &Gbl_RootTable, TRUE);
 204     if (ACPI_FAILURE (Status))
 205     {
 206         return (Status);
 207     }
 208 
 209     Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
 210     DtSetTableChecksum (&Rsdp->Checksum);
 211 
 212     if (Rsdp->Revision > 0)
 213     {
 214         /* Compile the "extended" part of the RSDP as a subtable */
 215 
 216         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
 217                     &Subtable, TRUE);
 218         if (ACPI_FAILURE (Status))
 219         {
 220             return (Status);
 221         }
 222 
 223         DtInsertSubtable (Gbl_RootTable, Subtable);
 224 
 225         /* Set length and extended checksum for entire RSDP */
 226 
 227         RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
 228         RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
 229         DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
 230     }
 231 
 232     return (AE_OK);
 233 }
 234 
 235 
 236 /******************************************************************************
 237  *
 238  * FUNCTION:    DtCompileAsf
 239  *
 240  * PARAMETERS:  List                - Current field list pointer
 241  *
 242  * RETURN:      Status
 243  *
 244  * DESCRIPTION: Compile ASF!.
 245  *
 246  *****************************************************************************/
 247 
 248 ACPI_STATUS
 249 DtCompileAsf (
 250     void                    **List)
 251 {
 252     ACPI_ASF_INFO           *AsfTable;
 253     DT_SUBTABLE             *Subtable;
 254     DT_SUBTABLE             *ParentTable;
 255     ACPI_DMTABLE_INFO       *InfoTable;
 256     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
 257     UINT32                  DataCount = 0;
 258     ACPI_STATUS             Status;
 259     UINT32                  i;
 260     DT_FIELD                **PFieldList = (DT_FIELD **) List;
 261     DT_FIELD                *SubtableStart;
 262 
 263 
 264     while (*PFieldList)
 265     {
 266         SubtableStart = *PFieldList;
 267         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
 268                     &Subtable, TRUE);
 269         if (ACPI_FAILURE (Status))
 270         {
 271             return (Status);
 272         }
 273 
 274         ParentTable = DtPeekSubtable ();
 275         DtInsertSubtable (ParentTable, Subtable);
 276         DtPushSubtable (Subtable);
 277 
 278         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
 279 
 280         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
 281         {
 282         case ACPI_ASF_TYPE_INFO:
 283 
 284             InfoTable = AcpiDmTableInfoAsf0;
 285             break;
 286 
 287         case ACPI_ASF_TYPE_ALERT:
 288 
 289             InfoTable = AcpiDmTableInfoAsf1;
 290             break;
 291 
 292         case ACPI_ASF_TYPE_CONTROL:
 293 
 294             InfoTable = AcpiDmTableInfoAsf2;
 295             break;
 296 
 297         case ACPI_ASF_TYPE_BOOT:
 298 
 299             InfoTable = AcpiDmTableInfoAsf3;
 300             break;
 301 
 302         case ACPI_ASF_TYPE_ADDRESS:
 303 
 304             InfoTable = AcpiDmTableInfoAsf4;
 305             break;
 306 
 307         default:
 308 
 309             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
 310             return (AE_ERROR);
 311         }
 312 
 313         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
 314         if (ACPI_FAILURE (Status))
 315         {
 316             return (Status);
 317         }
 318 
 319         ParentTable = DtPeekSubtable ();
 320         DtInsertSubtable (ParentTable, Subtable);
 321 
 322         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
 323         {
 324         case ACPI_ASF_TYPE_INFO:
 325 
 326             DataInfoTable = NULL;
 327             break;
 328 
 329         case ACPI_ASF_TYPE_ALERT:
 330 
 331             DataInfoTable = AcpiDmTableInfoAsf1a;
 332             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
 333                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
 334                             sizeof (ACPI_ASF_HEADER)))->Alerts;
 335             break;
 336 
 337         case ACPI_ASF_TYPE_CONTROL:
 338 
 339             DataInfoTable = AcpiDmTableInfoAsf2a;
 340             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
 341                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
 342                             sizeof (ACPI_ASF_HEADER)))->Controls;
 343             break;
 344 
 345         case ACPI_ASF_TYPE_BOOT:
 346 
 347             DataInfoTable = NULL;
 348             break;
 349 
 350         case ACPI_ASF_TYPE_ADDRESS:
 351 
 352             DataInfoTable = TableInfoAsfAddress;
 353             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
 354                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
 355                             sizeof (ACPI_ASF_HEADER)))->Devices;
 356             break;
 357 
 358         default:
 359 
 360             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
 361             return (AE_ERROR);
 362         }
 363 
 364         if (DataInfoTable)
 365         {
 366             switch (AsfTable->Header.Type & 0x7F)
 367             {
 368             case ACPI_ASF_TYPE_ADDRESS:
 369 
 370                 while (DataCount > 0)
 371                 {
 372                     Status = DtCompileTable (PFieldList, DataInfoTable,
 373                                 &Subtable, TRUE);
 374                     if (ACPI_FAILURE (Status))
 375                     {
 376                         return (Status);
 377                     }
 378 
 379                     DtInsertSubtable (ParentTable, Subtable);
 380                     DataCount = DataCount - Subtable->Length;
 381                 }
 382                 break;
 383 
 384             default:
 385 
 386                 for (i = 0; i < DataCount; i++)
 387                 {
 388                     Status = DtCompileTable (PFieldList, DataInfoTable,
 389                                 &Subtable, TRUE);
 390                     if (ACPI_FAILURE (Status))
 391                     {
 392                         return (Status);
 393                     }
 394 
 395                     DtInsertSubtable (ParentTable, Subtable);
 396                 }
 397                 break;
 398             }
 399         }
 400 
 401         DtPopSubtable ();
 402     }
 403 
 404     return (AE_OK);
 405 }
 406 
 407 
 408 /******************************************************************************
 409  *
 410  * FUNCTION:    DtCompileCpep
 411  *
 412  * PARAMETERS:  List                - Current field list pointer
 413  *
 414  * RETURN:      Status
 415  *
 416  * DESCRIPTION: Compile CPEP.
 417  *
 418  *****************************************************************************/
 419 
 420 ACPI_STATUS
 421 DtCompileCpep (
 422     void                    **List)
 423 {
 424     ACPI_STATUS             Status;
 425 
 426 
 427     Status = DtCompileTwoSubtables (List,
 428                  AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
 429     return (Status);
 430 }
 431 
 432 
 433 /******************************************************************************
 434  *
 435  * FUNCTION:    DtCompileCsrt
 436  *
 437  * PARAMETERS:  List                - Current field list pointer
 438  *
 439  * RETURN:      Status
 440  *
 441  * DESCRIPTION: Compile CSRT.
 442  *
 443  *****************************************************************************/
 444 
 445 ACPI_STATUS
 446 DtCompileCsrt (
 447     void                    **List)
 448 {
 449     ACPI_STATUS             Status = AE_OK;
 450     DT_SUBTABLE             *Subtable;
 451     DT_SUBTABLE             *ParentTable;
 452     DT_FIELD                **PFieldList = (DT_FIELD **) List;
 453     UINT32                  DescriptorCount;
 454     UINT32                  GroupLength;
 455 
 456 
 457     /* Sub-tables (Resource Groups) */
 458 
 459     while (*PFieldList)
 460     {
 461         /* Resource group subtable */
 462 
 463         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
 464                     &Subtable, TRUE);
 465         if (ACPI_FAILURE (Status))
 466         {
 467             return (Status);
 468         }
 469 
 470         /* Compute the number of resource descriptors */
 471 
 472         GroupLength =
 473             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
 474                 Subtable->Buffer))->Length -
 475             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
 476                 Subtable->Buffer))->SharedInfoLength -
 477             sizeof (ACPI_CSRT_GROUP);
 478 
 479         DescriptorCount = (GroupLength  /
 480             sizeof (ACPI_CSRT_DESCRIPTOR));
 481 
 482         ParentTable = DtPeekSubtable ();
 483         DtInsertSubtable (ParentTable, Subtable);
 484         DtPushSubtable (Subtable);
 485 
 486         /* Shared info subtable (One per resource group) */
 487 
 488         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
 489                     &Subtable, TRUE);
 490         if (ACPI_FAILURE (Status))
 491         {
 492             return (Status);
 493         }
 494 
 495         ParentTable = DtPeekSubtable ();
 496         DtInsertSubtable (ParentTable, Subtable);
 497 
 498         /* Sub-Subtables (Resource Descriptors) */
 499 
 500         while (*PFieldList && DescriptorCount)
 501         {
 502             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
 503                         &Subtable, TRUE);
 504             if (ACPI_FAILURE (Status))
 505             {
 506                 return (Status);
 507             }
 508 
 509             ParentTable = DtPeekSubtable ();
 510             DtInsertSubtable (ParentTable, Subtable);
 511             DescriptorCount--;
 512         }
 513 
 514         DtPopSubtable ();
 515     }
 516 
 517     return (Status);
 518 }
 519 
 520 
 521 /******************************************************************************
 522  *
 523  * FUNCTION:    DtCompileDbg2
 524  *
 525  * PARAMETERS:  List                - Current field list pointer
 526  *
 527  * RETURN:      Status
 528  *
 529  * DESCRIPTION: Compile DBG2.
 530  *
 531  *****************************************************************************/
 532 
 533 ACPI_STATUS
 534 DtCompileDbg2 (
 535     void                    **List)
 536 {
 537     ACPI_STATUS             Status;
 538     DT_SUBTABLE             *Subtable;
 539     DT_SUBTABLE             *ParentTable;
 540     DT_FIELD                **PFieldList = (DT_FIELD **) List;
 541     UINT32                  SubtableCount;
 542     ACPI_DBG2_HEADER        *Dbg2Header;
 543     ACPI_DBG2_DEVICE        *DeviceInfo;
 544     UINT16                  CurrentOffset;
 545     UINT32                  i;
 546 
 547 
 548     /* Main table */
 549 
 550     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
 551     if (ACPI_FAILURE (Status))
 552     {
 553         return (Status);
 554     }
 555 
 556     ParentTable = DtPeekSubtable ();
 557     DtInsertSubtable (ParentTable, Subtable);
 558 
 559     /* Main table fields */
 560 
 561     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
 562     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
 563         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
 564 
 565     SubtableCount = Dbg2Header->InfoCount;
 566     DtPushSubtable (Subtable);
 567 
 568     /* Process all Device Information subtables (Count = InfoCount) */
 569 
 570     while (*PFieldList && SubtableCount)
 571     {
 572         /* Subtable: Debug Device Information */
 573 
 574         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
 575                     &Subtable, TRUE);
 576         if (ACPI_FAILURE (Status))
 577         {
 578             return (Status);
 579         }
 580 
 581         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
 582         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
 583 
 584         ParentTable = DtPeekSubtable ();
 585         DtInsertSubtable (ParentTable, Subtable);
 586         DtPushSubtable (Subtable);
 587 
 588         ParentTable = DtPeekSubtable ();
 589 
 590         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
 591 
 592         DeviceInfo->BaseAddressOffset = CurrentOffset;
 593         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
 594         {
 595             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
 596                         &Subtable, TRUE);
 597             if (ACPI_FAILURE (Status))
 598             {
 599                 return (Status);
 600             }
 601 
 602             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
 603             DtInsertSubtable (ParentTable, Subtable);
 604         }
 605 
 606         /* AddressSize array (Required, size = RegisterCount) */
 607 
 608         DeviceInfo->AddressSizeOffset = CurrentOffset;
 609         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
 610         {
 611             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
 612                         &Subtable, TRUE);
 613             if (ACPI_FAILURE (Status))
 614             {
 615                 return (Status);
 616             }
 617 
 618             CurrentOffset += (UINT16) sizeof (UINT32);
 619             DtInsertSubtable (ParentTable, Subtable);
 620         }
 621 
 622         /* NamespaceString device identifier (Required, size = NamePathLength) */
 623 
 624         DeviceInfo->NamepathOffset = CurrentOffset;
 625         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
 626                     &Subtable, TRUE);
 627         if (ACPI_FAILURE (Status))
 628         {
 629             return (Status);
 630         }
 631 
 632         /* Update the device info header */
 633 
 634         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
 635         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
 636         DtInsertSubtable (ParentTable, Subtable);
 637 
 638         /* OemData - Variable-length data (Optional, size = OemDataLength) */
 639 
 640         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
 641                     &Subtable, TRUE);
 642         if (ACPI_FAILURE (Status))
 643         {
 644             return (Status);
 645         }
 646 
 647         /* Update the device info header (zeros if no OEM data present) */
 648 
 649         DeviceInfo->OemDataOffset = 0;
 650         DeviceInfo->OemDataLength = 0;
 651 
 652         /* Optional subtable (OemData) */
 653 
 654         if (Subtable && Subtable->Length)
 655         {
 656             DeviceInfo->OemDataOffset = CurrentOffset;
 657             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
 658 
 659             DtInsertSubtable (ParentTable, Subtable);
 660         }
 661 
 662         SubtableCount--;
 663         DtPopSubtable (); /* Get next Device Information subtable */
 664     }
 665 
 666     DtPopSubtable ();
 667     return (AE_OK);
 668 }
 669 
 670 
 671 /******************************************************************************
 672  *
 673  * FUNCTION:    DtCompileDmar
 674  *
 675  * PARAMETERS:  List                - Current field list pointer
 676  *
 677  * RETURN:      Status
 678  *
 679  * DESCRIPTION: Compile DMAR.
 680  *
 681  *****************************************************************************/
 682 
 683 ACPI_STATUS
 684 DtCompileDmar (
 685     void                    **List)
 686 {
 687     ACPI_STATUS             Status;
 688     DT_SUBTABLE             *Subtable;
 689     DT_SUBTABLE             *ParentTable;
 690     DT_FIELD                **PFieldList = (DT_FIELD **) List;
 691     DT_FIELD                *SubtableStart;
 692     ACPI_DMTABLE_INFO       *InfoTable;
 693     ACPI_DMAR_HEADER        *DmarHeader;
 694     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
 695     UINT32                  DeviceScopeLength;
 696     UINT32                  PciPathLength;
 697 
 698 
 699     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
 700     if (ACPI_FAILURE (Status))
 701     {
 702         return (Status);
 703     }
 704 
 705     ParentTable = DtPeekSubtable ();
 706     DtInsertSubtable (ParentTable, Subtable);
 707     DtPushSubtable (Subtable);
 708 
 709     while (*PFieldList)
 710     {
 711         /* DMAR Header */
 712 
 713         SubtableStart = *PFieldList;
 714         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
 715                     &Subtable, TRUE);
 716         if (ACPI_FAILURE (Status))
 717         {
 718             return (Status);
 719         }
 720 
 721         ParentTable = DtPeekSubtable ();
 722         DtInsertSubtable (ParentTable, Subtable);
 723         DtPushSubtable (Subtable);
 724 
 725         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
 726 
 727         switch (DmarHeader->Type)
 728         {
 729         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
 730 
 731             InfoTable = AcpiDmTableInfoDmar0;
 732             break;
 733 
 734         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
 735 
 736             InfoTable = AcpiDmTableInfoDmar1;
 737             break;
 738 
 739         case ACPI_DMAR_TYPE_ATSR:
 740 
 741             InfoTable = AcpiDmTableInfoDmar2;
 742             break;
 743 
 744         case ACPI_DMAR_HARDWARE_AFFINITY:
 745 
 746             InfoTable = AcpiDmTableInfoDmar3;
 747             break;
 748 
 749         default:
 750 
 751             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
 752             return (AE_ERROR);
 753         }
 754 
 755         /* DMAR Subtable */
 756 
 757         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
 758         if (ACPI_FAILURE (Status))
 759         {
 760             return (Status);
 761         }
 762 
 763         ParentTable = DtPeekSubtable ();
 764         DtInsertSubtable (ParentTable, Subtable);
 765         DtPushSubtable (Subtable);
 766 
 767         /* Optional Device Scope subtables */
 768 
 769         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
 770             ParentTable->Length;
 771         while (DeviceScopeLength)
 772         {
 773             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
 774                         &Subtable, FALSE);
 775             if (Status == AE_NOT_FOUND)
 776             {
 777                 break;
 778             }
 779 
 780             ParentTable = DtPeekSubtable ();
 781             DtInsertSubtable (ParentTable, Subtable);
 782             DtPushSubtable (Subtable);
 783 
 784             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
 785 
 786             /* Optional PCI Paths */
 787 
 788             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
 789             while (PciPathLength)
 790             {
 791                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
 792                             &Subtable, FALSE);
 793                 if (Status == AE_NOT_FOUND)
 794                 {
 795                     DtPopSubtable ();
 796                     break;
 797                 }
 798 
 799                 ParentTable = DtPeekSubtable ();
 800                 DtInsertSubtable (ParentTable, Subtable);
 801                 PciPathLength -= Subtable->Length;
 802             }
 803 
 804             DtPopSubtable ();
 805             DeviceScopeLength -= DmarDeviceScope->Length;
 806         }
 807 
 808         DtPopSubtable ();
 809         DtPopSubtable ();
 810     }
 811 
 812     return (AE_OK);
 813 }
 814 
 815 
 816 /******************************************************************************
 817  *
 818  * FUNCTION:    DtCompileEinj
 819  *
 820  * PARAMETERS:  List                - Current field list pointer
 821  *
 822  * RETURN:      Status
 823  *
 824  * DESCRIPTION: Compile EINJ.
 825  *
 826  *****************************************************************************/
 827 
 828 ACPI_STATUS
 829 DtCompileEinj (
 830     void                    **List)
 831 {
 832     ACPI_STATUS             Status;
 833 
 834 
 835     Status = DtCompileTwoSubtables (List,
 836                  AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
 837     return (Status);
 838 }
 839 
 840 
 841 /******************************************************************************
 842  *
 843  * FUNCTION:    DtCompileErst
 844  *
 845  * PARAMETERS:  List                - Current field list pointer
 846  *
 847  * RETURN:      Status
 848  *
 849  * DESCRIPTION: Compile ERST.
 850  *
 851  *****************************************************************************/
 852 
 853 ACPI_STATUS
 854 DtCompileErst (
 855     void                    **List)
 856 {
 857     ACPI_STATUS             Status;
 858 
 859 
 860     Status = DtCompileTwoSubtables (List,
 861                  AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
 862     return (Status);
 863 }
 864 
 865 
 866 /******************************************************************************
 867  *
 868  * FUNCTION:    DtCompileFadt
 869  *
 870  * PARAMETERS:  List                - Current field list pointer
 871  *
 872  * RETURN:      Status
 873  *
 874  * DESCRIPTION: Compile FADT.
 875  *
 876  *****************************************************************************/
 877 
 878 ACPI_STATUS
 879 DtCompileFadt (
 880     void                    **List)
 881 {
 882     ACPI_STATUS             Status;
 883     DT_SUBTABLE             *Subtable;
 884     DT_SUBTABLE             *ParentTable;
 885     DT_FIELD                **PFieldList = (DT_FIELD **) List;
 886     ACPI_TABLE_HEADER       *Table;
 887     UINT8                   Revision;
 888 
 889 
 890     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
 891                 &Subtable, TRUE);
 892     if (ACPI_FAILURE (Status))
 893     {
 894         return (Status);
 895     }
 896 
 897     ParentTable = DtPeekSubtable ();
 898     DtInsertSubtable (ParentTable, Subtable);
 899 
 900     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
 901     Revision = Table->Revision;
 902 
 903     if (Revision == 2)
 904     {
 905         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
 906                     &Subtable, TRUE);
 907         if (ACPI_FAILURE (Status))
 908         {
 909             return (Status);
 910         }
 911 
 912         DtInsertSubtable (ParentTable, Subtable);
 913     }
 914     else if (Revision >= 2)
 915     {
 916         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
 917                     &Subtable, TRUE);
 918         if (ACPI_FAILURE (Status))
 919         {
 920             return (Status);
 921         }
 922 
 923         DtInsertSubtable (ParentTable, Subtable);
 924 
 925         if (Revision >= 5)
 926         {
 927             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
 928                         &Subtable, TRUE);
 929             if (ACPI_FAILURE (Status))
 930             {
 931                 return (Status);
 932             }
 933 
 934             DtInsertSubtable (ParentTable, Subtable);
 935         }
 936     }
 937 
 938     return (AE_OK);
 939 }
 940 
 941 
 942 /******************************************************************************
 943  *
 944  * FUNCTION:    DtCompileFpdt
 945  *
 946  * PARAMETERS:  List                - Current field list pointer
 947  *
 948  * RETURN:      Status
 949  *
 950  * DESCRIPTION: Compile FPDT.
 951  *
 952  *****************************************************************************/
 953 
 954 ACPI_STATUS
 955 DtCompileFpdt (
 956     void                    **List)
 957 {
 958     ACPI_STATUS             Status;
 959     ACPI_FPDT_HEADER        *FpdtHeader;
 960     DT_SUBTABLE             *Subtable;
 961     DT_SUBTABLE             *ParentTable;
 962     ACPI_DMTABLE_INFO       *InfoTable;
 963     DT_FIELD                **PFieldList = (DT_FIELD **) List;
 964     DT_FIELD                *SubtableStart;
 965 
 966 
 967     while (*PFieldList)
 968     {
 969         SubtableStart = *PFieldList;
 970         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
 971                     &Subtable, TRUE);
 972         if (ACPI_FAILURE (Status))
 973         {
 974             return (Status);
 975         }
 976 
 977         ParentTable = DtPeekSubtable ();
 978         DtInsertSubtable (ParentTable, Subtable);
 979         DtPushSubtable (Subtable);
 980 
 981         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
 982 
 983         switch (FpdtHeader->Type)
 984         {
 985         case ACPI_FPDT_TYPE_BOOT:
 986 
 987             InfoTable = AcpiDmTableInfoFpdt0;
 988             break;
 989 
 990         case ACPI_FPDT_TYPE_S3PERF:
 991 
 992             InfoTable = AcpiDmTableInfoFpdt1;
 993             break;
 994 
 995         default:
 996 
 997             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
 998             return (AE_ERROR);
 999             break;
1000         }
1001 
1002         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1003         if (ACPI_FAILURE (Status))
1004         {
1005             return (Status);
1006         }
1007 
1008         ParentTable = DtPeekSubtable ();
1009         DtInsertSubtable (ParentTable, Subtable);
1010         DtPopSubtable ();
1011     }
1012 
1013     return (AE_OK);
1014 }
1015 
1016 
1017 /******************************************************************************
1018  *
1019  * FUNCTION:    DtCompileHest
1020  *
1021  * PARAMETERS:  List                - Current field list pointer
1022  *
1023  * RETURN:      Status
1024  *
1025  * DESCRIPTION: Compile HEST.
1026  *
1027  *****************************************************************************/
1028 
1029 ACPI_STATUS
1030 DtCompileHest (
1031     void                    **List)
1032 {
1033     ACPI_STATUS             Status;
1034     DT_SUBTABLE             *Subtable;
1035     DT_SUBTABLE             *ParentTable;
1036     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1037     DT_FIELD                *SubtableStart;
1038     ACPI_DMTABLE_INFO       *InfoTable;
1039     UINT16                  Type;
1040     UINT32                  BankCount;
1041 
1042 
1043     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1044                 &Subtable, TRUE);
1045     if (ACPI_FAILURE (Status))
1046     {
1047         return (Status);
1048     }
1049 
1050     ParentTable = DtPeekSubtable ();
1051     DtInsertSubtable (ParentTable, Subtable);
1052 
1053     while (*PFieldList)
1054     {
1055         /* Get subtable type */
1056 
1057         SubtableStart = *PFieldList;
1058         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1059 
1060         switch (Type)
1061         {
1062         case ACPI_HEST_TYPE_IA32_CHECK:
1063 
1064             InfoTable = AcpiDmTableInfoHest0;
1065             break;
1066 
1067         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1068 
1069             InfoTable = AcpiDmTableInfoHest1;
1070             break;
1071 
1072         case ACPI_HEST_TYPE_IA32_NMI:
1073 
1074             InfoTable = AcpiDmTableInfoHest2;
1075             break;
1076 
1077         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1078 
1079             InfoTable = AcpiDmTableInfoHest6;
1080             break;
1081 
1082         case ACPI_HEST_TYPE_AER_ENDPOINT:
1083 
1084             InfoTable = AcpiDmTableInfoHest7;
1085             break;
1086 
1087         case ACPI_HEST_TYPE_AER_BRIDGE:
1088 
1089             InfoTable = AcpiDmTableInfoHest8;
1090             break;
1091 
1092         case ACPI_HEST_TYPE_GENERIC_ERROR:
1093 
1094             InfoTable = AcpiDmTableInfoHest9;
1095             break;
1096 
1097         default:
1098 
1099             /* Cannot continue on unknown type */
1100 
1101             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1102             return (AE_ERROR);
1103         }
1104 
1105         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1106         if (ACPI_FAILURE (Status))
1107         {
1108             return (Status);
1109         }
1110 
1111         DtInsertSubtable (ParentTable, Subtable);
1112 
1113         /*
1114          * Additional subtable data - IA32 Error Bank(s)
1115          */
1116         BankCount = 0;
1117         switch (Type)
1118         {
1119         case ACPI_HEST_TYPE_IA32_CHECK:
1120 
1121             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1122                             Subtable->Buffer))->NumHardwareBanks;
1123             break;
1124 
1125         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1126 
1127             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1128                             Subtable->Buffer))->NumHardwareBanks;
1129             break;
1130 
1131         default:
1132 
1133             break;
1134         }
1135 
1136         while (BankCount)
1137         {
1138             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1139                         &Subtable, TRUE);
1140             if (ACPI_FAILURE (Status))
1141             {
1142                 return (Status);
1143             }
1144 
1145             DtInsertSubtable (ParentTable, Subtable);
1146             BankCount--;
1147         }
1148     }
1149 
1150     return (AE_OK);
1151 }
1152 
1153 
1154 /******************************************************************************
1155  *
1156  * FUNCTION:    DtCompileIvrs
1157  *
1158  * PARAMETERS:  List                - Current field list pointer
1159  *
1160  * RETURN:      Status
1161  *
1162  * DESCRIPTION: Compile IVRS.
1163  *
1164  *****************************************************************************/
1165 
1166 ACPI_STATUS
1167 DtCompileIvrs (
1168     void                    **List)
1169 {
1170     ACPI_STATUS             Status;
1171     DT_SUBTABLE             *Subtable;
1172     DT_SUBTABLE             *ParentTable;
1173     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1174     DT_FIELD                *SubtableStart;
1175     ACPI_DMTABLE_INFO       *InfoTable;
1176     ACPI_IVRS_HEADER        *IvrsHeader;
1177     UINT8                   EntryType;
1178 
1179 
1180     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1181                 &Subtable, TRUE);
1182     if (ACPI_FAILURE (Status))
1183     {
1184         return (Status);
1185     }
1186 
1187     ParentTable = DtPeekSubtable ();
1188     DtInsertSubtable (ParentTable, Subtable);
1189 
1190     while (*PFieldList)
1191     {
1192         SubtableStart = *PFieldList;
1193         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1194                     &Subtable, TRUE);
1195         if (ACPI_FAILURE (Status))
1196         {
1197             return (Status);
1198         }
1199 
1200         ParentTable = DtPeekSubtable ();
1201         DtInsertSubtable (ParentTable, Subtable);
1202         DtPushSubtable (Subtable);
1203 
1204         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1205 
1206         switch (IvrsHeader->Type)
1207         {
1208         case ACPI_IVRS_TYPE_HARDWARE:
1209 
1210             InfoTable = AcpiDmTableInfoIvrs0;
1211             break;
1212 
1213         case ACPI_IVRS_TYPE_MEMORY1:
1214         case ACPI_IVRS_TYPE_MEMORY2:
1215         case ACPI_IVRS_TYPE_MEMORY3:
1216 
1217             InfoTable = AcpiDmTableInfoIvrs1;
1218             break;
1219 
1220         default:
1221 
1222             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1223             return (AE_ERROR);
1224         }
1225 
1226         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1227         if (ACPI_FAILURE (Status))
1228         {
1229             return (Status);
1230         }
1231 
1232         ParentTable = DtPeekSubtable ();
1233         DtInsertSubtable (ParentTable, Subtable);
1234 
1235         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1236         {
1237             while (*PFieldList &&
1238                     !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
1239             {
1240                 SubtableStart = *PFieldList;
1241                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1242 
1243                 switch (EntryType)
1244                 {
1245                 /* 4-byte device entries */
1246 
1247                 case ACPI_IVRS_TYPE_PAD4:
1248                 case ACPI_IVRS_TYPE_ALL:
1249                 case ACPI_IVRS_TYPE_SELECT:
1250                 case ACPI_IVRS_TYPE_START:
1251                 case ACPI_IVRS_TYPE_END:
1252 
1253                     InfoTable = AcpiDmTableInfoIvrs4;
1254                     break;
1255 
1256                 /* 8-byte entries, type A */
1257 
1258                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1259                 case ACPI_IVRS_TYPE_ALIAS_START:
1260 
1261                     InfoTable = AcpiDmTableInfoIvrs8a;
1262                     break;
1263 
1264                 /* 8-byte entries, type B */
1265 
1266                 case ACPI_IVRS_TYPE_PAD8:
1267                 case ACPI_IVRS_TYPE_EXT_SELECT:
1268                 case ACPI_IVRS_TYPE_EXT_START:
1269 
1270                     InfoTable = AcpiDmTableInfoIvrs8b;
1271                     break;
1272 
1273                 /* 8-byte entries, type C */
1274 
1275                 case ACPI_IVRS_TYPE_SPECIAL:
1276 
1277                     InfoTable = AcpiDmTableInfoIvrs8c;
1278                     break;
1279 
1280                 default:
1281 
1282                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1283                         "IVRS Device Entry");
1284                     return (AE_ERROR);
1285                 }
1286 
1287                 Status = DtCompileTable (PFieldList, InfoTable,
1288                             &Subtable, TRUE);
1289                 if (ACPI_FAILURE (Status))
1290                 {
1291                     return (Status);
1292                 }
1293 
1294                 DtInsertSubtable (ParentTable, Subtable);
1295             }
1296         }
1297 
1298         DtPopSubtable ();
1299     }
1300 
1301     return (AE_OK);
1302 }
1303 
1304 
1305 /******************************************************************************
1306  *
1307  * FUNCTION:    DtCompileMadt
1308  *
1309  * PARAMETERS:  List                - Current field list pointer
1310  *
1311  * RETURN:      Status
1312  *
1313  * DESCRIPTION: Compile MADT.
1314  *
1315  *****************************************************************************/
1316 
1317 ACPI_STATUS
1318 DtCompileMadt (
1319     void                    **List)
1320 {
1321     ACPI_STATUS             Status;
1322     DT_SUBTABLE             *Subtable;
1323     DT_SUBTABLE             *ParentTable;
1324     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1325     DT_FIELD                *SubtableStart;
1326     ACPI_SUBTABLE_HEADER    *MadtHeader;
1327     ACPI_DMTABLE_INFO       *InfoTable;
1328 
1329 
1330     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1331                 &Subtable, TRUE);
1332     if (ACPI_FAILURE (Status))
1333     {
1334         return (Status);
1335     }
1336 
1337     ParentTable = DtPeekSubtable ();
1338     DtInsertSubtable (ParentTable, Subtable);
1339 
1340     while (*PFieldList)
1341     {
1342         SubtableStart = *PFieldList;
1343         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1344                     &Subtable, TRUE);
1345         if (ACPI_FAILURE (Status))
1346         {
1347             return (Status);
1348         }
1349 
1350         ParentTable = DtPeekSubtable ();
1351         DtInsertSubtable (ParentTable, Subtable);
1352         DtPushSubtable (Subtable);
1353 
1354         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1355 
1356         switch (MadtHeader->Type)
1357         {
1358         case ACPI_MADT_TYPE_LOCAL_APIC:
1359 
1360             InfoTable = AcpiDmTableInfoMadt0;
1361             break;
1362 
1363         case ACPI_MADT_TYPE_IO_APIC:
1364 
1365             InfoTable = AcpiDmTableInfoMadt1;
1366             break;
1367 
1368         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1369 
1370             InfoTable = AcpiDmTableInfoMadt2;
1371             break;
1372 
1373         case ACPI_MADT_TYPE_NMI_SOURCE:
1374 
1375             InfoTable = AcpiDmTableInfoMadt3;
1376             break;
1377 
1378         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1379 
1380             InfoTable = AcpiDmTableInfoMadt4;
1381             break;
1382 
1383         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1384 
1385             InfoTable = AcpiDmTableInfoMadt5;
1386             break;
1387 
1388         case ACPI_MADT_TYPE_IO_SAPIC:
1389 
1390             InfoTable = AcpiDmTableInfoMadt6;
1391             break;
1392 
1393         case ACPI_MADT_TYPE_LOCAL_SAPIC:
1394 
1395             InfoTable = AcpiDmTableInfoMadt7;
1396             break;
1397 
1398         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1399 
1400             InfoTable = AcpiDmTableInfoMadt8;
1401             break;
1402 
1403         case ACPI_MADT_TYPE_LOCAL_X2APIC:
1404 
1405             InfoTable = AcpiDmTableInfoMadt9;
1406             break;
1407 
1408         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1409 
1410             InfoTable = AcpiDmTableInfoMadt10;
1411             break;
1412 
1413         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1414 
1415             InfoTable = AcpiDmTableInfoMadt11;
1416             break;
1417 
1418         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1419 
1420             InfoTable = AcpiDmTableInfoMadt12;
1421             break;
1422 
1423         default:
1424 
1425             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1426             return (AE_ERROR);
1427         }
1428 
1429         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1430         if (ACPI_FAILURE (Status))
1431         {
1432             return (Status);
1433         }
1434 
1435         ParentTable = DtPeekSubtable ();
1436         DtInsertSubtable (ParentTable, Subtable);
1437         DtPopSubtable ();
1438     }
1439 
1440     return (AE_OK);
1441 }
1442 
1443 
1444 /******************************************************************************
1445  *
1446  * FUNCTION:    DtCompileMcfg
1447  *
1448  * PARAMETERS:  List                - Current field list pointer
1449  *
1450  * RETURN:      Status
1451  *
1452  * DESCRIPTION: Compile MCFG.
1453  *
1454  *****************************************************************************/
1455 
1456 ACPI_STATUS
1457 DtCompileMcfg (
1458     void                    **List)
1459 {
1460     ACPI_STATUS             Status;
1461 
1462 
1463     Status = DtCompileTwoSubtables (List,
1464                  AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1465     return (Status);
1466 }
1467 
1468 
1469 /******************************************************************************
1470  *
1471  * FUNCTION:    DtCompileMpst
1472  *
1473  * PARAMETERS:  List                - Current field list pointer
1474  *
1475  * RETURN:      Status
1476  *
1477  * DESCRIPTION: Compile MPST.
1478  *
1479  *****************************************************************************/
1480 
1481 ACPI_STATUS
1482 DtCompileMpst (
1483     void                    **List)
1484 {
1485     ACPI_STATUS             Status;
1486     DT_SUBTABLE             *Subtable;
1487     DT_SUBTABLE             *ParentTable;
1488     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1489     ACPI_MPST_CHANNEL       *MpstChannelInfo;
1490     ACPI_MPST_POWER_NODE    *MpstPowerNode;
1491     ACPI_MPST_DATA_HDR      *MpstDataHeader;
1492     UINT16                  SubtableCount;
1493     UINT32                  PowerStateCount;
1494     UINT32                  ComponentCount;
1495 
1496 
1497     /* Main table */
1498 
1499     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1500     if (ACPI_FAILURE (Status))
1501     {
1502         return (Status);
1503     }
1504 
1505     ParentTable = DtPeekSubtable ();
1506     DtInsertSubtable (ParentTable, Subtable);
1507     DtPushSubtable (Subtable);
1508 
1509     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1510     SubtableCount = MpstChannelInfo->PowerNodeCount;
1511 
1512     while (*PFieldList && SubtableCount)
1513     {
1514         /* Subtable: Memory Power Node(s) */
1515 
1516         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1517                     &Subtable, TRUE);
1518         if (ACPI_FAILURE (Status))
1519         {
1520             return (Status);
1521         }
1522 
1523         ParentTable = DtPeekSubtable ();
1524         DtInsertSubtable (ParentTable, Subtable);
1525         DtPushSubtable (Subtable);
1526 
1527         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1528         PowerStateCount = MpstPowerNode->NumPowerStates;
1529         ComponentCount = MpstPowerNode->NumPhysicalComponents;
1530 
1531         ParentTable = DtPeekSubtable ();
1532 
1533         /* Sub-subtables - Memory Power State Structure(s) */
1534 
1535         while (*PFieldList && PowerStateCount)
1536         {
1537             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1538                         &Subtable, TRUE);
1539             if (ACPI_FAILURE (Status))
1540             {
1541                 return (Status);
1542             }
1543 
1544             DtInsertSubtable (ParentTable, Subtable);
1545             PowerStateCount--;
1546         }
1547 
1548         /* Sub-subtables - Physical Component ID Structure(s) */
1549 
1550         while (*PFieldList && ComponentCount)
1551         {
1552             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1553                         &Subtable, TRUE);
1554             if (ACPI_FAILURE (Status))
1555             {
1556                 return (Status);
1557             }
1558 
1559             DtInsertSubtable (ParentTable, Subtable);
1560             ComponentCount--;
1561         }
1562 
1563         SubtableCount--;
1564         DtPopSubtable ();
1565     }
1566 
1567     /* Subtable: Count of Memory Power State Characteristic structures */
1568 
1569     DtPopSubtable ();
1570 
1571     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1572     if (ACPI_FAILURE (Status))
1573     {
1574         return (Status);
1575     }
1576 
1577     ParentTable = DtPeekSubtable ();
1578     DtInsertSubtable (ParentTable, Subtable);
1579     DtPushSubtable (Subtable);
1580 
1581     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1582     SubtableCount = MpstDataHeader->CharacteristicsCount;
1583 
1584     ParentTable = DtPeekSubtable ();
1585 
1586     /* Subtable: Memory Power State Characteristics structure(s) */
1587 
1588     while (*PFieldList && SubtableCount)
1589     {
1590         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1591                     &Subtable, TRUE);
1592         if (ACPI_FAILURE (Status))
1593         {
1594             return (Status);
1595         }
1596 
1597         DtInsertSubtable (ParentTable, Subtable);
1598         SubtableCount--;
1599     }
1600 
1601     DtPopSubtable ();
1602     return (AE_OK);
1603 }
1604 
1605 
1606 /******************************************************************************
1607  *
1608  * FUNCTION:    DtCompileMsct
1609  *
1610  * PARAMETERS:  List                - Current field list pointer
1611  *
1612  * RETURN:      Status
1613  *
1614  * DESCRIPTION: Compile MSCT.
1615  *
1616  *****************************************************************************/
1617 
1618 ACPI_STATUS
1619 DtCompileMsct (
1620     void                    **List)
1621 {
1622     ACPI_STATUS             Status;
1623 
1624 
1625     Status = DtCompileTwoSubtables (List,
1626                  AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1627     return (Status);
1628 }
1629 
1630 
1631 /******************************************************************************
1632  *
1633  * FUNCTION:    DtCompileMtmr
1634  *
1635  * PARAMETERS:  List                - Current field list pointer
1636  *
1637  * RETURN:      Status
1638  *
1639  * DESCRIPTION: Compile MTMR.
1640  *
1641  *****************************************************************************/
1642 
1643 ACPI_STATUS
1644 DtCompileMtmr (
1645     void                    **List)
1646 {
1647     ACPI_STATUS             Status;
1648 
1649 
1650     Status = DtCompileTwoSubtables (List,
1651                  AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
1652     return (Status);
1653 }
1654 
1655 
1656 /******************************************************************************
1657  *
1658  * FUNCTION:    DtCompilePcct
1659  *
1660  * PARAMETERS:  List                - Current field list pointer
1661  *
1662  * RETURN:      Status
1663  *
1664  * DESCRIPTION: Compile PCCT.
1665  *
1666  *****************************************************************************/
1667 
1668 ACPI_STATUS
1669 DtCompilePcct (
1670     void                    **List)
1671 {
1672     ACPI_STATUS             Status;
1673     DT_SUBTABLE             *Subtable;
1674     DT_SUBTABLE             *ParentTable;
1675     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1676     DT_FIELD                *SubtableStart;
1677     ACPI_SUBTABLE_HEADER    *PcctHeader;
1678     ACPI_DMTABLE_INFO       *InfoTable;
1679 
1680 
1681     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1682                 &Subtable, TRUE);
1683     if (ACPI_FAILURE (Status))
1684     {
1685         return (Status);
1686     }
1687 
1688     ParentTable = DtPeekSubtable ();
1689     DtInsertSubtable (ParentTable, Subtable);
1690 
1691     while (*PFieldList)
1692     {
1693         SubtableStart = *PFieldList;
1694         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1695                     &Subtable, TRUE);
1696         if (ACPI_FAILURE (Status))
1697         {
1698             return (Status);
1699         }
1700 
1701         ParentTable = DtPeekSubtable ();
1702         DtInsertSubtable (ParentTable, Subtable);
1703         DtPushSubtable (Subtable);
1704 
1705         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1706 
1707         switch (PcctHeader->Type)
1708         {
1709         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1710 
1711             InfoTable = AcpiDmTableInfoPcct0;
1712             break;
1713 
1714         default:
1715 
1716             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1717             return (AE_ERROR);
1718         }
1719 
1720         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1721         if (ACPI_FAILURE (Status))
1722         {
1723             return (Status);
1724         }
1725 
1726         ParentTable = DtPeekSubtable ();
1727         DtInsertSubtable (ParentTable, Subtable);
1728         DtPopSubtable ();
1729     }
1730 
1731     return (AE_OK);
1732 }
1733 
1734 
1735 /******************************************************************************
1736  *
1737  * FUNCTION:    DtCompilePmtt
1738  *
1739  * PARAMETERS:  List                - Current field list pointer
1740  *
1741  * RETURN:      Status
1742  *
1743  * DESCRIPTION: Compile PMTT.
1744  *
1745  *****************************************************************************/
1746 
1747 ACPI_STATUS
1748 DtCompilePmtt (
1749     void                    **List)
1750 {
1751     ACPI_STATUS             Status;
1752     DT_SUBTABLE             *Subtable;
1753     DT_SUBTABLE             *ParentTable;
1754     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1755     DT_FIELD                *SubtableStart;
1756     ACPI_PMTT_HEADER        *PmttHeader;
1757     ACPI_PMTT_CONTROLLER    *PmttController;
1758     UINT16                  DomainCount;
1759     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1760 
1761 
1762     /* Main table */
1763 
1764     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1765     if (ACPI_FAILURE (Status))
1766     {
1767         return (Status);
1768     }
1769 
1770     ParentTable = DtPeekSubtable ();
1771     DtInsertSubtable (ParentTable, Subtable);
1772     DtPushSubtable (Subtable);
1773 
1774     while (*PFieldList)
1775     {
1776         SubtableStart = *PFieldList;
1777         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
1778                     &Subtable, TRUE);
1779         if (ACPI_FAILURE (Status))
1780         {
1781             return (Status);
1782         }
1783 
1784         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
1785         while (PrevType >= PmttHeader->Type)
1786         {
1787             DtPopSubtable ();
1788 
1789             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
1790             {
1791                 break;
1792             }
1793             PrevType--;
1794         }
1795         PrevType = PmttHeader->Type;
1796 
1797         ParentTable = DtPeekSubtable ();
1798         DtInsertSubtable (ParentTable, Subtable);
1799         DtPushSubtable (Subtable);
1800 
1801         switch (PmttHeader->Type)
1802         {
1803         case ACPI_PMTT_TYPE_SOCKET:
1804 
1805             /* Subtable: Socket Structure */
1806 
1807             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1808                     &Subtable, TRUE);
1809             if (ACPI_FAILURE (Status))
1810             {
1811                 return (Status);
1812             }
1813 
1814             ParentTable = DtPeekSubtable ();
1815             DtInsertSubtable (ParentTable, Subtable);
1816             break;
1817 
1818         case ACPI_PMTT_TYPE_CONTROLLER:
1819 
1820             /* Subtable: Memory Controller Structure */
1821 
1822             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1823                     &Subtable, TRUE);
1824             if (ACPI_FAILURE (Status))
1825             {
1826                 return (Status);
1827             }
1828 
1829             ParentTable = DtPeekSubtable ();
1830             DtInsertSubtable (ParentTable, Subtable);
1831 
1832             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
1833                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
1834             DomainCount = PmttController->DomainCount;
1835 
1836             while (DomainCount)
1837             {
1838                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
1839                     &Subtable, TRUE);
1840                 if (ACPI_FAILURE (Status))
1841                 {
1842                     return (Status);
1843                 }
1844 
1845                 DtInsertSubtable (ParentTable, Subtable);
1846                 DomainCount--;
1847             }
1848             break;
1849 
1850         case ACPI_PMTT_TYPE_DIMM:
1851 
1852             /* Subtable: Physical Component Structure */
1853 
1854             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1855                     &Subtable, TRUE);
1856             if (ACPI_FAILURE (Status))
1857             {
1858                 return (Status);
1859             }
1860 
1861             ParentTable = DtPeekSubtable ();
1862             DtInsertSubtable (ParentTable, Subtable);
1863             break;
1864 
1865         default:
1866 
1867             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1868             return (AE_ERROR);
1869         }
1870     }
1871 
1872     return (Status);
1873 }
1874 
1875 
1876 /******************************************************************************
1877  *
1878  * FUNCTION:    DtCompileRsdt
1879  *
1880  * PARAMETERS:  List                - Current field list pointer
1881  *
1882  * RETURN:      Status
1883  *
1884  * DESCRIPTION: Compile RSDT.
1885  *
1886  *****************************************************************************/
1887 
1888 ACPI_STATUS
1889 DtCompileRsdt (
1890     void                    **List)
1891 {
1892     DT_SUBTABLE             *Subtable;
1893     DT_SUBTABLE             *ParentTable;
1894     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1895     UINT32                  Address;
1896 
1897 
1898     ParentTable = DtPeekSubtable ();
1899 
1900     while (FieldList)
1901     {
1902         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1903 
1904         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1905         DtInsertSubtable (ParentTable, Subtable);
1906         FieldList = FieldList->Next;
1907     }
1908 
1909     return (AE_OK);
1910 }
1911 
1912 
1913 /******************************************************************************
1914  *
1915  * FUNCTION:    DtCompileS3pt
1916  *
1917  * PARAMETERS:  PFieldList          - Current field list pointer
1918  *
1919  * RETURN:      Status
1920  *
1921  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1922  *
1923  *****************************************************************************/
1924 
1925 ACPI_STATUS
1926 DtCompileS3pt (
1927     DT_FIELD                **PFieldList)
1928 {
1929     ACPI_STATUS             Status;
1930     ACPI_S3PT_HEADER        *S3ptHeader;
1931     DT_SUBTABLE             *Subtable;
1932     DT_SUBTABLE             *ParentTable;
1933     ACPI_DMTABLE_INFO       *InfoTable;
1934     DT_FIELD                *SubtableStart;
1935 
1936 
1937     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1938                 &Gbl_RootTable, TRUE);
1939     if (ACPI_FAILURE (Status))
1940     {
1941         return (Status);
1942     }
1943 
1944     DtPushSubtable (Gbl_RootTable);
1945 
1946     while (*PFieldList)
1947     {
1948         SubtableStart = *PFieldList;
1949         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1950                     &Subtable, TRUE);
1951         if (ACPI_FAILURE (Status))
1952         {
1953             return (Status);
1954         }
1955 
1956         ParentTable = DtPeekSubtable ();
1957         DtInsertSubtable (ParentTable, Subtable);
1958         DtPushSubtable (Subtable);
1959 
1960         S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
1961 
1962         switch (S3ptHeader->Type)
1963         {
1964         case ACPI_S3PT_TYPE_RESUME:
1965 
1966             InfoTable = AcpiDmTableInfoS3pt0;
1967             break;
1968 
1969         case ACPI_S3PT_TYPE_SUSPEND:
1970 
1971             InfoTable = AcpiDmTableInfoS3pt1;
1972             break;
1973 
1974         default:
1975 
1976             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1977             return (AE_ERROR);
1978         }
1979 
1980         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1981         if (ACPI_FAILURE (Status))
1982         {
1983             return (Status);
1984         }
1985 
1986         ParentTable = DtPeekSubtable ();
1987         DtInsertSubtable (ParentTable, Subtable);
1988         DtPopSubtable ();
1989     }
1990 
1991     return (AE_OK);
1992 }
1993 
1994 
1995 /******************************************************************************
1996  *
1997  * FUNCTION:    DtCompileSlic
1998  *
1999  * PARAMETERS:  List                - Current field list pointer
2000  *
2001  * RETURN:      Status
2002  *
2003  * DESCRIPTION: Compile SLIC.
2004  *
2005  *****************************************************************************/
2006 
2007 ACPI_STATUS
2008 DtCompileSlic (
2009     void                    **List)
2010 {
2011     ACPI_STATUS             Status;
2012     DT_SUBTABLE             *Subtable;
2013     DT_SUBTABLE             *ParentTable;
2014     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2015     DT_FIELD                *SubtableStart;
2016     ACPI_SLIC_HEADER        *SlicHeader;
2017     ACPI_DMTABLE_INFO       *InfoTable;
2018 
2019 
2020     while (*PFieldList)
2021     {
2022         SubtableStart = *PFieldList;
2023         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
2024                     &Subtable, TRUE);
2025         if (ACPI_FAILURE (Status))
2026         {
2027             return (Status);
2028         }
2029 
2030         ParentTable = DtPeekSubtable ();
2031         DtInsertSubtable (ParentTable, Subtable);
2032         DtPushSubtable (Subtable);
2033 
2034         SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
2035 
2036         switch (SlicHeader->Type)
2037         {
2038         case ACPI_SLIC_TYPE_PUBLIC_KEY:
2039 
2040             InfoTable = AcpiDmTableInfoSlic0;
2041             break;
2042 
2043         case ACPI_SLIC_TYPE_WINDOWS_MARKER:
2044 
2045             InfoTable = AcpiDmTableInfoSlic1;
2046             break;
2047 
2048         default:
2049 
2050             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
2051             return (AE_ERROR);
2052         }
2053 
2054         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2055         if (ACPI_FAILURE (Status))
2056         {
2057             return (Status);
2058         }
2059 
2060         ParentTable = DtPeekSubtable ();
2061         DtInsertSubtable (ParentTable, Subtable);
2062         DtPopSubtable ();
2063     }
2064 
2065     return (AE_OK);
2066 }
2067 
2068 
2069 /******************************************************************************
2070  *
2071  * FUNCTION:    DtCompileSlit
2072  *
2073  * PARAMETERS:  List                - Current field list pointer
2074  *
2075  * RETURN:      Status
2076  *
2077  * DESCRIPTION: Compile SLIT.
2078  *
2079  *****************************************************************************/
2080 
2081 ACPI_STATUS
2082 DtCompileSlit (
2083     void                    **List)
2084 {
2085     ACPI_STATUS             Status;
2086     DT_SUBTABLE             *Subtable;
2087     DT_SUBTABLE             *ParentTable;
2088     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2089     DT_FIELD                *FieldList;
2090     UINT32                  Localities;
2091     UINT8                   *LocalityBuffer;
2092 
2093 
2094     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2095                 &Subtable, TRUE);
2096     if (ACPI_FAILURE (Status))
2097     {
2098         return (Status);
2099     }
2100 
2101     ParentTable = DtPeekSubtable ();
2102     DtInsertSubtable (ParentTable, Subtable);
2103 
2104     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2105     LocalityBuffer = UtLocalCalloc (Localities);
2106 
2107     /* Compile each locality buffer */
2108 
2109     FieldList = *PFieldList;
2110     while (FieldList)
2111     {
2112         DtCompileBuffer (LocalityBuffer,
2113             FieldList->Value, FieldList, Localities);
2114 
2115         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2116         DtInsertSubtable (ParentTable, Subtable);
2117         FieldList = FieldList->Next;
2118     }
2119 
2120     ACPI_FREE (LocalityBuffer);
2121     return (AE_OK);
2122 }
2123 
2124 
2125 /******************************************************************************
2126  *
2127  * FUNCTION:    DtCompileSrat
2128  *
2129  * PARAMETERS:  List                - Current field list pointer
2130  *
2131  * RETURN:      Status
2132  *
2133  * DESCRIPTION: Compile SRAT.
2134  *
2135  *****************************************************************************/
2136 
2137 ACPI_STATUS
2138 DtCompileSrat (
2139     void                    **List)
2140 {
2141     ACPI_STATUS             Status;
2142     DT_SUBTABLE             *Subtable;
2143     DT_SUBTABLE             *ParentTable;
2144     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2145     DT_FIELD                *SubtableStart;
2146     ACPI_SUBTABLE_HEADER    *SratHeader;
2147     ACPI_DMTABLE_INFO       *InfoTable;
2148 
2149 
2150     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2151                 &Subtable, TRUE);
2152     if (ACPI_FAILURE (Status))
2153     {
2154         return (Status);
2155     }
2156 
2157     ParentTable = DtPeekSubtable ();
2158     DtInsertSubtable (ParentTable, Subtable);
2159 
2160     while (*PFieldList)
2161     {
2162         SubtableStart = *PFieldList;
2163         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2164                     &Subtable, TRUE);
2165         if (ACPI_FAILURE (Status))
2166         {
2167             return (Status);
2168         }
2169 
2170         ParentTable = DtPeekSubtable ();
2171         DtInsertSubtable (ParentTable, Subtable);
2172         DtPushSubtable (Subtable);
2173 
2174         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2175 
2176         switch (SratHeader->Type)
2177         {
2178         case ACPI_SRAT_TYPE_CPU_AFFINITY:
2179 
2180             InfoTable = AcpiDmTableInfoSrat0;
2181             break;
2182 
2183         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2184 
2185             InfoTable = AcpiDmTableInfoSrat1;
2186             break;
2187 
2188         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2189 
2190             InfoTable = AcpiDmTableInfoSrat2;
2191             break;
2192 
2193         default:
2194 
2195             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2196             return (AE_ERROR);
2197         }
2198 
2199         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2200         if (ACPI_FAILURE (Status))
2201         {
2202             return (Status);
2203         }
2204 
2205         ParentTable = DtPeekSubtable ();
2206         DtInsertSubtable (ParentTable, Subtable);
2207         DtPopSubtable ();
2208     }
2209 
2210     return (AE_OK);
2211 }
2212 
2213 
2214 /******************************************************************************
2215  *
2216  * FUNCTION:    DtGetGenericTableInfo
2217  *
2218  * PARAMETERS:  Name                - Generic type name
2219  *
2220  * RETURN:      Info entry
2221  *
2222  * DESCRIPTION: Obtain table info for a generic name entry
2223  *
2224  *****************************************************************************/
2225 
2226 ACPI_DMTABLE_INFO *
2227 DtGetGenericTableInfo (
2228     char                    *Name)
2229 {
2230     ACPI_DMTABLE_INFO       *Info;
2231     UINT32                  i;
2232 
2233 
2234     if (!Name)
2235     {
2236         return (NULL);
2237     }
2238 
2239     /* Search info table for name match */
2240 
2241     for (i = 0; ; i++)
2242     {
2243         Info = AcpiDmTableInfoGeneric[i];
2244         if (Info->Opcode == ACPI_DMT_EXIT)
2245         {
2246             Info = NULL;
2247             break;
2248         }
2249 
2250         /* Use caseless compare for generic keywords */
2251 
2252         if (!AcpiUtStricmp (Name, Info->Name))
2253         {
2254             break;
2255         }
2256     }
2257 
2258     return (Info);
2259 }
2260 
2261 
2262 /******************************************************************************
2263  *
2264  * FUNCTION:    DtCompileUefi
2265  *
2266  * PARAMETERS:  List                - Current field list pointer
2267  *
2268  * RETURN:      Status
2269  *
2270  * DESCRIPTION: Compile UEFI.
2271  *
2272  *****************************************************************************/
2273 
2274 ACPI_STATUS
2275 DtCompileUefi (
2276     void                    **List)
2277 {
2278     ACPI_STATUS             Status;
2279     DT_SUBTABLE             *Subtable;
2280     DT_SUBTABLE             *ParentTable;
2281     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2282     UINT16                  *DataOffset;
2283 
2284 
2285     /* Compile the predefined portion of the UEFI table */
2286 
2287     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2288                 &Subtable, TRUE);
2289     if (ACPI_FAILURE (Status))
2290     {
2291         return (Status);
2292     }
2293 
2294     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2295     *DataOffset = sizeof (ACPI_TABLE_UEFI);
2296 
2297     ParentTable = DtPeekSubtable ();
2298     DtInsertSubtable (ParentTable, Subtable);
2299 
2300     /*
2301      * Compile the "generic" portion of the UEFI table. This
2302      * part of the table is not predefined and any of the generic
2303      * operators may be used.
2304      */
2305 
2306     DtCompileGeneric ((void **) PFieldList);
2307 
2308     return (AE_OK);
2309 }
2310 
2311 
2312 /******************************************************************************
2313  *
2314  * FUNCTION:    DtCompileVrtc
2315  *
2316  * PARAMETERS:  List                - Current field list pointer
2317  *
2318  * RETURN:      Status
2319  *
2320  * DESCRIPTION: Compile VRTC.
2321  *
2322  *****************************************************************************/
2323 
2324 ACPI_STATUS
2325 DtCompileVrtc (
2326     void                    **List)
2327 {
2328     ACPI_STATUS             Status;
2329 
2330 
2331     Status = DtCompileTwoSubtables (List,
2332                  AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2333     return (Status);
2334 }
2335 
2336 
2337 /******************************************************************************
2338  *
2339  * FUNCTION:    DtCompileWdat
2340  *
2341  * PARAMETERS:  List                - Current field list pointer
2342  *
2343  * RETURN:      Status
2344  *
2345  * DESCRIPTION: Compile WDAT.
2346  *
2347  *****************************************************************************/
2348 
2349 ACPI_STATUS
2350 DtCompileWdat (
2351     void                    **List)
2352 {
2353     ACPI_STATUS             Status;
2354 
2355 
2356     Status = DtCompileTwoSubtables (List,
2357                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2358     return (Status);
2359 }
2360 
2361 
2362 /******************************************************************************
2363  *
2364  * FUNCTION:    DtCompileXsdt
2365  *
2366  * PARAMETERS:  List                - Current field list pointer
2367  *
2368  * RETURN:      Status
2369  *
2370  * DESCRIPTION: Compile XSDT.
2371  *
2372  *****************************************************************************/
2373 
2374 ACPI_STATUS
2375 DtCompileXsdt (
2376     void                    **List)
2377 {
2378     DT_SUBTABLE             *Subtable;
2379     DT_SUBTABLE             *ParentTable;
2380     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2381     UINT64                  Address;
2382 
2383     ParentTable = DtPeekSubtable ();
2384 
2385     while (FieldList)
2386     {
2387         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2388 
2389         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2390         DtInsertSubtable (ParentTable, Subtable);
2391         FieldList = FieldList->Next;
2392     }
2393 
2394     return (AE_OK);
2395 }
2396 
2397 
2398 /******************************************************************************
2399  *
2400  * FUNCTION:    DtCompileGeneric
2401  *
2402  * PARAMETERS:  List                - Current field list pointer
2403  *
2404  * RETURN:      Status
2405  *
2406  * DESCRIPTION: Compile generic unknown table.
2407  *
2408  *****************************************************************************/
2409 
2410 ACPI_STATUS
2411 DtCompileGeneric (
2412     void                    **List)
2413 {
2414     ACPI_STATUS             Status;
2415     DT_SUBTABLE             *Subtable;
2416     DT_SUBTABLE             *ParentTable;
2417     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2418     ACPI_DMTABLE_INFO       *Info;
2419 
2420 
2421     ParentTable = DtPeekSubtable ();
2422 
2423     /*
2424      * Compile the "generic" portion of the table. This
2425      * part of the table is not predefined and any of the generic
2426      * operators may be used.
2427      */
2428 
2429     /* Find any and all labels in the entire generic portion */
2430 
2431     DtDetectAllLabels (*PFieldList);
2432 
2433     /* Now we can actually compile the parse tree */
2434 
2435     while (*PFieldList)
2436     {
2437         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2438         if (!Info)
2439         {
2440             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2441                 (*PFieldList)->Name);
2442             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2443                 (*PFieldList), MsgBuffer);
2444 
2445             *PFieldList = (*PFieldList)->Next;
2446             continue;
2447         }
2448 
2449         Status = DtCompileTable (PFieldList, Info,
2450                     &Subtable, TRUE);
2451         if (ACPI_SUCCESS (Status))
2452         {
2453             DtInsertSubtable (ParentTable, Subtable);
2454         }
2455         else
2456         {
2457             *PFieldList = (*PFieldList)->Next;
2458 
2459             if (Status == AE_NOT_FOUND)
2460             {
2461                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2462                     (*PFieldList)->Name);
2463                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2464                     (*PFieldList), MsgBuffer);
2465             }
2466         }
2467     }
2468 
2469     return (AE_OK);
2470 }