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