1 /******************************************************************************
   2  *
   3  * Module Name: aetables - ACPI table setup/install for acpiexec utility
   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 #include "aecommon.h"
  45 #include "aetables.h"
  46 
  47 #define _COMPONENT          ACPI_TOOLS
  48         ACPI_MODULE_NAME    ("aetables")
  49 
  50 /* Local prototypes */
  51 
  52 void
  53 AeTableOverride (
  54     ACPI_TABLE_HEADER       *ExistingTable,
  55     ACPI_TABLE_HEADER       **NewTable);
  56 
  57 ACPI_PHYSICAL_ADDRESS
  58 AeLocalGetRootPointer (
  59     void);
  60 
  61 /* User table (DSDT) */
  62 
  63 static ACPI_TABLE_HEADER        *DsdtToInstallOverride;
  64 
  65 /* Non-AML tables that are constructed locally and installed */
  66 
  67 static ACPI_TABLE_RSDP          LocalRSDP;
  68 static ACPI_TABLE_FACS          LocalFACS;
  69 static ACPI_TABLE_HEADER        LocalTEST;
  70 static ACPI_TABLE_HEADER        LocalBADTABLE;
  71 
  72 /*
  73  * We need a local FADT so that the hardware subcomponent will function,
  74  * even though the underlying OSD HW access functions don't do anything.
  75  */
  76 static ACPI_TABLE_FADT          LocalFADT;
  77 
  78 /*
  79  * Use XSDT so that both 32- and 64-bit versions of this utility will
  80  * function automatically.
  81  */
  82 static ACPI_TABLE_XSDT          *LocalXSDT;
  83 
  84 #define BASE_XSDT_TABLES        10
  85 #define BASE_XSDT_SIZE          (sizeof (ACPI_TABLE_XSDT) + \
  86                                     ((BASE_XSDT_TABLES -1) * sizeof (UINT64)))
  87 
  88 #define ACPI_MAX_INIT_TABLES    (32)
  89 static ACPI_TABLE_DESC          Tables[ACPI_MAX_INIT_TABLES];
  90 
  91 
  92 /******************************************************************************
  93  *
  94  * FUNCTION:    AeTableOverride
  95  *
  96  * DESCRIPTION: Local implementation of AcpiOsTableOverride.
  97  *              Exercise the override mechanism
  98  *
  99  *****************************************************************************/
 100 
 101 void
 102 AeTableOverride (
 103     ACPI_TABLE_HEADER       *ExistingTable,
 104     ACPI_TABLE_HEADER       **NewTable)
 105 {
 106 
 107     /* This code exercises the table override mechanism in the core */
 108 
 109     if (ACPI_COMPARE_NAME (ExistingTable->Signature, ACPI_SIG_DSDT))
 110     {
 111         *NewTable = DsdtToInstallOverride;
 112     }
 113 
 114     /* This code tests override of dynamically loaded tables */
 115 
 116     else if (ACPI_COMPARE_NAME (ExistingTable->Signature, "OEM9"))
 117     {
 118         *NewTable = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Ssdt3Code);
 119     }
 120 }
 121 
 122 
 123 /******************************************************************************
 124  *
 125  * FUNCTION:    AeBuildLocalTables
 126  *
 127  * PARAMETERS:  TableCount      - Number of tables on the command line
 128  *              TableList       - List of actual tables from files
 129  *
 130  * RETURN:      Status
 131  *
 132  * DESCRIPTION: Build a complete ACPI table chain, with a local RSDP, XSDT,
 133  *              FADT, and several other test tables.
 134  *
 135  *****************************************************************************/
 136 
 137 ACPI_STATUS
 138 AeBuildLocalTables (
 139     UINT32                  TableCount,
 140     AE_TABLE_DESC           *TableList)
 141 {
 142     ACPI_PHYSICAL_ADDRESS   DsdtAddress = 0;
 143     UINT32                  XsdtSize;
 144     AE_TABLE_DESC           *NextTable;
 145     UINT32                  NextIndex;
 146     ACPI_TABLE_FADT         *ExternalFadt = NULL;
 147 
 148 
 149     /*
 150      * Update the table count. For DSDT, it is not put into the XSDT. For
 151      * FADT, this is already accounted for since we usually install a
 152      * local FADT.
 153      */
 154     NextTable = TableList;
 155     while (NextTable)
 156     {
 157         if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT) ||
 158             ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
 159         {
 160             TableCount--;
 161         }
 162         NextTable = NextTable->Next;
 163     }
 164 
 165     XsdtSize = BASE_XSDT_SIZE + (TableCount * sizeof (UINT64));
 166 
 167     /* Build an XSDT */
 168 
 169     LocalXSDT = AcpiOsAllocate (XsdtSize);
 170     if (!LocalXSDT)
 171     {
 172         return (AE_NO_MEMORY);
 173     }
 174 
 175     ACPI_MEMSET (LocalXSDT, 0, XsdtSize);
 176     ACPI_MOVE_NAME (LocalXSDT->Header.Signature, ACPI_SIG_XSDT);
 177     LocalXSDT->Header.Length = XsdtSize;
 178     LocalXSDT->Header.Revision = 1;
 179 
 180     LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (&LocalTEST);
 181     LocalXSDT->TableOffsetEntry[1] = ACPI_PTR_TO_PHYSADDR (&LocalBADTABLE);
 182     LocalXSDT->TableOffsetEntry[2] = ACPI_PTR_TO_PHYSADDR (&LocalFADT);
 183 
 184     /* Install two SSDTs to test multiple table support */
 185 
 186     LocalXSDT->TableOffsetEntry[3] = ACPI_PTR_TO_PHYSADDR (&Ssdt1Code);
 187     LocalXSDT->TableOffsetEntry[4] = ACPI_PTR_TO_PHYSADDR (&Ssdt2Code);
 188 
 189     /* Install the OEM1 table to test LoadTable */
 190 
 191     LocalXSDT->TableOffsetEntry[5] = ACPI_PTR_TO_PHYSADDR (&Oem1Code);
 192 
 193     /* Install the OEMx table to test LoadTable */
 194 
 195     LocalXSDT->TableOffsetEntry[6] = ACPI_PTR_TO_PHYSADDR (&OemxCode);
 196 
 197      /* Install the ECDT table to test _REG */
 198 
 199     LocalXSDT->TableOffsetEntry[7] = ACPI_PTR_TO_PHYSADDR (&EcdtCode);
 200 
 201     /* Install two UEFIs to test multiple table support */
 202 
 203     LocalXSDT->TableOffsetEntry[8] = ACPI_PTR_TO_PHYSADDR (&Uefi1Code);
 204     LocalXSDT->TableOffsetEntry[9] = ACPI_PTR_TO_PHYSADDR (&Uefi2Code);
 205 
 206     /*
 207      * Install the user tables. The DSDT must be installed in the FADT.
 208      * All other tables are installed directly into the XSDT.
 209      */
 210     NextIndex = BASE_XSDT_TABLES;
 211     NextTable = TableList;
 212     while (NextTable)
 213     {
 214         /*
 215          * Incoming DSDT or FADT are special cases. All other tables are
 216          * just immediately installed into the XSDT.
 217          */
 218         if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT))
 219         {
 220             if (DsdtAddress)
 221             {
 222                 printf ("Already found a DSDT, only one allowed\n");
 223                 return (AE_ALREADY_EXISTS);
 224             }
 225 
 226             /* The incoming user table is a DSDT */
 227 
 228             DsdtAddress = ACPI_PTR_TO_PHYSADDR (&DsdtCode);
 229             DsdtToInstallOverride = NextTable->Table;
 230         }
 231         else if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
 232         {
 233             ExternalFadt = ACPI_CAST_PTR (ACPI_TABLE_FADT, NextTable->Table);
 234             LocalXSDT->TableOffsetEntry[2] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
 235         }
 236         else
 237         {
 238             /* Install the table in the XSDT */
 239 
 240             LocalXSDT->TableOffsetEntry[NextIndex] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
 241             NextIndex++;
 242         }
 243 
 244         NextTable = NextTable->Next;
 245     }
 246 
 247     /* Build an RSDP */
 248 
 249     ACPI_MEMSET (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP));
 250     ACPI_MAKE_RSDP_SIG (LocalRSDP.Signature);
 251     ACPI_MEMCPY (LocalRSDP.OemId, "I_TEST", 6);
 252     LocalRSDP.Revision = 2;
 253     LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalXSDT);
 254     LocalRSDP.Length = sizeof (ACPI_TABLE_XSDT);
 255 
 256     /* Set checksums for both XSDT and RSDP */
 257 
 258     LocalXSDT->Header.Checksum = (UINT8) -AcpiTbChecksum (
 259         (void *) LocalXSDT, LocalXSDT->Header.Length);
 260     LocalRSDP.Checksum = (UINT8) -AcpiTbChecksum (
 261         (void *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH);
 262 
 263     if (!DsdtAddress)
 264     {
 265         /* Use the local DSDT because incoming table(s) are all SSDT(s) */
 266 
 267         DsdtAddress = ACPI_PTR_TO_PHYSADDR (LocalDsdtCode);
 268         DsdtToInstallOverride = ACPI_CAST_PTR (ACPI_TABLE_HEADER, LocalDsdtCode);
 269     }
 270 
 271     if (ExternalFadt)
 272     {
 273         /*
 274          * Use the external FADT, but we must update the DSDT/FACS addresses
 275          * as well as the checksum
 276          */
 277         ExternalFadt->Dsdt = DsdtAddress;
 278         if (!AcpiGbl_ReducedHardware)
 279         {
 280             ExternalFadt->Facs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
 281         }
 282 
 283         if (ExternalFadt->Header.Length > ACPI_PTR_DIFF (&ExternalFadt->XDsdt, ExternalFadt))
 284         {
 285             ExternalFadt->XDsdt = DsdtAddress;
 286 
 287             if (!AcpiGbl_ReducedHardware)
 288             {
 289                 ExternalFadt->XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
 290             }
 291         }
 292 
 293         /* Complete the FADT with the checksum */
 294 
 295         ExternalFadt->Header.Checksum = 0;
 296         ExternalFadt->Header.Checksum = (UINT8) -AcpiTbChecksum (
 297             (void *) ExternalFadt, ExternalFadt->Header.Length);
 298     }
 299     else if (AcpiGbl_UseHwReducedFadt)
 300     {
 301         ACPI_MEMCPY (&LocalFADT, HwReducedFadtCode, sizeof (ACPI_TABLE_FADT));
 302         LocalFADT.Dsdt = DsdtAddress;
 303         LocalFADT.XDsdt = DsdtAddress;
 304 
 305         LocalFADT.Header.Checksum = 0;
 306         LocalFADT.Header.Checksum = (UINT8) -AcpiTbChecksum (
 307             (void *) &LocalFADT, LocalFADT.Header.Length);
 308     }
 309     else
 310     {
 311         /*
 312          * Build a local FADT so we can test the hardware/event init
 313          */
 314         ACPI_MEMSET (&LocalFADT, 0, sizeof (ACPI_TABLE_FADT));
 315         ACPI_MOVE_NAME (LocalFADT.Header.Signature, ACPI_SIG_FADT);
 316 
 317         /* Setup FADT header and DSDT/FACS addresses */
 318 
 319         LocalFADT.Dsdt = 0;
 320         LocalFADT.Facs = 0;
 321 
 322         LocalFADT.XDsdt = DsdtAddress;
 323         LocalFADT.XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
 324 
 325         LocalFADT.Header.Revision = 3;
 326         LocalFADT.Header.Length = sizeof (ACPI_TABLE_FADT);
 327 
 328         /* Miscellaneous FADT fields */
 329 
 330         LocalFADT.Gpe0BlockLength = 16;
 331         LocalFADT.Gpe0Block = 0x00001234;
 332 
 333         LocalFADT.Gpe1BlockLength = 6;
 334         LocalFADT.Gpe1Block = 0x00005678;
 335         LocalFADT.Gpe1Base = 96;
 336 
 337         LocalFADT.Pm1EventLength = 4;
 338         LocalFADT.Pm1aEventBlock = 0x00001aaa;
 339         LocalFADT.Pm1bEventBlock = 0x00001bbb;
 340 
 341         LocalFADT.Pm1ControlLength = 2;
 342         LocalFADT.Pm1aControlBlock = 0xB0;
 343 
 344         LocalFADT.PmTimerLength = 4;
 345         LocalFADT.PmTimerBlock = 0xA0;
 346 
 347         LocalFADT.Pm2ControlBlock = 0xC0;
 348         LocalFADT.Pm2ControlLength = 1;
 349 
 350         /* Setup one example X-64 field */
 351 
 352         LocalFADT.XPm1bEventBlock.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
 353         LocalFADT.XPm1bEventBlock.Address = LocalFADT.Pm1bEventBlock;
 354         LocalFADT.XPm1bEventBlock.BitWidth = (UINT8) ACPI_MUL_8 (LocalFADT.Pm1EventLength);
 355 
 356         /* Complete the FADT with the checksum */
 357 
 358         LocalFADT.Header.Checksum = 0;
 359         LocalFADT.Header.Checksum = (UINT8) -AcpiTbChecksum (
 360             (void *) &LocalFADT, LocalFADT.Header.Length);
 361     }
 362 
 363     /* Build a FACS */
 364 
 365     ACPI_MEMSET (&LocalFACS, 0, sizeof (ACPI_TABLE_FACS));
 366     ACPI_MOVE_NAME (LocalFACS.Signature, ACPI_SIG_FACS);
 367 
 368     LocalFACS.Length = sizeof (ACPI_TABLE_FACS);
 369     LocalFACS.GlobalLock = 0x11AA0011;
 370 
 371     /*
 372      * Build a fake table [TEST] so that we make sure that the
 373      * ACPICA core ignores it
 374      */
 375     ACPI_MEMSET (&LocalTEST, 0, sizeof (ACPI_TABLE_HEADER));
 376     ACPI_MOVE_NAME (LocalTEST.Signature, "TEST");
 377 
 378     LocalTEST.Revision = 1;
 379     LocalTEST.Length = sizeof (ACPI_TABLE_HEADER);
 380     LocalTEST.Checksum = (UINT8) -AcpiTbChecksum (
 381         (void *) &LocalTEST, LocalTEST.Length);
 382 
 383     /*
 384      * Build a fake table with a bad signature [BAD!] so that we make
 385      * sure that the ACPICA core ignores it
 386      */
 387     ACPI_MEMSET (&LocalBADTABLE, 0, sizeof (ACPI_TABLE_HEADER));
 388     ACPI_MOVE_NAME (LocalBADTABLE.Signature, "BAD!");
 389 
 390     LocalBADTABLE.Revision = 1;
 391     LocalBADTABLE.Length = sizeof (ACPI_TABLE_HEADER);
 392     LocalBADTABLE.Checksum = (UINT8) -AcpiTbChecksum (
 393         (void *) &LocalBADTABLE, LocalBADTABLE.Length);
 394 
 395     return (AE_OK);
 396 }
 397 
 398 
 399 /******************************************************************************
 400  *
 401  * FUNCTION:    AeInstallTables
 402  *
 403  * PARAMETERS:  None
 404  *
 405  * RETURN:      Status
 406  *
 407  * DESCRIPTION: Install the various ACPI tables
 408  *
 409  *****************************************************************************/
 410 
 411 ACPI_STATUS
 412 AeInstallTables (
 413     void)
 414 {
 415     ACPI_STATUS             Status;
 416     ACPI_TABLE_HEADER       Header;
 417     ACPI_TABLE_HEADER       *Table;
 418 
 419 
 420     Status = AcpiInitializeTables (Tables, ACPI_MAX_INIT_TABLES, TRUE);
 421     AE_CHECK_OK (AcpiInitializeTables, Status);
 422 
 423     Status = AcpiReallocateRootTable ();
 424     AE_CHECK_OK (AcpiReallocateRootTable, Status);
 425 
 426     Status = AcpiLoadTables ();
 427     AE_CHECK_OK (AcpiLoadTables, Status);
 428 
 429     /*
 430      * Test run-time control method installation. Do it twice to test code
 431      * for an existing name.
 432      */
 433     Status = AcpiInstallMethod (MethodCode);
 434     if (ACPI_FAILURE (Status))
 435     {
 436         AcpiOsPrintf ("%s, Could not install method\n",
 437             AcpiFormatException (Status));
 438     }
 439 
 440     Status = AcpiInstallMethod (MethodCode);
 441     if (ACPI_FAILURE (Status))
 442     {
 443         AcpiOsPrintf ("%s, Could not install method\n",
 444             AcpiFormatException (Status));
 445     }
 446 
 447     /* Test multiple table/UEFI support. First, get the headers */
 448 
 449     Status = AcpiGetTableHeader (ACPI_SIG_UEFI, 1, &Header);
 450     AE_CHECK_OK (AcpiGetTableHeader, Status);
 451 
 452     Status = AcpiGetTableHeader (ACPI_SIG_UEFI, 2, &Header);
 453     AE_CHECK_OK (AcpiGetTableHeader, Status);
 454 
 455     Status = AcpiGetTableHeader (ACPI_SIG_UEFI, 3, &Header);
 456     AE_CHECK_STATUS (AcpiGetTableHeader, Status, AE_NOT_FOUND);
 457 
 458     /* Now get the actual tables */
 459 
 460     Status = AcpiGetTable (ACPI_SIG_UEFI, 1, &Table);
 461     AE_CHECK_OK (AcpiGetTable, Status);
 462 
 463     Status = AcpiGetTable (ACPI_SIG_UEFI, 2, &Table);
 464     AE_CHECK_OK (AcpiGetTable, Status);
 465 
 466     Status = AcpiGetTable (ACPI_SIG_UEFI, 3, &Table);
 467     AE_CHECK_STATUS (AcpiGetTable, Status, AE_NOT_FOUND);
 468 
 469     return (AE_OK);
 470 }
 471 
 472 
 473 /******************************************************************************
 474  *
 475  * FUNCTION:    AeLocalGetRootPointer
 476  *
 477  * PARAMETERS:  Flags       - not used
 478  *              Address     - Where the root pointer is returned
 479  *
 480  * RETURN:      Status
 481  *
 482  * DESCRIPTION: Return a local RSDP, used to dynamically load tables via the
 483  *              standard ACPI mechanism.
 484  *
 485  *****************************************************************************/
 486 
 487 ACPI_PHYSICAL_ADDRESS
 488 AeLocalGetRootPointer (
 489     void)
 490 {
 491 
 492     return ((ACPI_PHYSICAL_ADDRESS) &LocalRSDP);
 493 }