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