1/******************************************************************************
2 *
3 * Module Name: aslhex - ASCII hex output file generation (C, ASM, and ASL)
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
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
54/* Local prototypes */
55
56static void
57HxDoHexOutputC (
58    void);
59
60static void
61HxDoHexOutputAsl (
62    void);
63
64static void
65HxDoHexOutputAsm (
66    void);
67
68static UINT32
69HxReadAmlOutputFile (
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
86void
87HxDoHexOutput (
88    void)
89{
90
91    switch (Gbl_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
129static UINT32
130HxReadAmlOutputFile (
131    UINT8                   *Buffer)
132{
133    UINT32                  Actual;
134
135
136    Actual = fread (Buffer, 1, HEX_TABLE_LINE_SIZE,
137        Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
138
139    if (ferror (Gbl_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 ******************************************************************************/
162
163static void
164HxDoHexOutputC (
165    void)
166{
167    UINT8                   FileData[HEX_TABLE_LINE_SIZE];
168    UINT32                  LineLength;
169    UINT32                  Offset = 0;
170    UINT32                  AmlFileSize;
171    UINT32                  i;
172
173
174    /* Get AML size, seek back to start */
175
176    AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
177    FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
178
179    FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C source code output\n");
180    FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
181        AmlFileSize);
182    FlPrintFile (ASL_FILE_HEX_OUTPUT, "unsigned char AmlCode[] =\n{\n");
183
184    while (Offset < AmlFileSize)
185    {
186        /* Read enough bytes needed for one output line */
187
188        LineLength = HxReadAmlOutputFile (FileData);
189        if (!LineLength)
190        {
191            break;
192        }
193
194        FlPrintFile (ASL_FILE_HEX_OUTPUT, "    ");
195
196        for (i = 0; i < LineLength; i++)
197        {
198            /*
199             * Print each hex byte.
200             * Add a comma until the very last byte of the AML file
201             * (Some C compilers complain about a trailing comma)
202             */
203            FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]);
204            if ((Offset + i + 1) < AmlFileSize)
205            {
206                FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
207            }
208            else
209            {
210                FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
211            }
212        }
213
214        /* Add fill spaces if needed for last line */
215
216        if (LineLength < HEX_TABLE_LINE_SIZE)
217        {
218            FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
219                5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
220        }
221
222        /* Emit the offset and ascii dump for the entire line */
223
224        FlPrintFile (ASL_FILE_HEX_OUTPUT, "  /* %8.8X", Offset);
225        LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
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        FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n",
314            HEX_TABLE_LINE_SIZE - LineLength + 1, " ");
315
316        Offset += LineLength;
317    }
318
319    FlPrintFile (ASL_FILE_HEX_OUTPUT, "    })\n");
320}
321
322
323/*******************************************************************************
324 *
325 * FUNCTION:    HxDoHexOutputAsm
326 *
327 * PARAMETERS:  None
328 *
329 * RETURN:      None
330 *
331 * DESCRIPTION: Create the hex output file. This is the same data as the AML
332 *              output file, but formatted into hex/ascii bytes suitable for
333 *              inclusion into a ASM source file.
334 *
335 ******************************************************************************/
336
337static void
338HxDoHexOutputAsm (
339    void)
340{
341    UINT8                   FileData[HEX_TABLE_LINE_SIZE];
342    UINT32                  LineLength;
343    UINT32                  Offset = 0;
344    UINT32                  AmlFileSize;
345    UINT32                  i;
346
347
348    /* Get AML size, seek back to start */
349
350    AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
351    FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
352
353    FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n");
354    FlPrintFile (ASL_FILE_HEX_OUTPUT, "; AML code block contains 0x%X bytes\n;\n",
355        AmlFileSize);
356
357    while (Offset < AmlFileSize)
358    {
359        /* Read enough bytes needed for one output line */
360
361        LineLength = HxReadAmlOutputFile (FileData);
362        if (!LineLength)
363        {
364            break;
365        }
366
367        FlPrintFile (ASL_FILE_HEX_OUTPUT, "  db  ");
368
369        for (i = 0; i < LineLength; i++)
370        {
371            /*
372             * Print each hex byte.
373             * Add a comma until the last byte of the line
374             */
375            FlPrintFile (ASL_FILE_HEX_OUTPUT, "0%2.2Xh", FileData[i]);
376            if ((i + 1) < LineLength)
377            {
378                FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
379            }
380        }
381
382        FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
383
384        /* Add fill spaces if needed for last line */
385
386        if (LineLength < HEX_TABLE_LINE_SIZE)
387        {
388            FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
389                5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
390        }
391
392        /* Emit the offset and ascii dump for the entire line */
393
394        FlPrintFile (ASL_FILE_HEX_OUTPUT, "  ; %8.8X", Offset);
395        LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
396        FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
397
398        Offset += LineLength;
399    }
400
401    FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
402}
403