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