Home | History | Annotate | Line # | Download | only in compiler
dttemplate.c revision 1.1.1.15
      1 /******************************************************************************
      2  *
      3  * Module Name: dttemplate - ACPI table template generation
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, 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 MERCHANTABILITY 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 "aslcompiler.h"
     45 #include "acapps.h"
     46 #include "dttemplate.h" /* Contains the hex ACPI table templates */
     47 
     48 #define _COMPONENT          DT_COMPILER
     49         ACPI_MODULE_NAME    ("dttemplate")
     50 
     51 
     52 /* Local prototypes */
     53 
     54 static BOOLEAN
     55 AcpiUtIsSpecialTable (
     56     char                    *Signature);
     57 
     58 static ACPI_STATUS
     59 DtCreateOneTemplateFile (
     60     char                    *Signature,
     61     UINT32                  TableCount);
     62 
     63 static ACPI_STATUS
     64 DtCreateOneTemplate (
     65     char                    *Signature,
     66     UINT32                  TableCount,
     67     const ACPI_DMTABLE_DATA *TableData);
     68 
     69 static ACPI_STATUS
     70 DtCreateAllTemplates (
     71     void);
     72 
     73 static int
     74 DtEmitDefinitionBlock (
     75     FILE                    *File,
     76     char                    *Filename,
     77     char                    *Signature,
     78     UINT32                  Instance);
     79 
     80 
     81 /*******************************************************************************
     82  *
     83  * FUNCTION:    AcpiUtIsSpecialTable
     84  *
     85  * PARAMETERS:  Signature           - ACPI table signature
     86  *
     87  * RETURN:      TRUE if signature is a special ACPI table
     88  *
     89  * DESCRIPTION: Check for valid ACPI tables that are not in the main ACPI
     90  *              table data structure (AcpiDmTableData).
     91  *
     92  ******************************************************************************/
     93 
     94 static BOOLEAN
     95 AcpiUtIsSpecialTable (
     96     char                    *Signature)
     97 {
     98 
     99     if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_DSDT) ||
    100         ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_OSDT) ||
    101         ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT) ||
    102         ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_FACS) ||
    103         ACPI_COMPARE_NAMESEG (Signature, ACPI_RSDP_NAME))
    104     {
    105         return (TRUE);
    106     }
    107 
    108     return (FALSE);
    109 }
    110 
    111 
    112 /*******************************************************************************
    113  *
    114  * FUNCTION:    DtCreateTemplates
    115  *
    116  * PARAMETERS:  argv                - Standard command line arguments
    117  *
    118  * RETURN:      Status
    119  *
    120  * DESCRIPTION: Create one or more template files.
    121  *
    122  ******************************************************************************/
    123 
    124 ACPI_STATUS
    125 DtCreateTemplates (
    126     char                    **argv)
    127 {
    128     char                    *Signature;
    129     char                    *End;
    130     unsigned long           TableCount;
    131     ACPI_STATUS             Status = AE_OK;
    132 
    133 
    134     AslInitializeGlobals ();
    135 
    136     Status = AdInitialize ();
    137     if (ACPI_FAILURE (Status))
    138     {
    139         return (Status);
    140     }
    141 
    142     /*
    143      * Special cases for DSDT, ALL, and '*'
    144      */
    145 
    146     /* Default (no signature option) is DSDT */
    147 
    148     if (AcpiGbl_Optind < 3)
    149     {
    150         fprintf (stderr, "Creating default template: [DSDT]\n");
    151         Status = DtCreateOneTemplateFile (ACPI_SIG_DSDT, 0);
    152         goto Exit;
    153     }
    154 
    155     AcpiGbl_Optind--;
    156     Signature = argv[AcpiGbl_Optind];
    157     AcpiUtStrupr (Signature);
    158 
    159     /*
    160      * Multiple SSDT support (-T <ssdt count>)
    161      */
    162     TableCount = strtoul (Signature, &End, 0);
    163     if (Signature != End)
    164     {
    165         /* The count is used for table ID and method name - max is 254(+1) */
    166 
    167         if (TableCount > 254)
    168         {
    169             fprintf (stderr, "%u SSDTs requested, maximum is 254\n",
    170                 (unsigned int) TableCount);
    171 
    172             Status = AE_LIMIT;
    173             goto Exit;
    174         }
    175 
    176         Status = DtCreateOneTemplateFile (ACPI_SIG_DSDT, TableCount);
    177         goto Exit;
    178     }
    179 
    180     if (!strcmp (Signature, "ALL"))
    181     {
    182         /* Create all available/known templates */
    183 
    184         Status = DtCreateAllTemplates ();
    185         goto Exit;
    186     }
    187 
    188     /*
    189      * Normal case: Create template for each signature
    190      */
    191     while (argv[AcpiGbl_Optind])
    192     {
    193         Signature = argv[AcpiGbl_Optind];
    194         AcpiUtStrupr (Signature);
    195 
    196         Status = DtCreateOneTemplateFile (Signature, 0);
    197         if (ACPI_FAILURE (Status))
    198         {
    199             goto Exit;
    200         }
    201 
    202         AcpiGbl_Optind++;
    203     }
    204 
    205 
    206 Exit:
    207     /* Shutdown ACPICA subsystem */
    208 
    209     (void) AcpiTerminate ();
    210     UtDeleteLocalCaches ();
    211     return (Status);
    212 }
    213 
    214 
    215 /*******************************************************************************
    216  *
    217  * FUNCTION:    DtCreateOneTemplateFile
    218  *
    219  * PARAMETERS:  Signature           - ACPI table signature
    220  *
    221  * RETURN:      Status
    222  *
    223  * DESCRIPTION: Create one template file of the requested signature.
    224  *
    225  ******************************************************************************/
    226 
    227 static ACPI_STATUS
    228 DtCreateOneTemplateFile (
    229     char                    *Signature,
    230     UINT32                  TableCount)
    231 {
    232     const ACPI_DMTABLE_DATA *TableData;
    233     ACPI_STATUS             Status;
    234 
    235 
    236     /*
    237      * Validate signature and get the template data:
    238      *  1) Signature must be 4 characters
    239      *  2) Signature must be a recognized ACPI table
    240      *  3) There must be a template associated with the signature
    241      */
    242     if (strlen (Signature) != ACPI_NAMESEG_SIZE)
    243     {
    244         fprintf (stderr,
    245             "%s: Invalid ACPI table signature "
    246             "(length must be 4 characters)\n", Signature);
    247         return (AE_ERROR);
    248     }
    249 
    250     /*
    251      * Some slack for the two strange tables whose name is different than
    252      * their signatures: MADT->APIC and FADT->FACP.
    253      */
    254     if (!strcmp (Signature, "MADT"))
    255     {
    256         Signature = "APIC";
    257     }
    258     else if (!strcmp (Signature, "FADT"))
    259     {
    260         Signature = "FACP";
    261     }
    262 
    263     /* TableData will point to the template */
    264 
    265     TableData = AcpiDmGetTableData (Signature);
    266     if (TableData)
    267     {
    268         if (!TableData->Template)
    269         {
    270             fprintf (stderr, "%4.4s: No template available\n", Signature);
    271             return (AE_ERROR);
    272         }
    273     }
    274     else if (!AcpiUtIsSpecialTable (Signature))
    275     {
    276         fprintf (stderr,
    277             "%4.4s: Unrecognized ACPI table signature\n", Signature);
    278         return (AE_ERROR);
    279     }
    280 
    281     Status = DtCreateOneTemplate (Signature, TableCount, TableData);
    282     return (Status);
    283 }
    284 
    285 
    286 /*******************************************************************************
    287  *
    288  * FUNCTION:    DtCreateAllTemplates
    289  *
    290  * PARAMETERS:  None
    291  *
    292  * RETURN:      Status
    293  *
    294  * DESCRIPTION: Create all currently defined template files
    295  *
    296  ******************************************************************************/
    297 
    298 static ACPI_STATUS
    299 DtCreateAllTemplates (
    300     void)
    301 {
    302     const ACPI_DMTABLE_DATA *TableData;
    303     ACPI_STATUS             Status;
    304 
    305 
    306     fprintf (stderr, "Creating all supported Template files\n");
    307 
    308     /* Walk entire ACPI table data structure */
    309 
    310     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
    311     {
    312         /* If table has a template, create the template file */
    313 
    314         if (TableData->Template)
    315         {
    316             Status = DtCreateOneTemplate (TableData->Signature,
    317                 0, TableData);
    318             if (ACPI_FAILURE (Status))
    319             {
    320                 return (Status);
    321             }
    322         }
    323     }
    324 
    325     /*
    326      * Create the special ACPI tables:
    327      * 1) DSDT/SSDT are AML tables, not data tables
    328      * 2) FACS and RSDP have non-standard headers
    329      */
    330     Status = DtCreateOneTemplate (ACPI_SIG_DSDT, 0, NULL);
    331     if (ACPI_FAILURE (Status))
    332     {
    333         return (Status);
    334     }
    335 
    336     Status = DtCreateOneTemplate (ACPI_SIG_SSDT, 0, NULL);
    337     if (ACPI_FAILURE (Status))
    338     {
    339         return (Status);
    340     }
    341 
    342     Status = DtCreateOneTemplate (ACPI_SIG_OSDT, 0, NULL);
    343     if (ACPI_FAILURE (Status))
    344     {
    345         return (Status);
    346     }
    347 
    348     Status = DtCreateOneTemplate (ACPI_SIG_FACS, 0, NULL);
    349     if (ACPI_FAILURE (Status))
    350     {
    351         return (Status);
    352     }
    353 
    354     Status = DtCreateOneTemplate (ACPI_RSDP_NAME, 0, NULL);
    355     if (ACPI_FAILURE (Status))
    356     {
    357         return (Status);
    358     }
    359 
    360     return (AE_OK);
    361 }
    362 
    363 
    364 /*******************************************************************************
    365  *
    366  * FUNCTION:    DtCreateOneTemplate
    367  *
    368  * PARAMETERS:  Signature           - ACPI signature, NULL terminated.
    369  *              TableCount          - Used for SSDTs in same file as DSDT
    370  *              TableData           - Entry in ACPI table data structure.
    371  *                                    NULL if a special ACPI table.
    372  *
    373  * RETURN:      Status
    374  *
    375  * DESCRIPTION: Create one template source file for the requested ACPI table.
    376  *
    377  ******************************************************************************/
    378 
    379 static ACPI_STATUS
    380 DtCreateOneTemplate (
    381     char                    *Signature,
    382     UINT32                  TableCount,
    383     const ACPI_DMTABLE_DATA  *TableData)
    384 {
    385     char                    *DisasmFilename;
    386     FILE                    *File;
    387     ACPI_STATUS             Status = AE_OK;
    388     int                     Actual;
    389     UINT32                  i;
    390 
    391 
    392     /* New file will have a .asl suffix */
    393 
    394     DisasmFilename = FlGenerateFilename (
    395         Signature, FILE_SUFFIX_ASL_CODE);
    396     if (!DisasmFilename)
    397     {
    398         fprintf (stderr, "Could not generate output filename\n");
    399         return (AE_ERROR);
    400     }
    401 
    402     AcpiUtStrlwr (DisasmFilename);
    403     if (!UtQueryForOverwrite (DisasmFilename))
    404     {
    405         return (AE_OK);
    406     }
    407 
    408     File = fopen (DisasmFilename, "w+");
    409     if (!File)
    410     {
    411         fprintf (stderr, "Could not open output file %s\n",
    412             DisasmFilename);
    413         return (AE_ERROR);
    414     }
    415 
    416     /* Emit the common file header */
    417 
    418     AcpiOsRedirectOutput (File);
    419 
    420     AcpiOsPrintf ("/*\n");
    421     AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * "));
    422 
    423     if (TableCount == 0)
    424     {
    425         AcpiOsPrintf (" * Template for [%4.4s] ACPI Table",
    426             Signature);
    427     }
    428     else
    429     {
    430         AcpiOsPrintf (" * Template for [%4.4s] and %u [SSDT] ACPI Tables",
    431             Signature, TableCount);
    432     }
    433 
    434     /* Dump the actual ACPI table */
    435 
    436     if (TableData)
    437     {
    438         /* Normal case, tables that appear in AcpiDmTableData */
    439 
    440         AcpiOsPrintf (" (static data table)\n");
    441 
    442         if (AslGbl_VerboseTemplates)
    443         {
    444             AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]"
    445                 "  FieldName : HexFieldValue\n */\n\n");
    446         }
    447         else
    448         {
    449             AcpiOsPrintf (" * Format: [ByteLength]"
    450                 "  FieldName : HexFieldValue\n */\n");
    451         }
    452 
    453         AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
    454             TableData->Template));
    455     }
    456     else
    457     {
    458         /* Special ACPI tables - DSDT, SSDT, OSDT, FACS, RSDP */
    459 
    460         AcpiOsPrintf (" (AML byte code table)\n");
    461         AcpiOsPrintf (" */\n");
    462 
    463         if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_DSDT))
    464         {
    465             Actual = DtEmitDefinitionBlock (
    466                 File, DisasmFilename, ACPI_SIG_DSDT, 1);
    467             if (Actual < 0)
    468             {
    469                 Status = AE_ERROR;
    470                 goto Cleanup;
    471             }
    472 
    473             /* Emit any requested SSDTs into the same file */
    474 
    475             for (i = 1; i <= TableCount; i++)
    476             {
    477                 Actual = DtEmitDefinitionBlock (
    478                     File, DisasmFilename, ACPI_SIG_SSDT, i + 1);
    479                 if (Actual < 0)
    480                 {
    481                     Status = AE_ERROR;
    482                     goto Cleanup;
    483                 }
    484             }
    485         }
    486         else if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT))
    487         {
    488             Actual = DtEmitDefinitionBlock (
    489                 File, DisasmFilename, ACPI_SIG_SSDT, 1);
    490             if (Actual < 0)
    491             {
    492                 Status = AE_ERROR;
    493                 goto Cleanup;
    494             }
    495         }
    496         else if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_OSDT))
    497         {
    498             Actual = DtEmitDefinitionBlock (
    499                 File, DisasmFilename, ACPI_SIG_OSDT, 1);
    500             if (Actual < 0)
    501             {
    502                 Status = AE_ERROR;
    503                 goto Cleanup;
    504             }
    505         }
    506         else if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_FACS))
    507         {
    508             AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
    509                 TemplateFacs));
    510         }
    511         else if (ACPI_COMPARE_NAMESEG (Signature, ACPI_RSDP_NAME))
    512         {
    513             AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
    514                 TemplateRsdp));
    515         }
    516         else
    517         {
    518             fprintf (stderr,
    519                 "%4.4s, Unrecognized ACPI table signature\n", Signature);
    520             Status = AE_ERROR;
    521             goto Cleanup;
    522         }
    523     }
    524 
    525     if (TableCount == 0)
    526     {
    527         fprintf (stderr,
    528             "Created ACPI table template for [%4.4s], "
    529             "written to \"%s\"\n",
    530             Signature, DisasmFilename);
    531     }
    532     else
    533     {
    534         fprintf (stderr,
    535             "Created ACPI table templates for [%4.4s] "
    536             "and %u [SSDT] in same file, written to \"%s\"\n",
    537             Signature, TableCount, DisasmFilename);
    538     }
    539 
    540 Cleanup:
    541     fclose (File);
    542     AcpiOsRedirectOutput (stdout);
    543     return (Status);
    544 }
    545 
    546 
    547 /*******************************************************************************
    548  *
    549  * FUNCTION:    DtEmitDefinitionBlock
    550  *
    551  * PARAMETERS:  File                - An open file for the block
    552  *              Filename            - Filename for same, for error msg(s)
    553  *              Signature           - ACPI signature for the block
    554  *              Instance            - Used for multiple SSDTs in the same file
    555  *
    556  * RETURN:      Status from fprintf
    557  *
    558  * DESCRIPTION: Emit the raw ASL for a complete Definition Block (DSDT or SSDT)
    559  *
    560  * Note: The AMLFileName parameter for DefinitionBlock is left as a NULL
    561  * string. This allows the compiler to create the output AML filename from
    562  * the input filename.
    563  *
    564  ******************************************************************************/
    565 
    566 static int
    567 DtEmitDefinitionBlock (
    568     FILE                    *File,
    569     char                    *Filename,
    570     char                    *Signature,
    571     UINT32                  Instance)
    572 {
    573     int                     Status;
    574 
    575 
    576     Status = fprintf (File,
    577         "DefinitionBlock (\"\", \"%4.4s\", 2, \"Intel\", \"_%4.4s_%.2X\", 0x00000001)\n"
    578         "{\n"
    579         "    Method (%2.2s%.2X)\n"
    580         "    {\n"
    581         "    }\n"
    582         "}\n\n",
    583         Signature, Signature, Instance, Signature, Instance);
    584 
    585     if (Status < 0)
    586     {
    587         fprintf (stderr,
    588             "Could not write %4.4s to output file %s\n",
    589             Signature, Filename);
    590     }
    591 
    592     return (Status);
    593 }
    594