1 /******************************************************************************
2  *
3  * Module Name: utbuffer - Buffer dump routines
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2020, 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 "acpi.h"
45 #include "accommon.h"
46 
47 #define _COMPONENT          ACPI_UTILITIES
48         ACPI_MODULE_NAME    ("utbuffer")
49 
50 
51 /*******************************************************************************
52  *
53  * FUNCTION:    AcpiUtDumpBuffer
54  *
55  * PARAMETERS:  Buffer              - Buffer to dump
56  *              Count               - Amount to dump, in bytes
57  *              Display             - BYTE, WORD, DWORD, or QWORD display:
58  *                                      DB_BYTE_DISPLAY
59  *                                      DB_WORD_DISPLAY
60  *                                      DB_DWORD_DISPLAY
61  *                                      DB_QWORD_DISPLAY
62  *              BaseOffset          - Beginning buffer offset (display only)
63  *
64  * RETURN:      None
65  *
66  * DESCRIPTION: Generic dump buffer in both hex and ascii.
67  *
68  ******************************************************************************/
69 
70 void
71 AcpiUtDumpBuffer (
72     UINT8                   *Buffer,
73     UINT32                  Count,
74     UINT32                  Display,
75     UINT32                  BaseOffset)
76 {
77     UINT32                  i = 0;
78     UINT32                  j;
79     UINT32                  Temp32;
80     UINT8                   BufChar;
81     UINT32                  DisplayDataOnly = Display & DB_DISPLAY_DATA_ONLY;
82 
83 
84     Display &= ~DB_DISPLAY_DATA_ONLY;
85     if (!Buffer)
86     {
87         AcpiOsPrintf ("Null Buffer Pointer in DumpBuffer!\n");
88         return;
89     }
90 
91     if ((Count < 4) || (Count & 0x01))
92     {
93         Display = DB_BYTE_DISPLAY;
94     }
95 
96     /* Nasty little dump buffer routine! */
97 
98     while (i < Count)
99     {
100         /* Print current offset */
101 
102         if (!DisplayDataOnly)
103         {
104             AcpiOsPrintf ("%8.4X: ", (BaseOffset + i));
105         }
106 
107         /* Print 16 hex chars */
108 
109         for (j = 0; j < 16;)
110         {
111             if (i + j >= Count)
112             {
113                 /* Dump fill spaces */
114 
115                 AcpiOsPrintf ("%*s", ((Display * 2) + 1), " ");
116                 j += Display;
117                 continue;
118             }
119 
120             switch (Display)
121             {
122             case DB_BYTE_DISPLAY:
123             default:    /* Default is BYTE display */
124 
125                 AcpiOsPrintf ("%02X ", Buffer[(ACPI_SIZE) i + j]);
126                 break;
127 
128             case DB_WORD_DISPLAY:
129 
130                 ACPI_MOVE_16_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]);
131                 AcpiOsPrintf ("%04X ", Temp32);
132                 break;
133 
134             case DB_DWORD_DISPLAY:
135 
136                 ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]);
137                 AcpiOsPrintf ("%08X ", Temp32);
138                 break;
139 
140             case DB_QWORD_DISPLAY:
141 
142                 ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]);
143                 AcpiOsPrintf ("%08X", Temp32);
144 
145                 ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j + 4]);
146                 AcpiOsPrintf ("%08X ", Temp32);
147                 break;
148             }
149 
150             j += Display;
151         }
152 
153         /*
154          * Print the ASCII equivalent characters but watch out for the bad
155          * unprintable ones (printable chars are 0x20 through 0x7E)
156          */
157         if (!DisplayDataOnly)
158         {
159             AcpiOsPrintf (" ");
160             for (j = 0; j < 16; j++)
161             {
162                 if (i + j >= Count)
163                 {
164                     AcpiOsPrintf ("\n");
165                     return;
166                 }
167 
168                 /*
169                  * Add comment characters so rest of line is ignored when
170                  * compiled
171                  */
172                 if (j == 0)
173                 {
174                     AcpiOsPrintf ("// ");
175                 }
176 
177                 BufChar = Buffer[(ACPI_SIZE) i + j];
178                 if (isprint (BufChar))
179                 {
180                     AcpiOsPrintf ("%c", BufChar);
181                 }
182                 else
183                 {
184                     AcpiOsPrintf (".");
185                 }
186             }
187 
188             /* Done with that line. */
189 
190             AcpiOsPrintf ("\n");
191         }
192         i += 16;
193     }
194 
195     return;
196 }
197 
198 
199 /*******************************************************************************
200  *
201  * FUNCTION:    AcpiUtDebugDumpBuffer
202  *
203  * PARAMETERS:  Buffer              - Buffer to dump
204  *              Count               - Amount to dump, in bytes
205  *              Display             - BYTE, WORD, DWORD, or QWORD display:
206  *                                      DB_BYTE_DISPLAY
207  *                                      DB_WORD_DISPLAY
208  *                                      DB_DWORD_DISPLAY
209  *                                      DB_QWORD_DISPLAY
210  *              ComponentID         - Caller's component ID
211  *
212  * RETURN:      None
213  *
214  * DESCRIPTION: Generic dump buffer in both hex and ascii.
215  *
216  ******************************************************************************/
217 
218 void
219 AcpiUtDebugDumpBuffer (
220     UINT8                   *Buffer,
221     UINT32                  Count,
222     UINT32                  Display,
223     UINT32                  ComponentId)
224 {
225 
226     /* Only dump the buffer if tracing is enabled */
227 
228     if (!((ACPI_LV_TABLES & AcpiDbgLevel) &&
229         (ComponentId & AcpiDbgLayer)))
230     {
231         return;
232     }
233 
234     AcpiUtDumpBuffer (Buffer, Count, Display, 0);
235 }
236 
237 
238 #ifdef ACPI_APPLICATION
239 /*******************************************************************************
240  *
241  * FUNCTION:    AcpiUtDumpBufferToFile
242  *
243  * PARAMETERS:  File                - File descriptor
244  *              Buffer              - Buffer to dump
245  *              Count               - Amount to dump, in bytes
246  *              Display             - BYTE, WORD, DWORD, or QWORD display:
247  *                                      DB_BYTE_DISPLAY
248  *                                      DB_WORD_DISPLAY
249  *                                      DB_DWORD_DISPLAY
250  *                                      DB_QWORD_DISPLAY
251  *              BaseOffset          - Beginning buffer offset (display only)
252  *
253  * RETURN:      None
254  *
255  * DESCRIPTION: Generic dump buffer in both hex and ascii to a file.
256  *
257  ******************************************************************************/
258 
259 void
260 AcpiUtDumpBufferToFile (
261     ACPI_FILE               File,
262     UINT8                   *Buffer,
263     UINT32                  Count,
264     UINT32                  Display,
265     UINT32                  BaseOffset)
266 {
267     UINT32                  i = 0;
268     UINT32                  j;
269     UINT32                  Temp32;
270     UINT8                   BufChar;
271 
272 
273     if (!Buffer)
274     {
275         fprintf (File, "Null Buffer Pointer in DumpBuffer!\n");
276         return;
277     }
278 
279     if ((Count < 4) || (Count & 0x01))
280     {
281         Display = DB_BYTE_DISPLAY;
282     }
283 
284     /* Nasty little dump buffer routine! */
285 
286     while (i < Count)
287     {
288         /* Print current offset */
289 
290         fprintf (File, "%8.4X: ", (BaseOffset + i));
291 
292         /* Print 16 hex chars */
293 
294         for (j = 0; j < 16;)
295         {
296             if (i + j >= Count)
297             {
298                 /* Dump fill spaces */
299 
300                 fprintf (File, "%*s", ((Display * 2) + 1), " ");
301                 j += Display;
302                 continue;
303             }
304 
305             switch (Display)
306             {
307             case DB_BYTE_DISPLAY:
308             default:    /* Default is BYTE display */
309 
310                 fprintf (File, "%02X ", Buffer[(ACPI_SIZE) i + j]);
311                 break;
312 
313             case DB_WORD_DISPLAY:
314 
315                 ACPI_MOVE_16_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]);
316                 fprintf (File, "%04X ", Temp32);
317                 break;
318 
319             case DB_DWORD_DISPLAY:
320 
321                 ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]);
322                 fprintf (File, "%08X ", Temp32);
323                 break;
324 
325             case DB_QWORD_DISPLAY:
326 
327                 ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]);
328                 fprintf (File, "%08X", Temp32);
329 
330                 ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j + 4]);
331                 fprintf (File, "%08X ", Temp32);
332                 break;
333             }
334 
335             j += Display;
336         }
337 
338         /*
339          * Print the ASCII equivalent characters but watch out for the bad
340          * unprintable ones (printable chars are 0x20 through 0x7E)
341          */
342         fprintf (File, " ");
343         for (j = 0; j < 16; j++)
344         {
345             if (i + j >= Count)
346             {
347                 fprintf (File, "\n");
348                 return;
349             }
350 
351             BufChar = Buffer[(ACPI_SIZE) i + j];
352             if (isprint (BufChar))
353             {
354                 fprintf (File, "%c", BufChar);
355             }
356             else
357             {
358                 fprintf (File, ".");
359             }
360         }
361 
362         /* Done with that line. */
363 
364         fprintf (File, "\n");
365         i += 16;
366     }
367 
368     return;
369 }
370 #endif
371