1209734Sjkim/******************************************************************************
2209734Sjkim *
3209734Sjkim * Module Name: dttemplate - ACPI table template generation
4209734Sjkim *
5209734Sjkim *****************************************************************************/
6209734Sjkim
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp.
9209734Sjkim * All rights reserved.
10209734Sjkim *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25209734Sjkim *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29209734Sjkim *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43209734Sjkim
44209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45209746Sjkim#include <contrib/dev/acpica/include/acapps.h>
46209746Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
47209746Sjkim#include <contrib/dev/acpica/compiler/dttemplate.h> /* Contains the hex ACPI table templates */
48209734Sjkim
49209734Sjkim#define _COMPONENT          DT_COMPILER
50209734Sjkim        ACPI_MODULE_NAME    ("dttemplate")
51209734Sjkim
52209734Sjkim
53209734Sjkim/* Local prototypes */
54209734Sjkim
55209734Sjkimstatic BOOLEAN
56209734SjkimAcpiUtIsSpecialTable (
57209734Sjkim    char                    *Signature);
58209734Sjkim
59209734Sjkimstatic ACPI_STATUS
60209734SjkimDtCreateOneTemplate (
61209734Sjkim    char                    *Signature,
62209734Sjkim    ACPI_DMTABLE_DATA       *TableData);
63209734Sjkim
64209734Sjkimstatic ACPI_STATUS
65209734SjkimDtCreateAllTemplates (
66209734Sjkim    void);
67209734Sjkim
68209734Sjkim
69209734Sjkim/*******************************************************************************
70209734Sjkim *
71209734Sjkim * FUNCTION:    AcpiUtIsSpecialTable
72209734Sjkim *
73209734Sjkim * PARAMETERS:  Signature           - ACPI table signature
74209734Sjkim *
75209734Sjkim * RETURN:      TRUE if signature is a special ACPI table
76209734Sjkim *
77209734Sjkim * DESCRIPTION: Check for valid ACPI tables that are not in the main ACPI
78209734Sjkim *              table data structure (AcpiDmTableData).
79209734Sjkim *
80209734Sjkim ******************************************************************************/
81209734Sjkim
82209734Sjkimstatic BOOLEAN
83209734SjkimAcpiUtIsSpecialTable (
84209734Sjkim    char                    *Signature)
85209734Sjkim{
86209734Sjkim
87209734Sjkim    if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
88209734Sjkim        ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) ||
89209734Sjkim        ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS) ||
90209734Sjkim        ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
91209734Sjkim    {
92209734Sjkim        return (TRUE);
93209734Sjkim    }
94209734Sjkim
95209734Sjkim    return (FALSE);
96209734Sjkim}
97209734Sjkim
98209734Sjkim
99209734Sjkim/*******************************************************************************
100209734Sjkim *
101209734Sjkim * FUNCTION:    DtCreateTemplates
102209734Sjkim *
103209734Sjkim * PARAMETERS:  Signature           - ACPI table signature
104209734Sjkim *
105209734Sjkim * RETURN:      Status
106209734Sjkim *
107209734Sjkim * DESCRIPTION: Create one or more template files.
108209734Sjkim *
109209734Sjkim ******************************************************************************/
110209734Sjkim
111209734SjkimACPI_STATUS
112209734SjkimDtCreateTemplates (
113209734Sjkim    char                    *Signature)
114209734Sjkim{
115209734Sjkim    ACPI_DMTABLE_DATA       *TableData;
116209734Sjkim    ACPI_STATUS             Status;
117209734Sjkim
118209734Sjkim
119209734Sjkim    AslInitializeGlobals ();
120209734Sjkim
121253690Sjkim    /* Default (no signature) is DSDT */
122209734Sjkim
123253690Sjkim    if (!Signature)
124253690Sjkim    {
125253690Sjkim        Signature = "DSDT";
126253690Sjkim        goto GetTemplate;
127253690Sjkim    }
128253690Sjkim
129253690Sjkim    AcpiUtStrupr (Signature);
130253690Sjkim    if (!ACPI_STRCMP (Signature, "ALL") ||
131220663Sjkim        !ACPI_STRCMP (Signature, "*"))
132209734Sjkim    {
133253690Sjkim        /* Create all available/known templates */
134253690Sjkim
135209734Sjkim        Status = DtCreateAllTemplates ();
136209734Sjkim        return (Status);
137209734Sjkim    }
138209734Sjkim
139209734Sjkim    /*
140209734Sjkim     * Validate signature and get the template data:
141209734Sjkim     *  1) Signature must be 4 characters
142209734Sjkim     *  2) Signature must be a recognized ACPI table
143209734Sjkim     *  3) There must be a template associated with the signature
144209734Sjkim     */
145209734Sjkim    if (strlen (Signature) != ACPI_NAME_SIZE)
146209734Sjkim    {
147253690Sjkim        fprintf (stderr,
148253690Sjkim            "%s: Invalid ACPI table signature (length must be 4 characters)\n",
149253690Sjkim            Signature);
150209734Sjkim        return (AE_ERROR);
151209734Sjkim    }
152209734Sjkim
153209734Sjkim    /*
154209734Sjkim     * Some slack for the two strange tables whose name is different than
155209734Sjkim     * their signatures: MADT->APIC and FADT->FACP.
156209734Sjkim     */
157209734Sjkim    if (!strcmp (Signature, "MADT"))
158209734Sjkim    {
159209734Sjkim        Signature = "APIC";
160209734Sjkim    }
161209734Sjkim    else if (!strcmp (Signature, "FADT"))
162209734Sjkim    {
163209734Sjkim        Signature = "FACP";
164209734Sjkim    }
165209734Sjkim
166253690SjkimGetTemplate:
167209734Sjkim    TableData = AcpiDmGetTableData (Signature);
168209734Sjkim    if (TableData)
169209734Sjkim    {
170209734Sjkim        if (!TableData->Template)
171209734Sjkim        {
172253690Sjkim            fprintf (stderr, "%4.4s: No template available\n", Signature);
173209734Sjkim            return (AE_ERROR);
174209734Sjkim        }
175209734Sjkim    }
176209734Sjkim    else if (!AcpiUtIsSpecialTable (Signature))
177209734Sjkim    {
178209734Sjkim        fprintf (stderr,
179253690Sjkim            "%4.4s: Unrecognized ACPI table signature\n", Signature);
180209734Sjkim        return (AE_ERROR);
181209734Sjkim    }
182209734Sjkim
183209734Sjkim    Status = AdInitialize ();
184209734Sjkim    if (ACPI_FAILURE (Status))
185209734Sjkim    {
186209734Sjkim        return (Status);
187209734Sjkim    }
188209734Sjkim
189209734Sjkim    Status = DtCreateOneTemplate (Signature, TableData);
190209734Sjkim    return (Status);
191209734Sjkim}
192209734Sjkim
193209734Sjkim
194209734Sjkim/*******************************************************************************
195209734Sjkim *
196209734Sjkim * FUNCTION:    DtCreateAllTemplates
197209734Sjkim *
198209734Sjkim * PARAMETERS:  None
199209734Sjkim *
200209734Sjkim * RETURN:      Status
201209734Sjkim *
202209734Sjkim * DESCRIPTION: Create all currently defined template files
203209734Sjkim *
204209734Sjkim ******************************************************************************/
205209734Sjkim
206209734Sjkimstatic ACPI_STATUS
207209734SjkimDtCreateAllTemplates (
208209734Sjkim    void)
209209734Sjkim{
210209734Sjkim    ACPI_DMTABLE_DATA       *TableData;
211209734Sjkim    ACPI_STATUS             Status;
212209734Sjkim
213209734Sjkim
214209734Sjkim    Status = AdInitialize ();
215209734Sjkim    if (ACPI_FAILURE (Status))
216209734Sjkim    {
217209734Sjkim        return (Status);
218209734Sjkim    }
219209734Sjkim
220209734Sjkim    fprintf (stderr, "Creating all supported Template files\n");
221209734Sjkim
222209734Sjkim    /* Walk entire ACPI table data structure */
223209734Sjkim
224209734Sjkim    for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
225209734Sjkim    {
226209734Sjkim        /* If table has a template, create the template file */
227209734Sjkim
228209734Sjkim        if (TableData->Template)
229209734Sjkim        {
230209734Sjkim            Status = DtCreateOneTemplate (TableData->Signature,
231209734Sjkim                        TableData);
232209734Sjkim            if (ACPI_FAILURE (Status))
233209734Sjkim            {
234209734Sjkim                return (Status);
235209734Sjkim            }
236209734Sjkim        }
237209734Sjkim    }
238209734Sjkim
239209734Sjkim    /*
240237412Sjkim     * Create the special ACPI tables:
241209734Sjkim     * 1) DSDT/SSDT are AML tables, not data tables
242209734Sjkim     * 2) FACS and RSDP have non-standard headers
243209734Sjkim     */
244209734Sjkim    Status = DtCreateOneTemplate (ACPI_SIG_DSDT, NULL);
245209734Sjkim    if (ACPI_FAILURE (Status))
246209734Sjkim    {
247209734Sjkim        return (Status);
248209734Sjkim    }
249209734Sjkim
250209734Sjkim    Status = DtCreateOneTemplate (ACPI_SIG_SSDT, NULL);
251209734Sjkim    if (ACPI_FAILURE (Status))
252209734Sjkim    {
253209734Sjkim        return (Status);
254209734Sjkim    }
255209734Sjkim
256209734Sjkim    Status = DtCreateOneTemplate (ACPI_SIG_FACS, NULL);
257209734Sjkim    if (ACPI_FAILURE (Status))
258209734Sjkim    {
259209734Sjkim        return (Status);
260209734Sjkim    }
261209734Sjkim
262209734Sjkim    Status = DtCreateOneTemplate (ACPI_RSDP_NAME, NULL);
263209734Sjkim    if (ACPI_FAILURE (Status))
264209734Sjkim    {
265209734Sjkim        return (Status);
266209734Sjkim    }
267209734Sjkim
268209734Sjkim    return (AE_OK);
269209734Sjkim}
270209734Sjkim
271209734Sjkim
272209734Sjkim/*******************************************************************************
273209734Sjkim *
274209734Sjkim * FUNCTION:    DtCreateOneTemplate
275209734Sjkim *
276209734Sjkim * PARAMETERS:  Signature           - ACPI signature, NULL terminated.
277209734Sjkim *              TableData           - Entry in ACPI table data structure.
278209734Sjkim *                                    NULL if a special ACPI table.
279209734Sjkim *
280209734Sjkim * RETURN:      Status
281209734Sjkim *
282209734Sjkim * DESCRIPTION: Create one template source file for the requested ACPI table.
283209734Sjkim *
284209734Sjkim ******************************************************************************/
285209734Sjkim
286209734Sjkimstatic ACPI_STATUS
287209734SjkimDtCreateOneTemplate (
288209734Sjkim    char                    *Signature,
289209734Sjkim    ACPI_DMTABLE_DATA       *TableData)
290209734Sjkim{
291209734Sjkim    char                    *DisasmFilename;
292209734Sjkim    FILE                    *File;
293209734Sjkim    ACPI_STATUS             Status = AE_OK;
294243347Sjkim    ACPI_SIZE               Actual;
295209734Sjkim
296209734Sjkim
297209734Sjkim    /* New file will have a .asl suffix */
298209734Sjkim
299209734Sjkim    DisasmFilename = FlGenerateFilename (
300209734Sjkim        Signature, FILE_SUFFIX_ASL_CODE);
301209734Sjkim    if (!DisasmFilename)
302209734Sjkim    {
303209734Sjkim        fprintf (stderr, "Could not generate output filename\n");
304209734Sjkim        return (AE_ERROR);
305209734Sjkim    }
306209734Sjkim
307209734Sjkim    /* Probably should prompt to overwrite the file */
308209734Sjkim
309209734Sjkim    AcpiUtStrlwr (DisasmFilename);
310209734Sjkim    File = fopen (DisasmFilename, "w+");
311209734Sjkim    if (!File)
312209734Sjkim    {
313209734Sjkim        fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
314209734Sjkim        return (AE_ERROR);
315209734Sjkim    }
316209734Sjkim
317209734Sjkim    /* Emit the common file header */
318209734Sjkim
319209734Sjkim    AcpiOsRedirectOutput (File);
320209734Sjkim
321213806Sjkim    AcpiOsPrintf ("/*\n");
322213806Sjkim    AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * "));
323213806Sjkim
324209734Sjkim    AcpiOsPrintf (" * Template for [%4.4s] ACPI Table\n",
325209734Sjkim        Signature);
326209734Sjkim
327209734Sjkim    /* Dump the actual ACPI table */
328209734Sjkim
329209734Sjkim    if (TableData)
330209734Sjkim    {
331209734Sjkim        /* Normal case, tables that appear in AcpiDmTableData */
332209734Sjkim
333209734Sjkim        if (Gbl_VerboseTemplates)
334209734Sjkim        {
335209734Sjkim            AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]"
336209734Sjkim                "  FieldName : HexFieldValue\n */\n\n");
337209734Sjkim        }
338209734Sjkim        else
339209734Sjkim        {
340209734Sjkim            AcpiOsPrintf (" * Format: [ByteLength]"
341209734Sjkim                "  FieldName : HexFieldValue\n */\n\n");
342209734Sjkim        }
343209734Sjkim
344209734Sjkim        AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
345209734Sjkim            TableData->Template));
346209734Sjkim    }
347209734Sjkim    else
348209734Sjkim    {
349243347Sjkim        /* Special ACPI tables - DSDT, SSDT, FADT, RSDP */
350209734Sjkim
351209734Sjkim        AcpiOsPrintf (" */\n\n");
352209734Sjkim        if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
353209734Sjkim        {
354243347Sjkim            Actual = fwrite (TemplateDsdt, 1, sizeof (TemplateDsdt) -1, File);
355243347Sjkim            if (Actual != sizeof (TemplateDsdt) -1)
356243347Sjkim            {
357243347Sjkim                fprintf (stderr,
358243347Sjkim                    "Could not write to output file %s\n", DisasmFilename);
359243347Sjkim                Status = AE_ERROR;
360243347Sjkim                goto Cleanup;
361243347Sjkim            }
362209734Sjkim        }
363209734Sjkim        else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT))
364209734Sjkim        {
365243347Sjkim            Actual = fwrite (TemplateSsdt, 1, sizeof (TemplateSsdt) -1, File);
366243347Sjkim            if (Actual != sizeof (TemplateSsdt) -1)
367243347Sjkim            {
368243347Sjkim                fprintf (stderr,
369243347Sjkim                    "Could not write to output file %s\n", DisasmFilename);
370243347Sjkim                Status = AE_ERROR;
371243347Sjkim                goto Cleanup;
372243347Sjkim            }
373209734Sjkim        }
374243347Sjkim        else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) /* FADT */
375209734Sjkim        {
376209734Sjkim            AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
377209734Sjkim                TemplateFacs));
378209734Sjkim        }
379209734Sjkim        else if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
380209734Sjkim        {
381209734Sjkim            AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
382209734Sjkim                TemplateRsdp));
383209734Sjkim        }
384209734Sjkim        else
385209734Sjkim        {
386209734Sjkim            fprintf (stderr,
387209734Sjkim                "%4.4s, Unrecognized ACPI table signature\n", Signature);
388243347Sjkim            Status = AE_ERROR;
389243347Sjkim            goto Cleanup;
390209734Sjkim        }
391209734Sjkim    }
392209734Sjkim
393209734Sjkim    fprintf (stderr,
394209734Sjkim        "Created ACPI table template for [%4.4s], written to \"%s\"\n",
395209734Sjkim        Signature, DisasmFilename);
396209734Sjkim
397243347SjkimCleanup:
398209734Sjkim    fclose (File);
399209734Sjkim    AcpiOsRedirectOutput (stdout);
400209734Sjkim    ACPI_FREE (DisasmFilename);
401209734Sjkim    return (Status);
402209734Sjkim}
403