xref: /illumos-gate/usr/src/cmd/acpi/iasl/dttemplate.c (revision bc36eafd)
1*bc36eafdSMike Gerdts /******************************************************************************
2*bc36eafdSMike Gerdts  *
3*bc36eafdSMike Gerdts  * Module Name: dttemplate - ACPI table template generation
4*bc36eafdSMike Gerdts  *
5*bc36eafdSMike Gerdts  *****************************************************************************/
6*bc36eafdSMike Gerdts 
7*bc36eafdSMike Gerdts /*
8*bc36eafdSMike Gerdts  * Copyright (C) 2000 - 2016, Intel Corp.
9*bc36eafdSMike Gerdts  * All rights reserved.
10*bc36eafdSMike Gerdts  *
11*bc36eafdSMike Gerdts  * Redistribution and use in source and binary forms, with or without
12*bc36eafdSMike Gerdts  * modification, are permitted provided that the following conditions
13*bc36eafdSMike Gerdts  * are met:
14*bc36eafdSMike Gerdts  * 1. Redistributions of source code must retain the above copyright
15*bc36eafdSMike Gerdts  *    notice, this list of conditions, and the following disclaimer,
16*bc36eafdSMike Gerdts  *    without modification.
17*bc36eafdSMike Gerdts  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*bc36eafdSMike Gerdts  *    substantially similar to the "NO WARRANTY" disclaimer below
19*bc36eafdSMike Gerdts  *    ("Disclaimer") and any redistribution must be conditioned upon
20*bc36eafdSMike Gerdts  *    including a substantially similar Disclaimer requirement for further
21*bc36eafdSMike Gerdts  *    binary redistribution.
22*bc36eafdSMike Gerdts  * 3. Neither the names of the above-listed copyright holders nor the names
23*bc36eafdSMike Gerdts  *    of any contributors may be used to endorse or promote products derived
24*bc36eafdSMike Gerdts  *    from this software without specific prior written permission.
25*bc36eafdSMike Gerdts  *
26*bc36eafdSMike Gerdts  * Alternatively, this software may be distributed under the terms of the
27*bc36eafdSMike Gerdts  * GNU General Public License ("GPL") version 2 as published by the Free
28*bc36eafdSMike Gerdts  * Software Foundation.
29*bc36eafdSMike Gerdts  *
30*bc36eafdSMike Gerdts  * NO WARRANTY
31*bc36eafdSMike Gerdts  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*bc36eafdSMike Gerdts  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*bc36eafdSMike Gerdts  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*bc36eafdSMike Gerdts  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*bc36eafdSMike Gerdts  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*bc36eafdSMike Gerdts  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*bc36eafdSMike Gerdts  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*bc36eafdSMike Gerdts  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*bc36eafdSMike Gerdts  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*bc36eafdSMike Gerdts  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*bc36eafdSMike Gerdts  * POSSIBILITY OF SUCH DAMAGES.
42*bc36eafdSMike Gerdts  */
43*bc36eafdSMike Gerdts 
44*bc36eafdSMike Gerdts #include "aslcompiler.h"
45*bc36eafdSMike Gerdts #include "acapps.h"
46*bc36eafdSMike Gerdts #include "dtcompiler.h"
47*bc36eafdSMike Gerdts #include "dttemplate.h" /* Contains the hex ACPI table templates */
48*bc36eafdSMike Gerdts 
49*bc36eafdSMike Gerdts #define _COMPONENT          DT_COMPILER
50*bc36eafdSMike Gerdts         ACPI_MODULE_NAME    ("dttemplate")
51*bc36eafdSMike Gerdts 
52*bc36eafdSMike Gerdts 
53*bc36eafdSMike Gerdts /* Local prototypes */
54*bc36eafdSMike Gerdts 
55*bc36eafdSMike Gerdts static BOOLEAN
56*bc36eafdSMike Gerdts AcpiUtIsSpecialTable (
57*bc36eafdSMike Gerdts     char                    *Signature);
58*bc36eafdSMike Gerdts 
59*bc36eafdSMike Gerdts static ACPI_STATUS
60*bc36eafdSMike Gerdts DtCreateOneTemplateFile (
61*bc36eafdSMike Gerdts     char                    *Signature,
62*bc36eafdSMike Gerdts     UINT32                  TableCount);
63*bc36eafdSMike Gerdts 
64*bc36eafdSMike Gerdts static ACPI_STATUS
65*bc36eafdSMike Gerdts DtCreateOneTemplate (
66*bc36eafdSMike Gerdts     char                    *Signature,
67*bc36eafdSMike Gerdts     UINT32                  TableCount,
68*bc36eafdSMike Gerdts     const ACPI_DMTABLE_DATA *TableData);
69*bc36eafdSMike Gerdts 
70*bc36eafdSMike Gerdts static ACPI_STATUS
71*bc36eafdSMike Gerdts DtCreateAllTemplates (
72*bc36eafdSMike Gerdts     void);
73*bc36eafdSMike Gerdts 
74*bc36eafdSMike Gerdts static int
75*bc36eafdSMike Gerdts DtEmitDefinitionBlock (
76*bc36eafdSMike Gerdts     FILE                    *File,
77*bc36eafdSMike Gerdts     char                    *Filename,
78*bc36eafdSMike Gerdts     char                    *Signature,
79*bc36eafdSMike Gerdts     UINT32                  Instance);
80*bc36eafdSMike Gerdts 
81*bc36eafdSMike Gerdts 
82*bc36eafdSMike Gerdts /*******************************************************************************
83*bc36eafdSMike Gerdts  *
84*bc36eafdSMike Gerdts  * FUNCTION:    AcpiUtIsSpecialTable
85*bc36eafdSMike Gerdts  *
86*bc36eafdSMike Gerdts  * PARAMETERS:  Signature           - ACPI table signature
87*bc36eafdSMike Gerdts  *
88*bc36eafdSMike Gerdts  * RETURN:      TRUE if signature is a special ACPI table
89*bc36eafdSMike Gerdts  *
90*bc36eafdSMike Gerdts  * DESCRIPTION: Check for valid ACPI tables that are not in the main ACPI
91*bc36eafdSMike Gerdts  *              table data structure (AcpiDmTableData).
92*bc36eafdSMike Gerdts  *
93*bc36eafdSMike Gerdts  ******************************************************************************/
94*bc36eafdSMike Gerdts 
95*bc36eafdSMike Gerdts static BOOLEAN
96*bc36eafdSMike Gerdts AcpiUtIsSpecialTable (
97*bc36eafdSMike Gerdts     char                    *Signature)
98*bc36eafdSMike Gerdts {
99*bc36eafdSMike Gerdts 
100*bc36eafdSMike Gerdts     if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
101*bc36eafdSMike Gerdts         ACPI_COMPARE_NAME (Signature, ACPI_SIG_OSDT) ||
102*bc36eafdSMike Gerdts         ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) ||
103*bc36eafdSMike Gerdts         ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS) ||
104*bc36eafdSMike Gerdts         ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
105*bc36eafdSMike Gerdts     {
106*bc36eafdSMike Gerdts         return (TRUE);
107*bc36eafdSMike Gerdts     }
108*bc36eafdSMike Gerdts 
109*bc36eafdSMike Gerdts     return (FALSE);
110*bc36eafdSMike Gerdts }
111*bc36eafdSMike Gerdts 
112*bc36eafdSMike Gerdts 
113*bc36eafdSMike Gerdts /*******************************************************************************
114*bc36eafdSMike Gerdts  *
115*bc36eafdSMike Gerdts  * FUNCTION:    DtCreateTemplates
116*bc36eafdSMike Gerdts  *
117*bc36eafdSMike Gerdts  * PARAMETERS:  argv                - Standard command line arguments
118*bc36eafdSMike Gerdts  *
119*bc36eafdSMike Gerdts  * RETURN:      Status
120*bc36eafdSMike Gerdts  *
121*bc36eafdSMike Gerdts  * DESCRIPTION: Create one or more template files.
122*bc36eafdSMike Gerdts  *
123*bc36eafdSMike Gerdts  ******************************************************************************/
124*bc36eafdSMike Gerdts 
125*bc36eafdSMike Gerdts ACPI_STATUS
126*bc36eafdSMike Gerdts DtCreateTemplates (
127*bc36eafdSMike Gerdts     char                    **argv)
128*bc36eafdSMike Gerdts {
129*bc36eafdSMike Gerdts     char                    *Signature;
130*bc36eafdSMike Gerdts     char                    *End;
131*bc36eafdSMike Gerdts     unsigned long           TableCount;
132*bc36eafdSMike Gerdts     ACPI_STATUS             Status = AE_OK;
133*bc36eafdSMike Gerdts 
134*bc36eafdSMike Gerdts 
135*bc36eafdSMike Gerdts     AslInitializeGlobals ();
136*bc36eafdSMike Gerdts 
137*bc36eafdSMike Gerdts     Status = AdInitialize ();
138*bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
139*bc36eafdSMike Gerdts     {
140*bc36eafdSMike Gerdts         return (Status);
141*bc36eafdSMike Gerdts     }
142*bc36eafdSMike Gerdts 
143*bc36eafdSMike Gerdts     /*
144*bc36eafdSMike Gerdts      * Special cases for DSDT, ALL, and '*'
145*bc36eafdSMike Gerdts      */
146*bc36eafdSMike Gerdts 
147*bc36eafdSMike Gerdts     /* Default (no signature option) is DSDT */
148*bc36eafdSMike Gerdts 
149*bc36eafdSMike Gerdts     if (AcpiGbl_Optind < 3)
150*bc36eafdSMike Gerdts     {
151*bc36eafdSMike Gerdts         Status = DtCreateOneTemplateFile (ACPI_SIG_DSDT, 0);
152*bc36eafdSMike Gerdts         goto Exit;
153*bc36eafdSMike Gerdts     }
154*bc36eafdSMike Gerdts 
155*bc36eafdSMike Gerdts     AcpiGbl_Optind--;
156*bc36eafdSMike Gerdts     Signature = argv[AcpiGbl_Optind];
157*bc36eafdSMike Gerdts     AcpiUtStrupr (Signature);
158*bc36eafdSMike Gerdts 
159*bc36eafdSMike Gerdts     /*
160*bc36eafdSMike Gerdts      * Multiple SSDT support (-T <ssdt count>)
161*bc36eafdSMike Gerdts      */
162*bc36eafdSMike Gerdts     TableCount = strtoul (Signature, &End, 0);
163*bc36eafdSMike Gerdts     if (Signature != End)
164*bc36eafdSMike Gerdts     {
165*bc36eafdSMike Gerdts         /* The count is used for table ID and method name - max is 254(+1) */
166*bc36eafdSMike Gerdts 
167*bc36eafdSMike Gerdts         if (TableCount > 254)
168*bc36eafdSMike Gerdts         {
169*bc36eafdSMike Gerdts             fprintf (stderr, "%u SSDTs requested, maximum is 254\n",
170*bc36eafdSMike Gerdts                 (unsigned int) TableCount);
171*bc36eafdSMike Gerdts 
172*bc36eafdSMike Gerdts             Status = AE_LIMIT;
173*bc36eafdSMike Gerdts             goto Exit;
174*bc36eafdSMike Gerdts         }
175*bc36eafdSMike Gerdts 
176*bc36eafdSMike Gerdts         Status = DtCreateOneTemplateFile (ACPI_SIG_DSDT, TableCount);
177*bc36eafdSMike Gerdts         goto Exit;
178*bc36eafdSMike Gerdts     }
179*bc36eafdSMike Gerdts 
180*bc36eafdSMike Gerdts     if (!strcmp (Signature, "ALL"))
181*bc36eafdSMike Gerdts     {
182*bc36eafdSMike Gerdts         /* Create all available/known templates */
183*bc36eafdSMike Gerdts 
184*bc36eafdSMike Gerdts         Status = DtCreateAllTemplates ();
185*bc36eafdSMike Gerdts         goto Exit;
186*bc36eafdSMike Gerdts     }
187*bc36eafdSMike Gerdts 
188*bc36eafdSMike Gerdts     /*
189*bc36eafdSMike Gerdts      * Normal case: Create template for each signature
190*bc36eafdSMike Gerdts      */
191*bc36eafdSMike Gerdts     while (argv[AcpiGbl_Optind])
192*bc36eafdSMike Gerdts     {
193*bc36eafdSMike Gerdts         Signature = argv[AcpiGbl_Optind];
194*bc36eafdSMike Gerdts         AcpiUtStrupr (Signature);
195*bc36eafdSMike Gerdts 
196*bc36eafdSMike Gerdts         Status = DtCreateOneTemplateFile (Signature, 0);
197*bc36eafdSMike Gerdts         if (ACPI_FAILURE (Status))
198*bc36eafdSMike Gerdts         {
199*bc36eafdSMike Gerdts             goto Exit;
200*bc36eafdSMike Gerdts         }
201*bc36eafdSMike Gerdts 
202*bc36eafdSMike Gerdts         AcpiGbl_Optind++;
203*bc36eafdSMike Gerdts     }
204*bc36eafdSMike Gerdts 
205*bc36eafdSMike Gerdts 
206*bc36eafdSMike Gerdts Exit:
207*bc36eafdSMike Gerdts     /* Shutdown ACPICA subsystem */
208*bc36eafdSMike Gerdts 
209*bc36eafdSMike Gerdts     (void) AcpiTerminate ();
210*bc36eafdSMike Gerdts     CmDeleteCaches ();
211*bc36eafdSMike Gerdts     return (Status);
212*bc36eafdSMike Gerdts }
213*bc36eafdSMike Gerdts 
214*bc36eafdSMike Gerdts 
215*bc36eafdSMike Gerdts /*******************************************************************************
216*bc36eafdSMike Gerdts  *
217*bc36eafdSMike Gerdts  * FUNCTION:    DtCreateOneTemplateFile
218*bc36eafdSMike Gerdts  *
219*bc36eafdSMike Gerdts  * PARAMETERS:  Signature           - ACPI table signature
220*bc36eafdSMike Gerdts  *
221*bc36eafdSMike Gerdts  * RETURN:      Status
222*bc36eafdSMike Gerdts  *
223*bc36eafdSMike Gerdts  * DESCRIPTION: Create one template file of the requested signature.
224*bc36eafdSMike Gerdts  *
225*bc36eafdSMike Gerdts  ******************************************************************************/
226*bc36eafdSMike Gerdts 
227*bc36eafdSMike Gerdts static ACPI_STATUS
228*bc36eafdSMike Gerdts DtCreateOneTemplateFile (
229*bc36eafdSMike Gerdts     char                    *Signature,
230*bc36eafdSMike Gerdts     UINT32                  TableCount)
231*bc36eafdSMike Gerdts {
232*bc36eafdSMike Gerdts     const ACPI_DMTABLE_DATA *TableData;
233*bc36eafdSMike Gerdts     ACPI_STATUS             Status;
234*bc36eafdSMike Gerdts 
235*bc36eafdSMike Gerdts 
236*bc36eafdSMike Gerdts     /*
237*bc36eafdSMike Gerdts      * Validate signature and get the template data:
238*bc36eafdSMike Gerdts      *  1) Signature must be 4 characters
239*bc36eafdSMike Gerdts      *  2) Signature must be a recognized ACPI table
240*bc36eafdSMike Gerdts      *  3) There must be a template associated with the signature
241*bc36eafdSMike Gerdts      */
242*bc36eafdSMike Gerdts     if (strlen (Signature) != ACPI_NAME_SIZE)
243*bc36eafdSMike Gerdts     {
244*bc36eafdSMike Gerdts         fprintf (stderr,
245*bc36eafdSMike Gerdts             "%s: Invalid ACPI table signature "
246*bc36eafdSMike Gerdts             "(length must be 4 characters)\n", Signature);
247*bc36eafdSMike Gerdts         return (AE_ERROR);
248*bc36eafdSMike Gerdts     }
249*bc36eafdSMike Gerdts 
250*bc36eafdSMike Gerdts     /*
251*bc36eafdSMike Gerdts      * Some slack for the two strange tables whose name is different than
252*bc36eafdSMike Gerdts      * their signatures: MADT->APIC and FADT->FACP.
253*bc36eafdSMike Gerdts      */
254*bc36eafdSMike Gerdts     if (!strcmp (Signature, "MADT"))
255*bc36eafdSMike Gerdts     {
256*bc36eafdSMike Gerdts         Signature = "APIC";
257*bc36eafdSMike Gerdts     }
258*bc36eafdSMike Gerdts     else if (!strcmp (Signature, "FADT"))
259*bc36eafdSMike Gerdts     {
260*bc36eafdSMike Gerdts         Signature = "FACP";
261*bc36eafdSMike Gerdts     }
262*bc36eafdSMike Gerdts 
263*bc36eafdSMike Gerdts     /* TableData will point to the template */
264*bc36eafdSMike Gerdts 
265*bc36eafdSMike Gerdts     TableData = AcpiDmGetTableData (Signature);
266*bc36eafdSMike Gerdts     if (TableData)
267*bc36eafdSMike Gerdts     {
268*bc36eafdSMike Gerdts         if (!TableData->Template)
269*bc36eafdSMike Gerdts         {
270*bc36eafdSMike Gerdts             fprintf (stderr, "%4.4s: No template available\n", Signature);
271*bc36eafdSMike Gerdts             return (AE_ERROR);
272*bc36eafdSMike Gerdts         }
273*bc36eafdSMike Gerdts     }
274*bc36eafdSMike Gerdts     else if (!AcpiUtIsSpecialTable (Signature))
275*bc36eafdSMike Gerdts     {
276*bc36eafdSMike Gerdts         fprintf (stderr,
277*bc36eafdSMike Gerdts             "%4.4s: Unrecognized ACPI table signature\n", Signature);
278*bc36eafdSMike Gerdts         return (AE_ERROR);
279*bc36eafdSMike Gerdts     }
280*bc36eafdSMike Gerdts 
281*bc36eafdSMike Gerdts     Status = DtCreateOneTemplate (Signature, TableCount, TableData);
282*bc36eafdSMike Gerdts     return (Status);
283*bc36eafdSMike Gerdts }
284*bc36eafdSMike Gerdts 
285*bc36eafdSMike Gerdts 
286*bc36eafdSMike Gerdts /*******************************************************************************
287*bc36eafdSMike Gerdts  *
288*bc36eafdSMike Gerdts  * FUNCTION:    DtCreateAllTemplates
289*bc36eafdSMike Gerdts  *
290*bc36eafdSMike Gerdts  * PARAMETERS:  None
291*bc36eafdSMike Gerdts  *
292*bc36eafdSMike Gerdts  * RETURN:      Status
293*bc36eafdSMike Gerdts  *
294*bc36eafdSMike Gerdts  * DESCRIPTION: Create all currently defined template files
295*bc36eafdSMike Gerdts  *
296*bc36eafdSMike Gerdts  ******************************************************************************/
297*bc36eafdSMike Gerdts 
298*bc36eafdSMike Gerdts static ACPI_STATUS
299*bc36eafdSMike Gerdts DtCreateAllTemplates (
300*bc36eafdSMike Gerdts     void)
301*bc36eafdSMike Gerdts {
302*bc36eafdSMike Gerdts     const ACPI_DMTABLE_DATA *TableData;
303*bc36eafdSMike Gerdts     ACPI_STATUS             Status;
304*bc36eafdSMike Gerdts 
305*bc36eafdSMike Gerdts 
306*bc36eafdSMike Gerdts     fprintf (stderr, "Creating all supported Template files\n");
307*bc36eafdSMike Gerdts 
308*bc36eafdSMike Gerdts     /* Walk entire ACPI table data structure */
309*bc36eafdSMike Gerdts 
310*bc36eafdSMike Gerdts     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
311*bc36eafdSMike Gerdts     {
312*bc36eafdSMike Gerdts         /* If table has a template, create the template file */
313*bc36eafdSMike Gerdts 
314*bc36eafdSMike Gerdts         if (TableData->Template)
315*bc36eafdSMike Gerdts         {
316*bc36eafdSMike Gerdts             Status = DtCreateOneTemplate (TableData->Signature,
317*bc36eafdSMike Gerdts                 0, TableData);
318*bc36eafdSMike Gerdts             if (ACPI_FAILURE (Status))
319*bc36eafdSMike Gerdts             {
320*bc36eafdSMike Gerdts                 return (Status);
321*bc36eafdSMike Gerdts             }
322*bc36eafdSMike Gerdts         }
323*bc36eafdSMike Gerdts     }
324*bc36eafdSMike Gerdts 
325*bc36eafdSMike Gerdts     /*
326*bc36eafdSMike Gerdts      * Create the special ACPI tables:
327*bc36eafdSMike Gerdts      * 1) DSDT/SSDT are AML tables, not data tables
328*bc36eafdSMike Gerdts      * 2) FACS and RSDP have non-standard headers
329*bc36eafdSMike Gerdts      */
330*bc36eafdSMike Gerdts     Status = DtCreateOneTemplate (ACPI_SIG_DSDT, 0, NULL);
331*bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
332*bc36eafdSMike Gerdts     {
333*bc36eafdSMike Gerdts         return (Status);
334*bc36eafdSMike Gerdts     }
335*bc36eafdSMike Gerdts 
336*bc36eafdSMike Gerdts     Status = DtCreateOneTemplate (ACPI_SIG_SSDT, 0, NULL);
337*bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
338*bc36eafdSMike Gerdts     {
339*bc36eafdSMike Gerdts         return (Status);
340*bc36eafdSMike Gerdts     }
341*bc36eafdSMike Gerdts 
342*bc36eafdSMike Gerdts     Status = DtCreateOneTemplate (ACPI_SIG_OSDT, 0, NULL);
343*bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
344*bc36eafdSMike Gerdts     {
345*bc36eafdSMike Gerdts         return (Status);
346*bc36eafdSMike Gerdts     }
347*bc36eafdSMike Gerdts 
348*bc36eafdSMike Gerdts     Status = DtCreateOneTemplate (ACPI_SIG_FACS, 0, NULL);
349*bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
350*bc36eafdSMike Gerdts     {
351*bc36eafdSMike Gerdts         return (Status);
352*bc36eafdSMike Gerdts     }
353*bc36eafdSMike Gerdts 
354*bc36eafdSMike Gerdts     Status = DtCreateOneTemplate (ACPI_RSDP_NAME, 0, NULL);
355*bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
356*bc36eafdSMike Gerdts     {
357*bc36eafdSMike Gerdts         return (Status);
358*bc36eafdSMike Gerdts     }
359*bc36eafdSMike Gerdts 
360*bc36eafdSMike Gerdts     return (AE_OK);
361*bc36eafdSMike Gerdts }
362*bc36eafdSMike Gerdts 
363*bc36eafdSMike Gerdts 
364*bc36eafdSMike Gerdts /*******************************************************************************
365*bc36eafdSMike Gerdts  *
366*bc36eafdSMike Gerdts  * FUNCTION:    DtCreateOneTemplate
367*bc36eafdSMike Gerdts  *
368*bc36eafdSMike Gerdts  * PARAMETERS:  Signature           - ACPI signature, NULL terminated.
369*bc36eafdSMike Gerdts  *              TableCount          - Used for SSDTs in same file as DSDT
370*bc36eafdSMike Gerdts  *              TableData           - Entry in ACPI table data structure.
371*bc36eafdSMike Gerdts  *                                    NULL if a special ACPI table.
372*bc36eafdSMike Gerdts  *
373*bc36eafdSMike Gerdts  * RETURN:      Status
374*bc36eafdSMike Gerdts  *
375*bc36eafdSMike Gerdts  * DESCRIPTION: Create one template source file for the requested ACPI table.
376*bc36eafdSMike Gerdts  *
377*bc36eafdSMike Gerdts  ******************************************************************************/
378*bc36eafdSMike Gerdts 
379*bc36eafdSMike Gerdts static ACPI_STATUS
380*bc36eafdSMike Gerdts DtCreateOneTemplate (
381*bc36eafdSMike Gerdts     char                    *Signature,
382*bc36eafdSMike Gerdts     UINT32                  TableCount,
383*bc36eafdSMike Gerdts     const ACPI_DMTABLE_DATA  *TableData)
384*bc36eafdSMike Gerdts {
385*bc36eafdSMike Gerdts     char                    *DisasmFilename;
386*bc36eafdSMike Gerdts     FILE                    *File;
387*bc36eafdSMike Gerdts     ACPI_STATUS             Status = AE_OK;
388*bc36eafdSMike Gerdts     int                     Actual;
389*bc36eafdSMike Gerdts     UINT32                  i;
390*bc36eafdSMike Gerdts 
391*bc36eafdSMike Gerdts 
392*bc36eafdSMike Gerdts     /* New file will have a .asl suffix */
393*bc36eafdSMike Gerdts 
394*bc36eafdSMike Gerdts     DisasmFilename = FlGenerateFilename (
395*bc36eafdSMike Gerdts         Signature, FILE_SUFFIX_ASL_CODE);
396*bc36eafdSMike Gerdts     if (!DisasmFilename)
397*bc36eafdSMike Gerdts     {
398*bc36eafdSMike Gerdts         fprintf (stderr, "Could not generate output filename\n");
399*bc36eafdSMike Gerdts         return (AE_ERROR);
400*bc36eafdSMike Gerdts     }
401*bc36eafdSMike Gerdts 
402*bc36eafdSMike Gerdts     AcpiUtStrlwr (DisasmFilename);
403*bc36eafdSMike Gerdts     if (!UtQueryForOverwrite (DisasmFilename))
404*bc36eafdSMike Gerdts     {
405*bc36eafdSMike Gerdts         return (AE_ERROR);
406*bc36eafdSMike Gerdts     }
407*bc36eafdSMike Gerdts 
408*bc36eafdSMike Gerdts     File = fopen (DisasmFilename, "w+");
409*bc36eafdSMike Gerdts     if (!File)
410*bc36eafdSMike Gerdts     {
411*bc36eafdSMike Gerdts         fprintf (stderr, "Could not open output file %s\n",
412*bc36eafdSMike Gerdts             DisasmFilename);
413*bc36eafdSMike Gerdts         return (AE_ERROR);
414*bc36eafdSMike Gerdts     }
415*bc36eafdSMike Gerdts 
416*bc36eafdSMike Gerdts     /* Emit the common file header */
417*bc36eafdSMike Gerdts 
418*bc36eafdSMike Gerdts     AcpiOsRedirectOutput (File);
419*bc36eafdSMike Gerdts 
420*bc36eafdSMike Gerdts     AcpiOsPrintf ("/*\n");
421*bc36eafdSMike Gerdts     AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * "));
422*bc36eafdSMike Gerdts 
423*bc36eafdSMike Gerdts     if (TableCount == 0)
424*bc36eafdSMike Gerdts     {
425*bc36eafdSMike Gerdts         AcpiOsPrintf (" * Template for [%4.4s] ACPI Table",
426*bc36eafdSMike Gerdts             Signature);
427*bc36eafdSMike Gerdts     }
428*bc36eafdSMike Gerdts     else
429*bc36eafdSMike Gerdts     {
430*bc36eafdSMike Gerdts         AcpiOsPrintf (" * Template for [%4.4s] and %u [SSDT] ACPI Tables",
431*bc36eafdSMike Gerdts             Signature, TableCount);
432*bc36eafdSMike Gerdts     }
433*bc36eafdSMike Gerdts 
434*bc36eafdSMike Gerdts     /* Dump the actual ACPI table */
435*bc36eafdSMike Gerdts 
436*bc36eafdSMike Gerdts     if (TableData)
437*bc36eafdSMike Gerdts     {
438*bc36eafdSMike Gerdts         /* Normal case, tables that appear in AcpiDmTableData */
439*bc36eafdSMike Gerdts 
440*bc36eafdSMike Gerdts         AcpiOsPrintf (" (static data table)\n");
441*bc36eafdSMike Gerdts 
442*bc36eafdSMike Gerdts         if (Gbl_VerboseTemplates)
443*bc36eafdSMike Gerdts         {
444*bc36eafdSMike Gerdts             AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]"
445*bc36eafdSMike Gerdts                 "  FieldName : HexFieldValue\n */\n\n");
446*bc36eafdSMike Gerdts         }
447*bc36eafdSMike Gerdts         else
448*bc36eafdSMike Gerdts         {
449*bc36eafdSMike Gerdts             AcpiOsPrintf (" * Format: [ByteLength]"
450*bc36eafdSMike Gerdts                 "  FieldName : HexFieldValue\n */\n");
451*bc36eafdSMike Gerdts         }
452*bc36eafdSMike Gerdts 
453*bc36eafdSMike Gerdts         AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
454*bc36eafdSMike Gerdts             TableData->Template));
455*bc36eafdSMike Gerdts     }
456*bc36eafdSMike Gerdts     else
457*bc36eafdSMike Gerdts     {
458*bc36eafdSMike Gerdts         /* Special ACPI tables - DSDT, SSDT, OSDT, FACS, RSDP */
459*bc36eafdSMike Gerdts 
460*bc36eafdSMike Gerdts         AcpiOsPrintf (" (AML byte code table)\n");
461*bc36eafdSMike Gerdts         AcpiOsPrintf (" */\n");
462*bc36eafdSMike Gerdts 
463*bc36eafdSMike Gerdts         if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
464*bc36eafdSMike Gerdts         {
465*bc36eafdSMike Gerdts             Actual = DtEmitDefinitionBlock (
466*bc36eafdSMike Gerdts                 File, DisasmFilename, ACPI_SIG_DSDT, 1);
467*bc36eafdSMike Gerdts             if (Actual < 0)
468*bc36eafdSMike Gerdts             {
469*bc36eafdSMike Gerdts                 Status = AE_ERROR;
470*bc36eafdSMike Gerdts                 goto Cleanup;
471*bc36eafdSMike Gerdts             }
472*bc36eafdSMike Gerdts 
473*bc36eafdSMike Gerdts             /* Emit any requested SSDTs into the same file */
474*bc36eafdSMike Gerdts 
475*bc36eafdSMike Gerdts             for (i = 1; i <= TableCount; i++)
476*bc36eafdSMike Gerdts             {
477*bc36eafdSMike Gerdts                 Actual = DtEmitDefinitionBlock (
478*bc36eafdSMike Gerdts                     File, DisasmFilename, ACPI_SIG_SSDT, i + 1);
479*bc36eafdSMike Gerdts                 if (Actual < 0)
480*bc36eafdSMike Gerdts                 {
481*bc36eafdSMike Gerdts                     Status = AE_ERROR;
482*bc36eafdSMike Gerdts                     goto Cleanup;
483*bc36eafdSMike Gerdts                 }
484*bc36eafdSMike Gerdts             }
485*bc36eafdSMike Gerdts         }
486*bc36eafdSMike Gerdts         else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT))
487*bc36eafdSMike Gerdts         {
488*bc36eafdSMike Gerdts             Actual = DtEmitDefinitionBlock (
489*bc36eafdSMike Gerdts                 File, DisasmFilename, ACPI_SIG_SSDT, 1);
490*bc36eafdSMike Gerdts             if (Actual < 0)
491*bc36eafdSMike Gerdts             {
492*bc36eafdSMike Gerdts                 Status = AE_ERROR;
493*bc36eafdSMike Gerdts                 goto Cleanup;
494*bc36eafdSMike Gerdts             }
495*bc36eafdSMike Gerdts         }
496*bc36eafdSMike Gerdts         else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_OSDT))
497*bc36eafdSMike Gerdts         {
498*bc36eafdSMike Gerdts             Actual = DtEmitDefinitionBlock (
499*bc36eafdSMike Gerdts                 File, DisasmFilename, ACPI_SIG_OSDT, 1);
500*bc36eafdSMike Gerdts             if (Actual < 0)
501*bc36eafdSMike Gerdts             {
502*bc36eafdSMike Gerdts                 Status = AE_ERROR;
503*bc36eafdSMike Gerdts                 goto Cleanup;
504*bc36eafdSMike Gerdts             }
505*bc36eafdSMike Gerdts         }
506*bc36eafdSMike Gerdts         else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
507*bc36eafdSMike Gerdts         {
508*bc36eafdSMike Gerdts             AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
509*bc36eafdSMike Gerdts                 TemplateFacs));
510*bc36eafdSMike Gerdts         }
511*bc36eafdSMike Gerdts         else if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
512*bc36eafdSMike Gerdts         {
513*bc36eafdSMike Gerdts             AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
514*bc36eafdSMike Gerdts                 TemplateRsdp));
515*bc36eafdSMike Gerdts         }
516*bc36eafdSMike Gerdts         else
517*bc36eafdSMike Gerdts         {
518*bc36eafdSMike Gerdts             fprintf (stderr,
519*bc36eafdSMike Gerdts                 "%4.4s, Unrecognized ACPI table signature\n", Signature);
520*bc36eafdSMike Gerdts             Status = AE_ERROR;
521*bc36eafdSMike Gerdts             goto Cleanup;
522*bc36eafdSMike Gerdts         }
523*bc36eafdSMike Gerdts     }
524*bc36eafdSMike Gerdts 
525*bc36eafdSMike Gerdts     if (TableCount == 0)
526*bc36eafdSMike Gerdts     {
527*bc36eafdSMike Gerdts         fprintf (stderr,
528*bc36eafdSMike Gerdts             "Created ACPI table template for [%4.4s], "
529*bc36eafdSMike Gerdts             "written to \"%s\"\n",
530*bc36eafdSMike Gerdts             Signature, DisasmFilename);
531*bc36eafdSMike Gerdts     }
532*bc36eafdSMike Gerdts     else
533*bc36eafdSMike Gerdts     {
534*bc36eafdSMike Gerdts         fprintf (stderr,
535*bc36eafdSMike Gerdts             "Created ACPI table templates for [%4.4s] "
536*bc36eafdSMike Gerdts             "and %u [SSDT], written to \"%s\"\n",
537*bc36eafdSMike Gerdts             Signature, TableCount, DisasmFilename);
538*bc36eafdSMike Gerdts     }
539*bc36eafdSMike Gerdts 
540*bc36eafdSMike Gerdts Cleanup:
541*bc36eafdSMike Gerdts     fclose (File);
542*bc36eafdSMike Gerdts     AcpiOsRedirectOutput (stdout);
543*bc36eafdSMike Gerdts     return (Status);
544*bc36eafdSMike Gerdts }
545*bc36eafdSMike Gerdts 
546*bc36eafdSMike Gerdts 
547*bc36eafdSMike Gerdts /*******************************************************************************
548*bc36eafdSMike Gerdts  *
549*bc36eafdSMike Gerdts  * FUNCTION:    DtEmitDefinitionBlock
550*bc36eafdSMike Gerdts  *
551*bc36eafdSMike Gerdts  * PARAMETERS:  File                - An open file for the block
552*bc36eafdSMike Gerdts  *              Filename            - Filename for same, for error msg(s)
553*bc36eafdSMike Gerdts  *              Signature           - ACPI signature for the block
554*bc36eafdSMike Gerdts  *              Instance            - Used for multiple SSDTs in the same file
555*bc36eafdSMike Gerdts  *
556*bc36eafdSMike Gerdts  * RETURN:      Status from fprintf
557*bc36eafdSMike Gerdts  *
558*bc36eafdSMike Gerdts  * DESCRIPTION: Emit the raw ASL for a complete Definition Block (DSDT or SSDT)
559*bc36eafdSMike Gerdts  *
560*bc36eafdSMike Gerdts  * Note: The AMLFileName parameter for DefinitionBlock is left as a NULL
561*bc36eafdSMike Gerdts  * string. This allows the compiler to create the output AML filename from
562*bc36eafdSMike Gerdts  * the input filename.
563*bc36eafdSMike Gerdts  *
564*bc36eafdSMike Gerdts  ******************************************************************************/
565*bc36eafdSMike Gerdts 
566*bc36eafdSMike Gerdts static int
567*bc36eafdSMike Gerdts DtEmitDefinitionBlock (
568*bc36eafdSMike Gerdts     FILE                    *File,
569*bc36eafdSMike Gerdts     char                    *Filename,
570*bc36eafdSMike Gerdts     char                    *Signature,
571*bc36eafdSMike Gerdts     UINT32                  Instance)
572*bc36eafdSMike Gerdts {
573*bc36eafdSMike Gerdts     int                     Status;
574*bc36eafdSMike Gerdts 
575*bc36eafdSMike Gerdts 
576*bc36eafdSMike Gerdts     Status = fprintf (File,
577*bc36eafdSMike Gerdts         "DefinitionBlock (\"\", \"%4.4s\", 2, \"Intel\", \"_%4.4s_%.2X\", 0x00000001)\n"
578*bc36eafdSMike Gerdts         "{\n"
579*bc36eafdSMike Gerdts         "    Method (%2.2s%.2X)\n"
580*bc36eafdSMike Gerdts         "    {\n"
581*bc36eafdSMike Gerdts         "    }\n"
582*bc36eafdSMike Gerdts         "}\n\n",
583*bc36eafdSMike Gerdts         Signature, Signature, Instance, Signature, Instance);
584*bc36eafdSMike Gerdts 
585*bc36eafdSMike Gerdts     if (Status < 0)
586*bc36eafdSMike Gerdts     {
587*bc36eafdSMike Gerdts         fprintf (stderr,
588*bc36eafdSMike Gerdts             "Could not write %4.4s to output file %s\n",
589*bc36eafdSMike Gerdts             Signature, Filename);
590*bc36eafdSMike Gerdts     }
591*bc36eafdSMike Gerdts 
592*bc36eafdSMike Gerdts     return (Status);
593*bc36eafdSMike Gerdts }
594