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