xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslhex.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1 /******************************************************************************
2  *
3  * Module Name: aslhex - ASCII hex output file generation (C, ASM, and ASL)
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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 "aslcompiler.h"
45 #include "acapps.h"
46 
47 #define _COMPONENT          ACPI_COMPILER
48         ACPI_MODULE_NAME    ("ashex")
49 
50 /*
51  * This module emits ASCII hex output files in either C, ASM, or ASL format
52  */
53 
54 /* Local prototypes */
55 
56 static void
57 HxDoHexOutputC (
58     void);
59 
60 static void
61 HxDoHexOutputAsl (
62     void);
63 
64 static void
65 HxDoHexOutputAsm (
66     void);
67 
68 static UINT32
69 HxReadAmlOutputFile (
70     UINT8                   *Buffer);
71 
72 
73 /*******************************************************************************
74  *
75  * FUNCTION:    HxDoHexOutput
76  *
77  * PARAMETERS:  None
78  *
79  * RETURN:      None
80  *
81  * DESCRIPTION: Create the hex output file. Note: data is obtained by reading
82  *              the entire AML output file that was previously generated.
83  *
84  ******************************************************************************/
85 
86 void
HxDoHexOutput(void)87 HxDoHexOutput (
88     void)
89 {
90 
91     switch (AslGbl_HexOutputFlag)
92     {
93     case HEX_OUTPUT_C:
94 
95         HxDoHexOutputC ();
96         break;
97 
98     case HEX_OUTPUT_ASM:
99 
100         HxDoHexOutputAsm ();
101         break;
102 
103     case HEX_OUTPUT_ASL:
104 
105         HxDoHexOutputAsl ();
106         break;
107 
108     default:
109 
110         /* No other output types supported */
111 
112         break;
113     }
114 }
115 
116 
117 /*******************************************************************************
118  *
119  * FUNCTION:    HxReadAmlOutputFile
120  *
121  * PARAMETERS:  Buffer              - Where to return data
122  *
123  * RETURN:      None
124  *
125  * DESCRIPTION: Read a line of the AML output prior to formatting the data
126  *
127  ******************************************************************************/
128 
129 static UINT32
HxReadAmlOutputFile(UINT8 * Buffer)130 HxReadAmlOutputFile (
131     UINT8                   *Buffer)
132 {
133     UINT32                  Actual;
134 
135 
136     Actual = fread (Buffer, 1, HEX_TABLE_LINE_SIZE,
137         AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle);
138 
139     if (ferror (AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle))
140     {
141         FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ);
142         AslAbort ();
143     }
144 
145     return (Actual);
146 }
147 
148 
149 /*******************************************************************************
150  *
151  * FUNCTION:    HxDoHexOutputC
152  *
153  * PARAMETERS:  None
154  *
155  * RETURN:      None
156  *
157  * DESCRIPTION: Create the hex output file. This is the same data as the AML
158  *              output file, but formatted into hex/ascii bytes suitable for
159  *              inclusion into a C source file.
160  *
161  *              Note: the base name of the hex output file is prepended to
162  *              all symbols as they are output to the file.
163  *
164  ******************************************************************************/
165 
166 static void
HxDoHexOutputC(void)167 HxDoHexOutputC (
168     void)
169 {
170     UINT8                   FileData[HEX_TABLE_LINE_SIZE];
171     UINT32                  LineLength;
172     UINT32                  Offset = 0;
173     UINT32                  AmlFileSize;
174     UINT32                  i;
175     char                    *FileBasename;
176 
177 
178     /* Obtain the file basename (filename with no extension) */
179 
180     FileBasename = FlGetFileBasename (AslGbl_Files [ASL_FILE_HEX_OUTPUT].Filename);
181 
182     /* Get AML size, seek back to start */
183 
184     AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
185     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
186 
187     /* Finish the file header and emit the non-data symbols */
188 
189     FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C source code output\n");
190     FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
191         AmlFileSize);
192 
193     FlPrintFile (ASL_FILE_HEX_OUTPUT, "#ifndef __%s_HEX__\n", FileBasename);
194     FlPrintFile (ASL_FILE_HEX_OUTPUT, "#define __%s_HEX__\n\n", FileBasename);
195 
196     AcpiUtStrlwr (FileBasename);
197     FlPrintFile (ASL_FILE_HEX_OUTPUT, "unsigned char %s_aml_code[] =\n{\n", FileBasename);
198 
199     while (Offset < AmlFileSize)
200     {
201         /* Read enough bytes needed for one output line */
202 
203         LineLength = HxReadAmlOutputFile (FileData);
204         if (!LineLength)
205         {
206             break;
207         }
208 
209         FlPrintFile (ASL_FILE_HEX_OUTPUT, "    ");
210 
211         for (i = 0; i < LineLength; i++)
212         {
213             /*
214              * Output each hex byte in the form: "0xnn,"
215              * Add a comma until the very last byte of the AML file
216              * (Some C compilers complain about a trailing comma)
217              */
218             FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]);
219             if ((Offset + i + 1) < AmlFileSize)
220             {
221                 FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
222             }
223             else
224             {
225                 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
226             }
227         }
228 
229         /* Add fill spaces if needed for last line */
230 
231         if (LineLength < HEX_TABLE_LINE_SIZE)
232         {
233             FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
234                 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
235         }
236 
237         /* Emit the offset and ascii dump for the entire line */
238 
239         FlPrintFile (ASL_FILE_HEX_OUTPUT, "  /* %8.8X", Offset);
240         LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
241 
242         FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n",
243             HEX_TABLE_LINE_SIZE - LineLength + 1, " ");
244 
245         Offset += LineLength;
246     }
247 
248     FlPrintFile (ASL_FILE_HEX_OUTPUT, "};\n\n");
249     FlPrintFile (ASL_FILE_HEX_OUTPUT, "#endif\n");
250 }
251 
252 
253 /*******************************************************************************
254  *
255  * FUNCTION:    HxDoHexOutputAsl
256  *
257  * PARAMETERS:  None
258  *
259  * RETURN:      None
260  *
261  * DESCRIPTION: Create the hex output file. This is the same data as the AML
262  *              output file, but formatted into hex/ascii bytes suitable for
263  *              inclusion into a C source file.
264  *
265  ******************************************************************************/
266 
267 static void
HxDoHexOutputAsl(void)268 HxDoHexOutputAsl (
269     void)
270 {
271     UINT8                   FileData[HEX_TABLE_LINE_SIZE];
272     UINT32                  LineLength;
273     UINT32                  Offset = 0;
274     UINT32                  AmlFileSize;
275     UINT32                  i;
276 
277 
278     /* Get AML size, seek back to start */
279 
280     AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
281     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
282 
283     FlPrintFile (ASL_FILE_HEX_OUTPUT, " * ASL source code output\n");
284     FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
285         AmlFileSize);
286     FlPrintFile (ASL_FILE_HEX_OUTPUT, "    Name (BUF1, Buffer()\n    {\n");
287 
288     while (Offset < AmlFileSize)
289     {
290         /* Read enough bytes needed for one output line */
291 
292         LineLength = HxReadAmlOutputFile (FileData);
293         if (!LineLength)
294         {
295             break;
296         }
297 
298         FlPrintFile (ASL_FILE_HEX_OUTPUT, "        ");
299 
300         for (i = 0; i < LineLength; i++)
301         {
302             /*
303              * Print each hex byte.
304              * Add a comma until the very last byte of the AML file
305              * (Some C compilers complain about a trailing comma)
306              */
307             FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]);
308             if ((Offset + i + 1) < AmlFileSize)
309             {
310                 FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
311             }
312             else
313             {
314                 FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
315             }
316         }
317 
318         /* Add fill spaces if needed for last line */
319 
320         if (LineLength < HEX_TABLE_LINE_SIZE)
321         {
322             FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
323                 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
324         }
325 
326         /* Emit the offset and ascii dump for the entire line */
327 
328         FlPrintFile (ASL_FILE_HEX_OUTPUT, "  /* %8.8X", Offset);
329         LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
330 
331         FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n",
332             HEX_TABLE_LINE_SIZE - LineLength + 1, " ");
333 
334         Offset += LineLength;
335     }
336 
337     FlPrintFile (ASL_FILE_HEX_OUTPUT, "    })\n");
338 }
339 
340 
341 /*******************************************************************************
342  *
343  * FUNCTION:    HxDoHexOutputAsm
344  *
345  * PARAMETERS:  None
346  *
347  * RETURN:      None
348  *
349  * DESCRIPTION: Create the hex output file. This is the same data as the AML
350  *              output file, but formatted into hex/ascii bytes suitable for
351  *              inclusion into a ASM source file.
352  *
353  ******************************************************************************/
354 
355 static void
HxDoHexOutputAsm(void)356 HxDoHexOutputAsm (
357     void)
358 {
359     UINT8                   FileData[HEX_TABLE_LINE_SIZE];
360     UINT32                  LineLength;
361     UINT32                  Offset = 0;
362     UINT32                  AmlFileSize;
363     UINT32                  i;
364 
365 
366     /* Get AML size, seek back to start */
367 
368     AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
369     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
370 
371     FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n");
372     FlPrintFile (ASL_FILE_HEX_OUTPUT, "; AML code block contains 0x%X bytes\n;\n",
373         AmlFileSize);
374 
375     while (Offset < AmlFileSize)
376     {
377         /* Read enough bytes needed for one output line */
378 
379         LineLength = HxReadAmlOutputFile (FileData);
380         if (!LineLength)
381         {
382             break;
383         }
384 
385         FlPrintFile (ASL_FILE_HEX_OUTPUT, "  db  ");
386 
387         for (i = 0; i < LineLength; i++)
388         {
389             /*
390              * Print each hex byte.
391              * Add a comma until the last byte of the line
392              */
393             FlPrintFile (ASL_FILE_HEX_OUTPUT, "0%2.2Xh", FileData[i]);
394             if ((i + 1) < LineLength)
395             {
396                 FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
397             }
398         }
399 
400         FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
401 
402         /* Add fill spaces if needed for last line */
403 
404         if (LineLength < HEX_TABLE_LINE_SIZE)
405         {
406             FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
407                 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
408         }
409 
410         /* Emit the offset and ascii dump for the entire line */
411 
412         FlPrintFile (ASL_FILE_HEX_OUTPUT, "  ; %8.8X", Offset);
413         LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
414 
415         FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
416 
417         Offset += LineLength;
418     }
419 
420     FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
421 }
422