xref: /linux/drivers/acpi/acpica/utbuffer.c (revision b85d45947951d23cb22d90caecf4c1eb81342c96)
1 /******************************************************************************
2  *
3  * Module Name: utbuffer - Buffer dump routines
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 <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 		acpi_ut_file_printf(file,
243 				    "Null Buffer Pointer in DumpBuffer!\n");
244 		return;
245 	}
246 
247 	if ((count < 4) || (count & 0x01)) {
248 		display = DB_BYTE_DISPLAY;
249 	}
250 
251 	/* Nasty little dump buffer routine! */
252 
253 	while (i < count) {
254 
255 		/* Print current offset */
256 
257 		acpi_ut_file_printf(file, "%6.4X: ", (base_offset + i));
258 
259 		/* Print 16 hex chars */
260 
261 		for (j = 0; j < 16;) {
262 			if (i + j >= count) {
263 
264 				/* Dump fill spaces */
265 
266 				acpi_ut_file_printf(file, "%*s",
267 						    ((display * 2) + 1), " ");
268 				j += display;
269 				continue;
270 			}
271 
272 			switch (display) {
273 			case DB_BYTE_DISPLAY:
274 			default:	/* Default is BYTE display */
275 
276 				acpi_ut_file_printf(file, "%02X ",
277 						    buffer[(acpi_size) i + j]);
278 				break;
279 
280 			case DB_WORD_DISPLAY:
281 
282 				ACPI_MOVE_16_TO_32(&temp32,
283 						   &buffer[(acpi_size) i + j]);
284 				acpi_ut_file_printf(file, "%04X ", temp32);
285 				break;
286 
287 			case DB_DWORD_DISPLAY:
288 
289 				ACPI_MOVE_32_TO_32(&temp32,
290 						   &buffer[(acpi_size) i + j]);
291 				acpi_ut_file_printf(file, "%08X ", temp32);
292 				break;
293 
294 			case DB_QWORD_DISPLAY:
295 
296 				ACPI_MOVE_32_TO_32(&temp32,
297 						   &buffer[(acpi_size) i + j]);
298 				acpi_ut_file_printf(file, "%08X", temp32);
299 
300 				ACPI_MOVE_32_TO_32(&temp32,
301 						   &buffer[(acpi_size) i + j +
302 							   4]);
303 				acpi_ut_file_printf(file, "%08X ", temp32);
304 				break;
305 			}
306 
307 			j += display;
308 		}
309 
310 		/*
311 		 * Print the ASCII equivalent characters but watch out for the bad
312 		 * unprintable ones (printable chars are 0x20 through 0x7E)
313 		 */
314 		acpi_ut_file_printf(file, " ");
315 		for (j = 0; j < 16; j++) {
316 			if (i + j >= count) {
317 				acpi_ut_file_printf(file, "\n");
318 				return;
319 			}
320 
321 			buf_char = buffer[(acpi_size) i + j];
322 			if (isprint(buf_char)) {
323 				acpi_ut_file_printf(file, "%c", buf_char);
324 			} else {
325 				acpi_ut_file_printf(file, ".");
326 			}
327 		}
328 
329 		/* Done with that line. */
330 
331 		acpi_ut_file_printf(file, "\n");
332 		i += 16;
333 	}
334 
335 	return;
336 }
337 #endif
338