1209734Sjkim/******************************************************************************
2209734Sjkim *
3209734Sjkim * Module Name: dttemplate - ACPI table template generation
4209734Sjkim *
5209734Sjkim *****************************************************************************/
6209734Sjkim
7217365Sjkim/*
8217365Sjkim * Copyright (C) 2000 - 2011, 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    AcpiUtStrupr (Signature);
121209734Sjkim
122209734Sjkim    /* Create all known templates if requested */
123209734Sjkim
124220663Sjkim    if (!ACPI_STRNCMP (Signature, "ALL", 3) ||
125220663Sjkim        !ACPI_STRCMP (Signature, "*"))
126209734Sjkim    {
127209734Sjkim        Status = DtCreateAllTemplates ();
128209734Sjkim        return (Status);
129209734Sjkim    }
130209734Sjkim
131209734Sjkim    /*
132209734Sjkim     * Validate signature and get the template data:
133209734Sjkim     *  1) Signature must be 4 characters
134209734Sjkim     *  2) Signature must be a recognized ACPI table
135209734Sjkim     *  3) There must be a template associated with the signature
136209734Sjkim     */
137209734Sjkim    if (strlen (Signature) != ACPI_NAME_SIZE)
138209734Sjkim    {
139209734Sjkim        fprintf (stderr, "%s, Invalid ACPI table signature\n", Signature);
140209734Sjkim        return (AE_ERROR);
141209734Sjkim    }
142209734Sjkim
143209734Sjkim    /*
144209734Sjkim     * Some slack for the two strange tables whose name is different than
145209734Sjkim     * their signatures: MADT->APIC and FADT->FACP.
146209734Sjkim     */
147209734Sjkim    if (!strcmp (Signature, "MADT"))
148209734Sjkim    {
149209734Sjkim        Signature = "APIC";
150209734Sjkim    }
151209734Sjkim    else if (!strcmp (Signature, "FADT"))
152209734Sjkim    {
153209734Sjkim        Signature = "FACP";
154209734Sjkim    }
155209734Sjkim
156209734Sjkim    TableData = AcpiDmGetTableData (Signature);
157209734Sjkim    if (TableData)
158209734Sjkim    {
159209734Sjkim        if (!TableData->Template)
160209734Sjkim        {
161209734Sjkim            fprintf (stderr, "%4.4s, No template available\n", Signature);
162209734Sjkim            return (AE_ERROR);
163209734Sjkim        }
164209734Sjkim    }
165209734Sjkim    else if (!AcpiUtIsSpecialTable (Signature))
166209734Sjkim    {
167209734Sjkim        fprintf (stderr,
168209734Sjkim            "%4.4s, Unrecognized ACPI table signature\n", Signature);
169209734Sjkim        return (AE_ERROR);
170209734Sjkim    }
171209734Sjkim
172209734Sjkim    Status = AdInitialize ();
173209734Sjkim    if (ACPI_FAILURE (Status))
174209734Sjkim    {
175209734Sjkim        return (Status);
176209734Sjkim    }
177209734Sjkim
178209734Sjkim    Status = DtCreateOneTemplate (Signature, TableData);
179209734Sjkim    return (Status);
180209734Sjkim}
181209734Sjkim
182209734Sjkim
183209734Sjkim/*******************************************************************************
184209734Sjkim *
185209734Sjkim * FUNCTION:    DtCreateAllTemplates
186209734Sjkim *
187209734Sjkim * PARAMETERS:  None
188209734Sjkim *
189209734Sjkim * RETURN:      Status
190209734Sjkim *
191209734Sjkim * DESCRIPTION: Create all currently defined template files
192209734Sjkim *
193209734Sjkim ******************************************************************************/
194209734Sjkim
195209734Sjkimstatic ACPI_STATUS
196209734SjkimDtCreateAllTemplates (
197209734Sjkim    void)
198209734Sjkim{
199209734Sjkim    ACPI_DMTABLE_DATA       *TableData;
200209734Sjkim    ACPI_STATUS             Status;
201209734Sjkim
202209734Sjkim
203209734Sjkim    Status = AdInitialize ();
204209734Sjkim    if (ACPI_FAILURE (Status))
205209734Sjkim    {
206209734Sjkim        return (Status);
207209734Sjkim    }
208209734Sjkim
209209734Sjkim    fprintf (stderr, "Creating all supported Template files\n");
210209734Sjkim
211209734Sjkim    /* Walk entire ACPI table data structure */
212209734Sjkim
213209734Sjkim    for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
214209734Sjkim    {
215209734Sjkim        /* If table has a template, create the template file */
216209734Sjkim
217209734Sjkim        if (TableData->Template)
218209734Sjkim        {
219209734Sjkim            Status = DtCreateOneTemplate (TableData->Signature,
220209734Sjkim                        TableData);
221209734Sjkim            if (ACPI_FAILURE (Status))
222209734Sjkim            {
223209734Sjkim                return (Status);
224209734Sjkim            }
225209734Sjkim        }
226209734Sjkim    }
227209734Sjkim
228209734Sjkim    /*
229209734Sjkim     * Create the "special ACPI tables:
230209734Sjkim     * 1) DSDT/SSDT are AML tables, not data tables
231209734Sjkim     * 2) FACS and RSDP have non-standard headers
232209734Sjkim     */
233209734Sjkim    Status = DtCreateOneTemplate (ACPI_SIG_DSDT, NULL);
234209734Sjkim    if (ACPI_FAILURE (Status))
235209734Sjkim    {
236209734Sjkim        return (Status);
237209734Sjkim    }
238209734Sjkim
239209734Sjkim    Status = DtCreateOneTemplate (ACPI_SIG_SSDT, NULL);
240209734Sjkim    if (ACPI_FAILURE (Status))
241209734Sjkim    {
242209734Sjkim        return (Status);
243209734Sjkim    }
244209734Sjkim
245209734Sjkim    Status = DtCreateOneTemplate (ACPI_SIG_FACS, NULL);
246209734Sjkim    if (ACPI_FAILURE (Status))
247209734Sjkim    {
248209734Sjkim        return (Status);
249209734Sjkim    }
250209734Sjkim
251209734Sjkim    Status = DtCreateOneTemplate (ACPI_RSDP_NAME, NULL);
252209734Sjkim    if (ACPI_FAILURE (Status))
253209734Sjkim    {
254209734Sjkim        return (Status);
255209734Sjkim    }
256209734Sjkim
257209734Sjkim    return (AE_OK);
258209734Sjkim}
259209734Sjkim
260209734Sjkim
261209734Sjkim/*******************************************************************************
262209734Sjkim *
263209734Sjkim * FUNCTION:    DtCreateOneTemplate
264209734Sjkim *
265209734Sjkim * PARAMETERS:  Signature           - ACPI signature, NULL terminated.
266209734Sjkim *              TableData           - Entry in ACPI table data structure.
267209734Sjkim *                                    NULL if a special ACPI table.
268209734Sjkim *
269209734Sjkim * RETURN:      Status
270209734Sjkim *
271209734Sjkim * DESCRIPTION: Create one template source file for the requested ACPI table.
272209734Sjkim *
273209734Sjkim ******************************************************************************/
274209734Sjkim
275209734Sjkimstatic ACPI_STATUS
276209734SjkimDtCreateOneTemplate (
277209734Sjkim    char                    *Signature,
278209734Sjkim    ACPI_DMTABLE_DATA       *TableData)
279209734Sjkim{
280209734Sjkim    char                    *DisasmFilename;
281209734Sjkim    FILE                    *File;
282209734Sjkim    ACPI_STATUS             Status = AE_OK;
283209734Sjkim
284209734Sjkim
285209734Sjkim    /* New file will have a .asl suffix */
286209734Sjkim
287209734Sjkim    DisasmFilename = FlGenerateFilename (
288209734Sjkim        Signature, FILE_SUFFIX_ASL_CODE);
289209734Sjkim    if (!DisasmFilename)
290209734Sjkim    {
291209734Sjkim        fprintf (stderr, "Could not generate output filename\n");
292209734Sjkim        return (AE_ERROR);
293209734Sjkim    }
294209734Sjkim
295209734Sjkim    /* Probably should prompt to overwrite the file */
296209734Sjkim
297209734Sjkim    AcpiUtStrlwr (DisasmFilename);
298209734Sjkim    File = fopen (DisasmFilename, "w+");
299209734Sjkim    if (!File)
300209734Sjkim    {
301209734Sjkim        fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
302209734Sjkim        return (AE_ERROR);
303209734Sjkim    }
304209734Sjkim
305209734Sjkim    /* Emit the common file header */
306209734Sjkim
307209734Sjkim    AcpiOsRedirectOutput (File);
308209734Sjkim
309213806Sjkim    AcpiOsPrintf ("/*\n");
310213806Sjkim    AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * "));
311213806Sjkim
312209734Sjkim    AcpiOsPrintf (" * Template for [%4.4s] ACPI Table\n",
313209734Sjkim        Signature);
314209734Sjkim
315209734Sjkim    /* Dump the actual ACPI table */
316209734Sjkim
317209734Sjkim    if (TableData)
318209734Sjkim    {
319209734Sjkim        /* Normal case, tables that appear in AcpiDmTableData */
320209734Sjkim
321209734Sjkim        if (Gbl_VerboseTemplates)
322209734Sjkim        {
323209734Sjkim            AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]"
324209734Sjkim                "  FieldName : HexFieldValue\n */\n\n");
325209734Sjkim        }
326209734Sjkim        else
327209734Sjkim        {
328209734Sjkim            AcpiOsPrintf (" * Format: [ByteLength]"
329209734Sjkim                "  FieldName : HexFieldValue\n */\n\n");
330209734Sjkim        }
331209734Sjkim
332209734Sjkim        AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
333209734Sjkim            TableData->Template));
334209734Sjkim    }
335209734Sjkim    else
336209734Sjkim    {
337209734Sjkim        /* Special ACPI tables - DSDT, SSDT, FACS, RSDP */
338209734Sjkim
339209734Sjkim        AcpiOsPrintf (" */\n\n");
340209734Sjkim        if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
341209734Sjkim        {
342209734Sjkim            fwrite (TemplateDsdt, sizeof (TemplateDsdt) -1, 1, File);
343209734Sjkim        }
344209734Sjkim        else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT))
345209734Sjkim        {
346209734Sjkim            fwrite (TemplateSsdt, sizeof (TemplateSsdt) -1, 1, File);
347209734Sjkim        }
348209734Sjkim        else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
349209734Sjkim        {
350209734Sjkim            AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
351209734Sjkim                TemplateFacs));
352209734Sjkim        }
353209734Sjkim        else if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
354209734Sjkim        {
355209734Sjkim            AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
356209734Sjkim                TemplateRsdp));
357209734Sjkim        }
358209734Sjkim        else
359209734Sjkim        {
360209734Sjkim            fprintf (stderr,
361209734Sjkim                "%4.4s, Unrecognized ACPI table signature\n", Signature);
362209734Sjkim            return (AE_ERROR);
363209734Sjkim        }
364209734Sjkim    }
365209734Sjkim
366209734Sjkim    fprintf (stderr,
367209734Sjkim        "Created ACPI table template for [%4.4s], written to \"%s\"\n",
368209734Sjkim        Signature, DisasmFilename);
369209734Sjkim
370209734Sjkim    fclose (File);
371209734Sjkim    AcpiOsRedirectOutput (stdout);
372209734Sjkim    ACPI_FREE (DisasmFilename);
373209734Sjkim    return (Status);
374209734Sjkim}
375