dttemplate.c revision 284460
1/******************************************************************************
2 *
3 * Module Name: dttemplate - ACPI table template generation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, 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    const 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    const 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
166GetTemplate:
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
191
192    /* Shutdown ACPICA subsystem */
193
194    (void) AcpiTerminate ();
195    CmDeleteCaches ();
196    return (Status);
197}
198
199
200/*******************************************************************************
201 *
202 * FUNCTION:    DtCreateAllTemplates
203 *
204 * PARAMETERS:  None
205 *
206 * RETURN:      Status
207 *
208 * DESCRIPTION: Create all currently defined template files
209 *
210 ******************************************************************************/
211
212static ACPI_STATUS
213DtCreateAllTemplates (
214    void)
215{
216    const ACPI_DMTABLE_DATA *TableData;
217    ACPI_STATUS             Status;
218
219
220    Status = AdInitialize ();
221    if (ACPI_FAILURE (Status))
222    {
223        return (Status);
224    }
225
226    fprintf (stderr, "Creating all supported Template files\n");
227
228    /* Walk entire ACPI table data structure */
229
230    for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
231    {
232        /* If table has a template, create the template file */
233
234        if (TableData->Template)
235        {
236            Status = DtCreateOneTemplate (TableData->Signature,
237                        TableData);
238            if (ACPI_FAILURE (Status))
239            {
240                return (Status);
241            }
242        }
243    }
244
245    /*
246     * Create the special ACPI tables:
247     * 1) DSDT/SSDT are AML tables, not data tables
248     * 2) FACS and RSDP have non-standard headers
249     */
250    Status = DtCreateOneTemplate (ACPI_SIG_DSDT, NULL);
251    if (ACPI_FAILURE (Status))
252    {
253        return (Status);
254    }
255
256    Status = DtCreateOneTemplate (ACPI_SIG_SSDT, NULL);
257    if (ACPI_FAILURE (Status))
258    {
259        return (Status);
260    }
261
262    Status = DtCreateOneTemplate (ACPI_SIG_FACS, NULL);
263    if (ACPI_FAILURE (Status))
264    {
265        return (Status);
266    }
267
268    Status = DtCreateOneTemplate (ACPI_RSDP_NAME, NULL);
269    if (ACPI_FAILURE (Status))
270    {
271        return (Status);
272    }
273
274    return (AE_OK);
275}
276
277
278/*******************************************************************************
279 *
280 * FUNCTION:    DtCreateOneTemplate
281 *
282 * PARAMETERS:  Signature           - ACPI signature, NULL terminated.
283 *              TableData           - Entry in ACPI table data structure.
284 *                                    NULL if a special ACPI table.
285 *
286 * RETURN:      Status
287 *
288 * DESCRIPTION: Create one template source file for the requested ACPI table.
289 *
290 ******************************************************************************/
291
292static ACPI_STATUS
293DtCreateOneTemplate (
294    char                    *Signature,
295    const ACPI_DMTABLE_DATA  *TableData)
296{
297    char                    *DisasmFilename;
298    FILE                    *File;
299    ACPI_STATUS             Status = AE_OK;
300    ACPI_SIZE               Actual;
301
302
303    /* New file will have a .asl suffix */
304
305    DisasmFilename = FlGenerateFilename (
306        Signature, FILE_SUFFIX_ASL_CODE);
307    if (!DisasmFilename)
308    {
309        fprintf (stderr, "Could not generate output filename\n");
310        return (AE_ERROR);
311    }
312
313    /* Probably should prompt to overwrite the file */
314
315    AcpiUtStrlwr (DisasmFilename);
316    File = fopen (DisasmFilename, "w+");
317    if (!File)
318    {
319        fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
320        return (AE_ERROR);
321    }
322
323    /* Emit the common file header */
324
325    AcpiOsRedirectOutput (File);
326
327    AcpiOsPrintf ("/*\n");
328    AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * "));
329
330    AcpiOsPrintf (" * Template for [%4.4s] ACPI Table\n",
331        Signature);
332
333    /* Dump the actual ACPI table */
334
335    if (TableData)
336    {
337        /* Normal case, tables that appear in AcpiDmTableData */
338
339        if (Gbl_VerboseTemplates)
340        {
341            AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]"
342                "  FieldName : HexFieldValue\n */\n\n");
343        }
344        else
345        {
346            AcpiOsPrintf (" * Format: [ByteLength]"
347                "  FieldName : HexFieldValue\n */\n\n");
348        }
349
350        AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
351            TableData->Template));
352    }
353    else
354    {
355        /* Special ACPI tables - DSDT, SSDT, FADT, RSDP */
356
357        AcpiOsPrintf (" */\n\n");
358        if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
359        {
360            Actual = fwrite (TemplateDsdt, 1, sizeof (TemplateDsdt) -1, File);
361            if (Actual != sizeof (TemplateDsdt) -1)
362            {
363                fprintf (stderr,
364                    "Could not write to output file %s\n", DisasmFilename);
365                Status = AE_ERROR;
366                goto Cleanup;
367            }
368        }
369        else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT))
370        {
371            Actual = fwrite (TemplateSsdt, 1, sizeof (TemplateSsdt) -1, File);
372            if (Actual != sizeof (TemplateSsdt) -1)
373            {
374                fprintf (stderr,
375                    "Could not write to output file %s\n", DisasmFilename);
376                Status = AE_ERROR;
377                goto Cleanup;
378            }
379        }
380        else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) /* FADT */
381        {
382            AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
383                TemplateFacs));
384        }
385        else if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
386        {
387            AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
388                TemplateRsdp));
389        }
390        else
391        {
392            fprintf (stderr,
393                "%4.4s, Unrecognized ACPI table signature\n", Signature);
394            Status = AE_ERROR;
395            goto Cleanup;
396        }
397    }
398
399    fprintf (stderr,
400        "Created ACPI table template for [%4.4s], written to \"%s\"\n",
401        Signature, DisasmFilename);
402
403Cleanup:
404    fclose (File);
405    AcpiOsRedirectOutput (stdout);
406    return (Status);
407}
408