dttable.c revision 219707
1/****************************************************************************** 2 * 3 * Module Name: dttable.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2011, 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 <contrib/dev/acpica/compiler/aslcompiler.h> 49#include <contrib/dev/acpica/compiler/dtcompiler.h> 50 51#define _COMPONENT DT_COMPILER 52 ACPI_MODULE_NAME ("dttable") 53 54 55/* TBD: merge these into dmtbinfo.c? */ 56 57static ACPI_DMTABLE_INFO TableInfoAsfAddress[] = 58{ 59 {ACPI_DMT_BUFFER, 0, "Addresses", 0}, 60 {ACPI_DMT_EXIT, 0, NULL, 0} 61}; 62 63static 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 78static ACPI_STATUS 79DtCompileTwoSubtables ( 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 100static ACPI_STATUS 101DtCompileTwoSubtables ( 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 148ACPI_STATUS 149DtCompileFacs ( 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 190ACPI_STATUS 191DtCompileRsdp ( 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 248ACPI_STATUS 249DtCompileAsf ( 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 InfoTable = AcpiDmTableInfoAsf0; 284 break; 285 286 case ACPI_ASF_TYPE_ALERT: 287 InfoTable = AcpiDmTableInfoAsf1; 288 break; 289 290 case ACPI_ASF_TYPE_CONTROL: 291 InfoTable = AcpiDmTableInfoAsf2; 292 break; 293 294 case ACPI_ASF_TYPE_BOOT: 295 InfoTable = AcpiDmTableInfoAsf3; 296 break; 297 298 case ACPI_ASF_TYPE_ADDRESS: 299 InfoTable = AcpiDmTableInfoAsf4; 300 break; 301 302 default: 303 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 304 return (AE_ERROR); 305 } 306 307 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 308 if (ACPI_FAILURE (Status)) 309 { 310 return (Status); 311 } 312 313 ParentTable = DtPeekSubtable (); 314 DtInsertSubtable (ParentTable, Subtable); 315 316 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 317 { 318 case ACPI_ASF_TYPE_INFO: 319 DataInfoTable = NULL; 320 break; 321 322 case ACPI_ASF_TYPE_ALERT: 323 DataInfoTable = AcpiDmTableInfoAsf1a; 324 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 325 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 326 sizeof (ACPI_ASF_HEADER)))->Alerts; 327 break; 328 329 case ACPI_ASF_TYPE_CONTROL: 330 DataInfoTable = AcpiDmTableInfoAsf2a; 331 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 332 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 333 sizeof (ACPI_ASF_HEADER)))->Controls; 334 break; 335 336 case ACPI_ASF_TYPE_BOOT: 337 DataInfoTable = NULL; 338 break; 339 340 case ACPI_ASF_TYPE_ADDRESS: 341 DataInfoTable = TableInfoAsfAddress; 342 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 343 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 344 sizeof (ACPI_ASF_HEADER)))->Devices; 345 break; 346 347 default: 348 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 349 return (AE_ERROR); 350 } 351 352 if (DataInfoTable) 353 { 354 switch (AsfTable->Header.Type & 0x7F) 355 { 356 case ACPI_ASF_TYPE_ADDRESS: 357 358 while (DataCount > 0) 359 { 360 Status = DtCompileTable (PFieldList, DataInfoTable, 361 &Subtable, TRUE); 362 if (ACPI_FAILURE (Status)) 363 { 364 return (Status); 365 } 366 367 DtInsertSubtable (ParentTable, Subtable); 368 DataCount = DataCount - Subtable->Length; 369 } 370 break; 371 372 default: 373 374 for (i = 0; i < DataCount; i++) 375 { 376 Status = DtCompileTable (PFieldList, DataInfoTable, 377 &Subtable, TRUE); 378 if (ACPI_FAILURE (Status)) 379 { 380 return (Status); 381 } 382 383 DtInsertSubtable (ParentTable, Subtable); 384 } 385 break; 386 } 387 } 388 389 DtPopSubtable (); 390 } 391 392 return (AE_OK); 393} 394 395 396/****************************************************************************** 397 * 398 * FUNCTION: DtCompileCpep 399 * 400 * PARAMETERS: List - Current field list pointer 401 * 402 * RETURN: Status 403 * 404 * DESCRIPTION: Compile CPEP. 405 * 406 *****************************************************************************/ 407 408ACPI_STATUS 409DtCompileCpep ( 410 void **List) 411{ 412 ACPI_STATUS Status; 413 414 415 Status = DtCompileTwoSubtables (List, 416 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 417 return (Status); 418} 419 420 421/****************************************************************************** 422 * 423 * FUNCTION: DtCompileDmar 424 * 425 * PARAMETERS: List - Current field list pointer 426 * 427 * RETURN: Status 428 * 429 * DESCRIPTION: Compile DMAR. 430 * 431 *****************************************************************************/ 432 433ACPI_STATUS 434DtCompileDmar ( 435 void **List) 436{ 437 ACPI_STATUS Status; 438 DT_SUBTABLE *Subtable; 439 DT_SUBTABLE *ParentTable; 440 DT_FIELD **PFieldList = (DT_FIELD **) List; 441 DT_FIELD *SubtableStart; 442 ACPI_DMTABLE_INFO *InfoTable; 443 ACPI_DMAR_HEADER *DmarHeader; 444 UINT8 *ReservedBuffer; 445 UINT32 ReservedSize; 446 447 448 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE); 449 if (ACPI_FAILURE (Status)) 450 { 451 return (Status); 452 } 453 454 ParentTable = DtPeekSubtable (); 455 DtInsertSubtable (ParentTable, Subtable); 456 457 /* DMAR Reserved area */ 458 459 ReservedSize = (UINT32) sizeof (((ACPI_TABLE_DMAR *) NULL)->Reserved); 460 ReservedBuffer = UtLocalCalloc (ReservedSize); 461 462 DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable); 463 464 ACPI_FREE (ReservedBuffer); 465 ParentTable = DtPeekSubtable (); 466 DtInsertSubtable (ParentTable, Subtable); 467 468 while (*PFieldList) 469 { 470 /* DMAR Header */ 471 472 SubtableStart = *PFieldList; 473 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 474 &Subtable, TRUE); 475 if (ACPI_FAILURE (Status)) 476 { 477 return (Status); 478 } 479 480 ParentTable = DtPeekSubtable (); 481 DtInsertSubtable (ParentTable, Subtable); 482 DtPushSubtable (Subtable); 483 484 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 485 486 switch (DmarHeader->Type) 487 { 488 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 489 InfoTable = AcpiDmTableInfoDmar0; 490 break; 491 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 492 InfoTable = AcpiDmTableInfoDmar1; 493 break; 494 case ACPI_DMAR_TYPE_ATSR: 495 InfoTable = AcpiDmTableInfoDmar2; 496 break; 497 case ACPI_DMAR_HARDWARE_AFFINITY: 498 InfoTable = AcpiDmTableInfoDmar3; 499 break; 500 default: 501 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 502 return (AE_ERROR); 503 } 504 505 /* DMAR Subtable */ 506 507 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 508 if (ACPI_FAILURE (Status)) 509 { 510 return (Status); 511 } 512 513 ParentTable = DtPeekSubtable (); 514 DtInsertSubtable (ParentTable, Subtable); 515 516 /* Optional Device Scope subtables */ 517 518 while (*PFieldList) 519 { 520 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 521 &Subtable, FALSE); 522 if (Status == AE_NOT_FOUND) 523 { 524 break; 525 } 526 527 ParentTable = DtPeekSubtable (); 528 DtInsertSubtable (ParentTable, Subtable); 529 DtPushSubtable (Subtable); 530 531 /* Optional PCI Paths */ 532 533 while (*PFieldList) 534 { 535 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 536 &Subtable, FALSE); 537 if (Status == AE_NOT_FOUND) 538 { 539 DtPopSubtable (); 540 break; 541 } 542 543 ParentTable = DtPeekSubtable (); 544 DtInsertSubtable (ParentTable, Subtable); 545 } 546 } 547 548 DtPopSubtable (); 549 } 550 551 return (AE_OK); 552} 553 554 555/****************************************************************************** 556 * 557 * FUNCTION: DtCompileEinj 558 * 559 * PARAMETERS: List - Current field list pointer 560 * 561 * RETURN: Status 562 * 563 * DESCRIPTION: Compile EINJ. 564 * 565 *****************************************************************************/ 566 567ACPI_STATUS 568DtCompileEinj ( 569 void **List) 570{ 571 ACPI_STATUS Status; 572 573 574 Status = DtCompileTwoSubtables (List, 575 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 576 return (Status); 577} 578 579 580/****************************************************************************** 581 * 582 * FUNCTION: DtCompileErst 583 * 584 * PARAMETERS: List - Current field list pointer 585 * 586 * RETURN: Status 587 * 588 * DESCRIPTION: Compile ERST. 589 * 590 *****************************************************************************/ 591 592ACPI_STATUS 593DtCompileErst ( 594 void **List) 595{ 596 ACPI_STATUS Status; 597 598 599 Status = DtCompileTwoSubtables (List, 600 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 601 return (Status); 602} 603 604 605/****************************************************************************** 606 * 607 * FUNCTION: DtCompileFadt 608 * 609 * PARAMETERS: List - Current field list pointer 610 * 611 * RETURN: Status 612 * 613 * DESCRIPTION: Compile FADT. 614 * 615 *****************************************************************************/ 616 617ACPI_STATUS 618DtCompileFadt ( 619 void **List) 620{ 621 ACPI_STATUS Status; 622 DT_SUBTABLE *Subtable; 623 DT_SUBTABLE *ParentTable; 624 DT_FIELD **PFieldList = (DT_FIELD **) List; 625 ACPI_TABLE_HEADER *Table; 626 UINT8 Revision; 627 628 629 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1, 630 &Subtable, TRUE); 631 if (ACPI_FAILURE (Status)) 632 { 633 return (Status); 634 } 635 636 ParentTable = DtPeekSubtable (); 637 DtInsertSubtable (ParentTable, Subtable); 638 639 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 640 Revision = Table->Revision; 641 642 if (Revision == 2) 643 { 644 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2, 645 &Subtable, TRUE); 646 if (ACPI_FAILURE (Status)) 647 { 648 return (Status); 649 } 650 651 DtInsertSubtable (ParentTable, Subtable); 652 } 653 else if (Revision >= 2) 654 { 655 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3, 656 &Subtable, TRUE); 657 if (ACPI_FAILURE (Status)) 658 { 659 return (Status); 660 } 661 662 DtInsertSubtable (ParentTable, Subtable); 663 } 664 665 return (AE_OK); 666} 667 668 669/****************************************************************************** 670 * 671 * FUNCTION: DtCompileHest 672 * 673 * PARAMETERS: List - Current field list pointer 674 * 675 * RETURN: Status 676 * 677 * DESCRIPTION: Compile HEST. 678 * 679 *****************************************************************************/ 680 681ACPI_STATUS 682DtCompileHest ( 683 void **List) 684{ 685 ACPI_STATUS Status; 686 DT_SUBTABLE *Subtable; 687 DT_SUBTABLE *ParentTable; 688 DT_FIELD **PFieldList = (DT_FIELD **) List; 689 DT_FIELD *SubtableStart; 690 ACPI_DMTABLE_INFO *InfoTable; 691 UINT16 Type; 692 UINT32 BankCount; 693 694 695 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 696 &Subtable, TRUE); 697 if (ACPI_FAILURE (Status)) 698 { 699 return (Status); 700 } 701 702 ParentTable = DtPeekSubtable (); 703 DtInsertSubtable (ParentTable, Subtable); 704 705 while (*PFieldList) 706 { 707 /* Get subtable type */ 708 709 SubtableStart = *PFieldList; 710 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 711 712 switch (Type) 713 { 714 case ACPI_HEST_TYPE_IA32_CHECK: 715 InfoTable = AcpiDmTableInfoHest0; 716 break; 717 718 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 719 InfoTable = AcpiDmTableInfoHest1; 720 break; 721 722 case ACPI_HEST_TYPE_IA32_NMI: 723 InfoTable = AcpiDmTableInfoHest2; 724 break; 725 726 case ACPI_HEST_TYPE_AER_ROOT_PORT: 727 InfoTable = AcpiDmTableInfoHest6; 728 break; 729 730 case ACPI_HEST_TYPE_AER_ENDPOINT: 731 InfoTable = AcpiDmTableInfoHest7; 732 break; 733 734 case ACPI_HEST_TYPE_AER_BRIDGE: 735 InfoTable = AcpiDmTableInfoHest8; 736 break; 737 738 case ACPI_HEST_TYPE_GENERIC_ERROR: 739 InfoTable = AcpiDmTableInfoHest9; 740 break; 741 742 default: 743 /* Cannot continue on unknown type */ 744 745 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 746 return (AE_ERROR); 747 } 748 749 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 750 if (ACPI_FAILURE (Status)) 751 { 752 return (Status); 753 } 754 755 DtInsertSubtable (ParentTable, Subtable); 756 757 /* 758 * Additional subtable data - IA32 Error Bank(s) 759 */ 760 BankCount = 0; 761 switch (Type) 762 { 763 case ACPI_HEST_TYPE_IA32_CHECK: 764 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 765 Subtable->Buffer))->NumHardwareBanks; 766 break; 767 768 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 769 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 770 Subtable->Buffer))->NumHardwareBanks; 771 break; 772 773 default: 774 break; 775 } 776 777 while (BankCount) 778 { 779 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 780 &Subtable, TRUE); 781 if (ACPI_FAILURE (Status)) 782 { 783 return (Status); 784 } 785 786 DtInsertSubtable (ParentTable, Subtable); 787 BankCount--; 788 } 789 } 790 791 return AE_OK; 792} 793 794 795/****************************************************************************** 796 * 797 * FUNCTION: DtCompileIvrs 798 * 799 * PARAMETERS: List - Current field list pointer 800 * 801 * RETURN: Status 802 * 803 * DESCRIPTION: Compile IVRS. 804 * 805 *****************************************************************************/ 806 807ACPI_STATUS 808DtCompileIvrs ( 809 void **List) 810{ 811 ACPI_STATUS Status; 812 DT_SUBTABLE *Subtable; 813 DT_SUBTABLE *ParentTable; 814 DT_FIELD **PFieldList = (DT_FIELD **) List; 815 DT_FIELD *SubtableStart; 816 ACPI_DMTABLE_INFO *InfoTable; 817 ACPI_IVRS_HEADER *IvrsHeader; 818 UINT8 EntryType; 819 820 821 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 822 &Subtable, TRUE); 823 if (ACPI_FAILURE (Status)) 824 { 825 return (Status); 826 } 827 828 ParentTable = DtPeekSubtable (); 829 DtInsertSubtable (ParentTable, Subtable); 830 831 while (*PFieldList) 832 { 833 SubtableStart = *PFieldList; 834 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr, 835 &Subtable, TRUE); 836 if (ACPI_FAILURE (Status)) 837 { 838 return (Status); 839 } 840 841 ParentTable = DtPeekSubtable (); 842 DtInsertSubtable (ParentTable, Subtable); 843 DtPushSubtable (Subtable); 844 845 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer); 846 847 switch (IvrsHeader->Type) 848 { 849 case ACPI_IVRS_TYPE_HARDWARE: 850 InfoTable = AcpiDmTableInfoIvrs0; 851 break; 852 853 case ACPI_IVRS_TYPE_MEMORY1: 854 case ACPI_IVRS_TYPE_MEMORY2: 855 case ACPI_IVRS_TYPE_MEMORY3: 856 InfoTable = AcpiDmTableInfoIvrs1; 857 break; 858 859 default: 860 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS"); 861 return (AE_ERROR); 862 } 863 864 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 865 if (ACPI_FAILURE (Status)) 866 { 867 return (Status); 868 } 869 870 ParentTable = DtPeekSubtable (); 871 DtInsertSubtable (ParentTable, Subtable); 872 873 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE) 874 { 875 while (*PFieldList && 876 !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type")) 877 { 878 SubtableStart = *PFieldList; 879 DtCompileInteger (&EntryType, *PFieldList, 1, 0); 880 881 switch (EntryType) 882 { 883 /* 4-byte device entries */ 884 885 case ACPI_IVRS_TYPE_PAD4: 886 case ACPI_IVRS_TYPE_ALL: 887 case ACPI_IVRS_TYPE_SELECT: 888 case ACPI_IVRS_TYPE_START: 889 case ACPI_IVRS_TYPE_END: 890 891 InfoTable = AcpiDmTableInfoIvrs4; 892 break; 893 894 /* 8-byte entries, type A */ 895 896 case ACPI_IVRS_TYPE_ALIAS_SELECT: 897 case ACPI_IVRS_TYPE_ALIAS_START: 898 899 InfoTable = AcpiDmTableInfoIvrs8a; 900 break; 901 902 /* 8-byte entries, type B */ 903 904 case ACPI_IVRS_TYPE_PAD8: 905 case ACPI_IVRS_TYPE_EXT_SELECT: 906 case ACPI_IVRS_TYPE_EXT_START: 907 908 InfoTable = AcpiDmTableInfoIvrs8b; 909 break; 910 911 /* 8-byte entries, type C */ 912 913 case ACPI_IVRS_TYPE_SPECIAL: 914 915 InfoTable = AcpiDmTableInfoIvrs8c; 916 break; 917 918 default: 919 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 920 "IVRS Device Entry"); 921 return (AE_ERROR); 922 } 923 924 Status = DtCompileTable (PFieldList, InfoTable, 925 &Subtable, TRUE); 926 if (ACPI_FAILURE (Status)) 927 { 928 return (Status); 929 } 930 931 DtInsertSubtable (ParentTable, Subtable); 932 } 933 } 934 935 DtPopSubtable (); 936 } 937 938 return (AE_OK); 939} 940 941 942/****************************************************************************** 943 * 944 * FUNCTION: DtCompileMadt 945 * 946 * PARAMETERS: List - Current field list pointer 947 * 948 * RETURN: Status 949 * 950 * DESCRIPTION: Compile MADT. 951 * 952 *****************************************************************************/ 953 954ACPI_STATUS 955DtCompileMadt ( 956 void **List) 957{ 958 ACPI_STATUS Status; 959 DT_SUBTABLE *Subtable; 960 DT_SUBTABLE *ParentTable; 961 DT_FIELD **PFieldList = (DT_FIELD **) List; 962 DT_FIELD *SubtableStart; 963 ACPI_SUBTABLE_HEADER *MadtHeader; 964 ACPI_DMTABLE_INFO *InfoTable; 965 966 967 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, 968 &Subtable, TRUE); 969 if (ACPI_FAILURE (Status)) 970 { 971 return (Status); 972 } 973 974 ParentTable = DtPeekSubtable (); 975 DtInsertSubtable (ParentTable, Subtable); 976 977 while (*PFieldList) 978 { 979 SubtableStart = *PFieldList; 980 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, 981 &Subtable, TRUE); 982 if (ACPI_FAILURE (Status)) 983 { 984 return (Status); 985 } 986 987 ParentTable = DtPeekSubtable (); 988 DtInsertSubtable (ParentTable, Subtable); 989 DtPushSubtable (Subtable); 990 991 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 992 993 switch (MadtHeader->Type) 994 { 995 case ACPI_MADT_TYPE_LOCAL_APIC: 996 InfoTable = AcpiDmTableInfoMadt0; 997 break; 998 case ACPI_MADT_TYPE_IO_APIC: 999 InfoTable = AcpiDmTableInfoMadt1; 1000 break; 1001 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 1002 InfoTable = AcpiDmTableInfoMadt2; 1003 break; 1004 case ACPI_MADT_TYPE_NMI_SOURCE: 1005 InfoTable = AcpiDmTableInfoMadt3; 1006 break; 1007 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 1008 InfoTable = AcpiDmTableInfoMadt4; 1009 break; 1010 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 1011 InfoTable = AcpiDmTableInfoMadt5; 1012 break; 1013 case ACPI_MADT_TYPE_IO_SAPIC: 1014 InfoTable = AcpiDmTableInfoMadt6; 1015 break; 1016 case ACPI_MADT_TYPE_LOCAL_SAPIC: 1017 InfoTable = AcpiDmTableInfoMadt7; 1018 break; 1019 case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 1020 InfoTable = AcpiDmTableInfoMadt8; 1021 break; 1022 case ACPI_MADT_TYPE_LOCAL_X2APIC: 1023 InfoTable = AcpiDmTableInfoMadt9; 1024 break; 1025 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 1026 InfoTable = AcpiDmTableInfoMadt10; 1027 break; 1028 default: 1029 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 1030 return (AE_ERROR); 1031 } 1032 1033 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1034 if (ACPI_FAILURE (Status)) 1035 { 1036 return (Status); 1037 } 1038 1039 ParentTable = DtPeekSubtable (); 1040 DtInsertSubtable (ParentTable, Subtable); 1041 DtPopSubtable (); 1042 } 1043 1044 return (AE_OK); 1045} 1046 1047 1048/****************************************************************************** 1049 * 1050 * FUNCTION: DtCompileMcfg 1051 * 1052 * PARAMETERS: List - Current field list pointer 1053 * 1054 * RETURN: Status 1055 * 1056 * DESCRIPTION: Compile MCFG. 1057 * 1058 *****************************************************************************/ 1059 1060ACPI_STATUS 1061DtCompileMcfg ( 1062 void **List) 1063{ 1064 ACPI_STATUS Status; 1065 1066 1067 Status = DtCompileTwoSubtables (List, 1068 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 1069 return (Status); 1070} 1071 1072 1073/****************************************************************************** 1074 * 1075 * FUNCTION: DtCompileMsct 1076 * 1077 * PARAMETERS: List - Current field list pointer 1078 * 1079 * RETURN: Status 1080 * 1081 * DESCRIPTION: Compile MSCT. 1082 * 1083 *****************************************************************************/ 1084 1085ACPI_STATUS 1086DtCompileMsct ( 1087 void **List) 1088{ 1089 ACPI_STATUS Status; 1090 1091 1092 Status = DtCompileTwoSubtables (List, 1093 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 1094 return (Status); 1095} 1096 1097 1098/****************************************************************************** 1099 * 1100 * FUNCTION: DtCompileRsdt 1101 * 1102 * PARAMETERS: List - Current field list pointer 1103 * 1104 * RETURN: Status 1105 * 1106 * DESCRIPTION: Compile RSDT. 1107 * 1108 *****************************************************************************/ 1109 1110ACPI_STATUS 1111DtCompileRsdt ( 1112 void **List) 1113{ 1114 DT_SUBTABLE *Subtable; 1115 DT_SUBTABLE *ParentTable; 1116 DT_FIELD *FieldList = *(DT_FIELD **) List; 1117 UINT32 Address; 1118 1119 1120 ParentTable = DtPeekSubtable (); 1121 1122 while (FieldList) 1123 { 1124 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 1125 1126 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 1127 DtInsertSubtable (ParentTable, Subtable); 1128 FieldList = FieldList->Next; 1129 } 1130 1131 return (AE_OK); 1132} 1133 1134 1135/****************************************************************************** 1136 * 1137 * FUNCTION: DtCompileSlic 1138 * 1139 * PARAMETERS: List - Current field list pointer 1140 * 1141 * RETURN: Status 1142 * 1143 * DESCRIPTION: Compile SLIC. 1144 * 1145 *****************************************************************************/ 1146 1147ACPI_STATUS 1148DtCompileSlic ( 1149 void **List) 1150{ 1151 ACPI_STATUS Status; 1152 DT_SUBTABLE *Subtable; 1153 DT_SUBTABLE *ParentTable; 1154 DT_FIELD **PFieldList = (DT_FIELD **) List; 1155 DT_FIELD *SubtableStart; 1156 ACPI_SLIC_HEADER *SlicHeader; 1157 ACPI_DMTABLE_INFO *InfoTable; 1158 1159 1160 while (*PFieldList) 1161 { 1162 SubtableStart = *PFieldList; 1163 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr, 1164 &Subtable, TRUE); 1165 if (ACPI_FAILURE (Status)) 1166 { 1167 return (Status); 1168 } 1169 1170 ParentTable = DtPeekSubtable (); 1171 DtInsertSubtable (ParentTable, Subtable); 1172 DtPushSubtable (Subtable); 1173 1174 SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer); 1175 1176 switch (SlicHeader->Type) 1177 { 1178 case ACPI_SLIC_TYPE_PUBLIC_KEY: 1179 InfoTable = AcpiDmTableInfoSlic0; 1180 break; 1181 case ACPI_SLIC_TYPE_WINDOWS_MARKER: 1182 InfoTable = AcpiDmTableInfoSlic1; 1183 break; 1184 default: 1185 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC"); 1186 return (AE_ERROR); 1187 } 1188 1189 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1190 if (ACPI_FAILURE (Status)) 1191 { 1192 return (Status); 1193 } 1194 1195 ParentTable = DtPeekSubtable (); 1196 DtInsertSubtable (ParentTable, Subtable); 1197 DtPopSubtable (); 1198 } 1199 1200 return (AE_OK); 1201} 1202 1203 1204/****************************************************************************** 1205 * 1206 * FUNCTION: DtCompileSlit 1207 * 1208 * PARAMETERS: List - Current field list pointer 1209 * 1210 * RETURN: Status 1211 * 1212 * DESCRIPTION: Compile SLIT. 1213 * 1214 *****************************************************************************/ 1215 1216ACPI_STATUS 1217DtCompileSlit ( 1218 void **List) 1219{ 1220 ACPI_STATUS Status; 1221 DT_SUBTABLE *Subtable; 1222 DT_SUBTABLE *ParentTable; 1223 DT_FIELD **PFieldList = (DT_FIELD **) List; 1224 DT_FIELD *FieldList; 1225 UINT32 Localities; 1226 UINT8 *LocalityBuffer; 1227 UINT32 RemainingData; 1228 1229 1230 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 1231 &Subtable, TRUE); 1232 if (ACPI_FAILURE (Status)) 1233 { 1234 return (Status); 1235 } 1236 1237 ParentTable = DtPeekSubtable (); 1238 DtInsertSubtable (ParentTable, Subtable); 1239 1240 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 1241 LocalityBuffer = UtLocalCalloc (Localities); 1242 1243 FieldList = *PFieldList; 1244 while (FieldList) 1245 { 1246 /* Handle multiple-line buffer */ 1247 1248 RemainingData = Localities; 1249 while (RemainingData && FieldList) 1250 { 1251 RemainingData = DtCompileBuffer ( 1252 LocalityBuffer + (Localities - RemainingData), 1253 FieldList->Value, FieldList, RemainingData); 1254 FieldList = FieldList->Next; 1255 } 1256 1257 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 1258 DtInsertSubtable (ParentTable, Subtable); 1259 } 1260 1261 ACPI_FREE (LocalityBuffer); 1262 return (AE_OK); 1263} 1264 1265 1266/****************************************************************************** 1267 * 1268 * FUNCTION: DtCompileSrat 1269 * 1270 * PARAMETERS: List - Current field list pointer 1271 * 1272 * RETURN: Status 1273 * 1274 * DESCRIPTION: Compile SRAT. 1275 * 1276 *****************************************************************************/ 1277 1278ACPI_STATUS 1279DtCompileSrat ( 1280 void **List) 1281{ 1282 ACPI_STATUS Status; 1283 DT_SUBTABLE *Subtable; 1284 DT_SUBTABLE *ParentTable; 1285 DT_FIELD **PFieldList = (DT_FIELD **) List; 1286 DT_FIELD *SubtableStart; 1287 ACPI_SUBTABLE_HEADER *SratHeader; 1288 ACPI_DMTABLE_INFO *InfoTable; 1289 1290 1291 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 1292 &Subtable, TRUE); 1293 if (ACPI_FAILURE (Status)) 1294 { 1295 return (Status); 1296 } 1297 1298 ParentTable = DtPeekSubtable (); 1299 DtInsertSubtable (ParentTable, Subtable); 1300 1301 while (*PFieldList) 1302 { 1303 SubtableStart = *PFieldList; 1304 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 1305 &Subtable, TRUE); 1306 if (ACPI_FAILURE (Status)) 1307 { 1308 return (Status); 1309 } 1310 1311 ParentTable = DtPeekSubtable (); 1312 DtInsertSubtable (ParentTable, Subtable); 1313 DtPushSubtable (Subtable); 1314 1315 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1316 1317 switch (SratHeader->Type) 1318 { 1319 case ACPI_SRAT_TYPE_CPU_AFFINITY: 1320 InfoTable = AcpiDmTableInfoSrat0; 1321 break; 1322 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1323 InfoTable = AcpiDmTableInfoSrat1; 1324 break; 1325 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1326 InfoTable = AcpiDmTableInfoSrat2; 1327 break; 1328 default: 1329 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 1330 return (AE_ERROR); 1331 } 1332 1333 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1334 if (ACPI_FAILURE (Status)) 1335 { 1336 return (Status); 1337 } 1338 1339 ParentTable = DtPeekSubtable (); 1340 DtInsertSubtable (ParentTable, Subtable); 1341 DtPopSubtable (); 1342 } 1343 1344 return (AE_OK); 1345} 1346 1347 1348/****************************************************************************** 1349 * 1350 * FUNCTION: DtGetGenericTableInfo 1351 * 1352 * PARAMETERS: Name - Generic type name 1353 * 1354 * RETURN: Info entry 1355 * 1356 * DESCRIPTION: Obtain table info for a generic name entry 1357 * 1358 *****************************************************************************/ 1359 1360ACPI_DMTABLE_INFO * 1361DtGetGenericTableInfo ( 1362 char *Name) 1363{ 1364 ACPI_DMTABLE_INFO *Info; 1365 UINT32 i; 1366 1367 1368 if (!Name) 1369 { 1370 return (NULL); 1371 } 1372 1373 /* Search info table for name match */ 1374 1375 for (i = 0; ; i++) 1376 { 1377 Info = AcpiDmTableInfoGeneric[i]; 1378 if (Info->Opcode == ACPI_DMT_EXIT) 1379 { 1380 Info = NULL; 1381 break; 1382 } 1383 1384 if (!ACPI_STRCMP (Name, Info->Name)) 1385 { 1386 break; 1387 } 1388 } 1389 1390 return (Info); 1391} 1392 1393 1394/****************************************************************************** 1395 * 1396 * FUNCTION: DtCompileUefi 1397 * 1398 * PARAMETERS: List - Current field list pointer 1399 * 1400 * RETURN: Status 1401 * 1402 * DESCRIPTION: Compile UEFI. 1403 * 1404 *****************************************************************************/ 1405 1406ACPI_STATUS 1407DtCompileUefi ( 1408 void **List) 1409{ 1410 ACPI_STATUS Status; 1411 DT_SUBTABLE *Subtable; 1412 DT_SUBTABLE *ParentTable; 1413 DT_FIELD **PFieldList = (DT_FIELD **) List; 1414 ACPI_DMTABLE_INFO *Info; 1415 UINT16 *DataOffset; 1416 1417 1418 /* Compile the predefined portion of the UEFI table */ 1419 1420 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 1421 &Subtable, TRUE); 1422 if (ACPI_FAILURE (Status)) 1423 { 1424 return (Status); 1425 } 1426 1427 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 1428 *DataOffset = sizeof (ACPI_TABLE_UEFI); 1429 1430 ParentTable = DtPeekSubtable (); 1431 DtInsertSubtable (ParentTable, Subtable); 1432 1433 /* 1434 * Compile the "generic" portion of the UEFI table. This 1435 * part of the table is not predefined and any of the generic 1436 * operators may be used. 1437 */ 1438 1439 /* Find any and all labels in the entire generic portion */ 1440 1441 DtDetectAllLabels (*PFieldList); 1442 1443 /* Now we can actually compile the parse tree */ 1444 1445 while (*PFieldList) 1446 { 1447 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 1448 if (!Info) 1449 { 1450 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 1451 (*PFieldList)->Name); 1452 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 1453 (*PFieldList), MsgBuffer); 1454 1455 *PFieldList = (*PFieldList)->Next; 1456 continue; 1457 } 1458 1459 Status = DtCompileTable (PFieldList, Info, 1460 &Subtable, TRUE); 1461 if (ACPI_SUCCESS (Status)) 1462 { 1463 DtInsertSubtable (ParentTable, Subtable); 1464 } 1465 else 1466 { 1467 *PFieldList = (*PFieldList)->Next; 1468 1469 if (Status == AE_NOT_FOUND) 1470 { 1471 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 1472 (*PFieldList)->Name); 1473 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 1474 (*PFieldList), MsgBuffer); 1475 } 1476 } 1477 } 1478 1479 return (AE_OK); 1480} 1481 1482 1483/****************************************************************************** 1484 * 1485 * FUNCTION: DtCompileWdat 1486 * 1487 * PARAMETERS: List - Current field list pointer 1488 * 1489 * RETURN: Status 1490 * 1491 * DESCRIPTION: Compile WDAT. 1492 * 1493 *****************************************************************************/ 1494 1495ACPI_STATUS 1496DtCompileWdat ( 1497 void **List) 1498{ 1499 ACPI_STATUS Status; 1500 1501 1502 Status = DtCompileTwoSubtables (List, 1503 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 1504 return (Status); 1505} 1506 1507 1508/****************************************************************************** 1509 * 1510 * FUNCTION: DtCompileXsdt 1511 * 1512 * PARAMETERS: List - Current field list pointer 1513 * 1514 * RETURN: Status 1515 * 1516 * DESCRIPTION: Compile XSDT. 1517 * 1518 *****************************************************************************/ 1519 1520ACPI_STATUS 1521DtCompileXsdt ( 1522 void **List) 1523{ 1524 DT_SUBTABLE *Subtable; 1525 DT_SUBTABLE *ParentTable; 1526 DT_FIELD *FieldList = *(DT_FIELD **) List; 1527 UINT64 Address; 1528 1529 ParentTable = DtPeekSubtable (); 1530 1531 while (FieldList) 1532 { 1533 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 1534 1535 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 1536 DtInsertSubtable (ParentTable, Subtable); 1537 FieldList = FieldList->Next; 1538 } 1539 1540 return (AE_OK); 1541} 1542