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