1 /******************************************************************************
   2  *
   3  * Module Name: dttemplate - ACPI table template generation
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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 "aslcompiler.h"
  45 #include "acapps.h"
  46 #include "dtcompiler.h"
  47 #include "dttemplate.h" /* Contains the hex ACPI table templates */
  48 
  49 #define _COMPONENT          DT_COMPILER
  50         ACPI_MODULE_NAME    ("dttemplate")
  51 
  52 
  53 /* Local prototypes */
  54 
  55 static BOOLEAN
  56 AcpiUtIsSpecialTable (
  57     char                    *Signature);
  58 
  59 static ACPI_STATUS
  60 DtCreateOneTemplate (
  61     char                    *Signature,
  62     ACPI_DMTABLE_DATA       *TableData);
  63 
  64 static ACPI_STATUS
  65 DtCreateAllTemplates (
  66     void);
  67 
  68 
  69 /*******************************************************************************
  70  *
  71  * FUNCTION:    AcpiUtIsSpecialTable
  72  *
  73  * PARAMETERS:  Signature           - ACPI table signature
  74  *
  75  * RETURN:      TRUE if signature is a special ACPI table
  76  *
  77  * DESCRIPTION: Check for valid ACPI tables that are not in the main ACPI
  78  *              table data structure (AcpiDmTableData).
  79  *
  80  ******************************************************************************/
  81 
  82 static BOOLEAN
  83 AcpiUtIsSpecialTable (
  84     char                    *Signature)
  85 {
  86 
  87     if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
  88         ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) ||
  89         ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS) ||
  90         ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
  91     {
  92         return (TRUE);
  93     }
  94 
  95     return (FALSE);
  96 }
  97 
  98 
  99 /*******************************************************************************
 100  *
 101  * FUNCTION:    DtCreateTemplates
 102  *
 103  * PARAMETERS:  Signature           - ACPI table signature
 104  *
 105  * RETURN:      Status
 106  *
 107  * DESCRIPTION: Create one or more template files.
 108  *
 109  ******************************************************************************/
 110 
 111 ACPI_STATUS
 112 DtCreateTemplates (
 113     char                    *Signature)
 114 {
 115     ACPI_DMTABLE_DATA       *TableData;
 116     ACPI_STATUS             Status;
 117 
 118 
 119     AslInitializeGlobals ();
 120 
 121     /* Default (no signature) is DSDT */
 122 
 123     if (!Signature)
 124     {
 125         Signature = "DSDT";
 126         goto GetTemplate;
 127     }
 128 
 129     AcpiUtStrupr (Signature);
 130     if (!ACPI_STRCMP (Signature, "ALL") ||
 131         !ACPI_STRCMP (Signature, "*"))
 132     {
 133         /* Create all available/known templates */
 134 
 135         Status = DtCreateAllTemplates ();
 136         return (Status);
 137     }
 138 
 139     /*
 140      * Validate signature and get the template data:
 141      *  1) Signature must be 4 characters
 142      *  2) Signature must be a recognized ACPI table
 143      *  3) There must be a template associated with the signature
 144      */
 145     if (strlen (Signature) != ACPI_NAME_SIZE)
 146     {
 147         fprintf (stderr,
 148             "%s: Invalid ACPI table signature (length must be 4 characters)\n",
 149             Signature);
 150         return (AE_ERROR);
 151     }
 152 
 153     /*
 154      * Some slack for the two strange tables whose name is different than
 155      * their signatures: MADT->APIC and FADT->FACP.
 156      */
 157     if (!strcmp (Signature, "MADT"))
 158     {
 159         Signature = "APIC";
 160     }
 161     else if (!strcmp (Signature, "FADT"))
 162     {
 163         Signature = "FACP";
 164     }
 165 
 166 GetTemplate:
 167     TableData = AcpiDmGetTableData (Signature);
 168     if (TableData)
 169     {
 170         if (!TableData->Template)
 171         {
 172             fprintf (stderr, "%4.4s: No template available\n", Signature);
 173             return (AE_ERROR);
 174         }
 175     }
 176     else if (!AcpiUtIsSpecialTable (Signature))
 177     {
 178         fprintf (stderr,
 179             "%4.4s: Unrecognized ACPI table signature\n", Signature);
 180         return (AE_ERROR);
 181     }
 182 
 183     Status = AdInitialize ();
 184     if (ACPI_FAILURE (Status))
 185     {
 186         return (Status);
 187     }
 188 
 189     Status = DtCreateOneTemplate (Signature, TableData);
 190     return (Status);
 191 }
 192 
 193 
 194 /*******************************************************************************
 195  *
 196  * FUNCTION:    DtCreateAllTemplates
 197  *
 198  * PARAMETERS:  None
 199  *
 200  * RETURN:      Status
 201  *
 202  * DESCRIPTION: Create all currently defined template files
 203  *
 204  ******************************************************************************/
 205 
 206 static ACPI_STATUS
 207 DtCreateAllTemplates (
 208     void)
 209 {
 210     ACPI_DMTABLE_DATA       *TableData;
 211     ACPI_STATUS             Status;
 212 
 213 
 214     Status = AdInitialize ();
 215     if (ACPI_FAILURE (Status))
 216     {
 217         return (Status);
 218     }
 219 
 220     fprintf (stderr, "Creating all supported Template files\n");
 221 
 222     /* Walk entire ACPI table data structure */
 223 
 224     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
 225     {
 226         /* If table has a template, create the template file */
 227 
 228         if (TableData->Template)
 229         {
 230             Status = DtCreateOneTemplate (TableData->Signature,
 231                         TableData);
 232             if (ACPI_FAILURE (Status))
 233             {
 234                 return (Status);
 235             }
 236         }
 237     }
 238 
 239     /*
 240      * Create the special ACPI tables:
 241      * 1) DSDT/SSDT are AML tables, not data tables
 242      * 2) FACS and RSDP have non-standard headers
 243      */
 244     Status = DtCreateOneTemplate (ACPI_SIG_DSDT, NULL);
 245     if (ACPI_FAILURE (Status))
 246     {
 247         return (Status);
 248     }
 249 
 250     Status = DtCreateOneTemplate (ACPI_SIG_SSDT, NULL);
 251     if (ACPI_FAILURE (Status))
 252     {
 253         return (Status);
 254     }
 255 
 256     Status = DtCreateOneTemplate (ACPI_SIG_FACS, NULL);
 257     if (ACPI_FAILURE (Status))
 258     {
 259         return (Status);
 260     }
 261 
 262     Status = DtCreateOneTemplate (ACPI_RSDP_NAME, NULL);
 263     if (ACPI_FAILURE (Status))
 264     {
 265         return (Status);
 266     }
 267 
 268     return (AE_OK);
 269 }
 270 
 271 
 272 /*******************************************************************************
 273  *
 274  * FUNCTION:    DtCreateOneTemplate
 275  *
 276  * PARAMETERS:  Signature           - ACPI signature, NULL terminated.
 277  *              TableData           - Entry in ACPI table data structure.
 278  *                                    NULL if a special ACPI table.
 279  *
 280  * RETURN:      Status
 281  *
 282  * DESCRIPTION: Create one template source file for the requested ACPI table.
 283  *
 284  ******************************************************************************/
 285 
 286 static ACPI_STATUS
 287 DtCreateOneTemplate (
 288     char                    *Signature,
 289     ACPI_DMTABLE_DATA       *TableData)
 290 {
 291     char                    *DisasmFilename;
 292     FILE                    *File;
 293     ACPI_STATUS             Status = AE_OK;
 294     ACPI_SIZE               Actual;
 295 
 296 
 297     /* New file will have a .asl suffix */
 298 
 299     DisasmFilename = FlGenerateFilename (
 300         Signature, FILE_SUFFIX_ASL_CODE);
 301     if (!DisasmFilename)
 302     {
 303         fprintf (stderr, "Could not generate output filename\n");
 304         return (AE_ERROR);
 305     }
 306 
 307     /* Probably should prompt to overwrite the file */
 308 
 309     AcpiUtStrlwr (DisasmFilename);
 310     File = fopen (DisasmFilename, "w+");
 311     if (!File)
 312     {
 313         fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
 314         return (AE_ERROR);
 315     }
 316 
 317     /* Emit the common file header */
 318 
 319     AcpiOsRedirectOutput (File);
 320 
 321     AcpiOsPrintf ("/*\n");
 322     AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * "));
 323 
 324     AcpiOsPrintf (" * Template for [%4.4s] ACPI Table\n",
 325         Signature);
 326 
 327     /* Dump the actual ACPI table */
 328 
 329     if (TableData)
 330     {
 331         /* Normal case, tables that appear in AcpiDmTableData */
 332 
 333         if (Gbl_VerboseTemplates)
 334         {
 335             AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]"
 336                 "  FieldName : HexFieldValue\n */\n\n");
 337         }
 338         else
 339         {
 340             AcpiOsPrintf (" * Format: [ByteLength]"
 341                 "  FieldName : HexFieldValue\n */\n\n");
 342         }
 343 
 344         AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
 345             TableData->Template));
 346     }
 347     else
 348     {
 349         /* Special ACPI tables - DSDT, SSDT, FADT, RSDP */
 350 
 351         AcpiOsPrintf (" */\n\n");
 352         if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
 353         {
 354             Actual = fwrite (TemplateDsdt, 1, sizeof (TemplateDsdt) -1, File);
 355             if (Actual != sizeof (TemplateDsdt) -1)
 356             {
 357                 fprintf (stderr,
 358                     "Could not write to output file %s\n", DisasmFilename);
 359                 Status = AE_ERROR;
 360                 goto Cleanup;
 361             }
 362         }
 363         else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT))
 364         {
 365             Actual = fwrite (TemplateSsdt, 1, sizeof (TemplateSsdt) -1, File);
 366             if (Actual != sizeof (TemplateSsdt) -1)
 367             {
 368                 fprintf (stderr,
 369                     "Could not write to output file %s\n", DisasmFilename);
 370                 Status = AE_ERROR;
 371                 goto Cleanup;
 372             }
 373         }
 374         else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) /* FADT */
 375         {
 376             AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
 377                 TemplateFacs));
 378         }
 379         else if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
 380         {
 381             AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
 382                 TemplateRsdp));
 383         }
 384         else
 385         {
 386             fprintf (stderr,
 387                 "%4.4s, Unrecognized ACPI table signature\n", Signature);
 388             Status = AE_ERROR;
 389             goto Cleanup;
 390         }
 391     }
 392 
 393     fprintf (stderr,
 394         "Created ACPI table template for [%4.4s], written to \"%s\"\n",
 395         Signature, DisasmFilename);
 396 
 397 Cleanup:
 398     fclose (File);
 399     AcpiOsRedirectOutput (stdout);
 400     ACPI_FREE (DisasmFilename);
 401     return (Status);
 402 }