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 - 2023, 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 | ******************************************************************************/ |
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 | u32 display_data_only = display & DB_DISPLAY_DATA_ONLY; |
41 | |
42 | display &= ~DB_DISPLAY_DATA_ONLY; |
43 | if (!buffer) { |
44 | acpi_os_printf(format: "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 | |
58 | if (!display_data_only) { |
59 | acpi_os_printf(format: "%8.4X: " , (base_offset + i)); |
60 | } |
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(format: "%*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(format: "%02X " , |
79 | buffer[(acpi_size)i + j]); |
80 | break; |
81 | |
82 | case DB_WORD_DISPLAY: |
83 | |
84 | ACPI_MOVE_16_TO_32(&temp32, |
85 | &buffer[(acpi_size)i + j]); |
86 | acpi_os_printf(format: "%04X " , temp32); |
87 | break; |
88 | |
89 | case DB_DWORD_DISPLAY: |
90 | |
91 | ACPI_MOVE_32_TO_32(&temp32, |
92 | &buffer[(acpi_size)i + j]); |
93 | acpi_os_printf(format: "%08X " , temp32); |
94 | break; |
95 | |
96 | case DB_QWORD_DISPLAY: |
97 | |
98 | ACPI_MOVE_32_TO_32(&temp32, |
99 | &buffer[(acpi_size)i + j]); |
100 | acpi_os_printf(format: "%08X" , temp32); |
101 | |
102 | ACPI_MOVE_32_TO_32(&temp32, |
103 | &buffer[(acpi_size)i + j + |
104 | 4]); |
105 | acpi_os_printf(format: "%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 | */ |
116 | if (!display_data_only) { |
117 | acpi_os_printf(format: " " ); |
118 | for (j = 0; j < 16; j++) { |
119 | if (i + j >= count) { |
120 | acpi_os_printf(format: "\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(format: "// " ); |
130 | } |
131 | |
132 | buf_char = buffer[(acpi_size)i + j]; |
133 | if (isprint(buf_char)) { |
134 | acpi_os_printf(format: "%c" , buf_char); |
135 | } else { |
136 | acpi_os_printf(format: "." ); |
137 | } |
138 | } |
139 | |
140 | /* Done with that line. */ |
141 | |
142 | acpi_os_printf(format: "\n" ); |
143 | } |
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, base_offset: 0); |
181 | } |
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) { |
214 | fprintf(file, "Null Buffer Pointer in DumpBuffer!\n" ); |
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 | |
228 | fprintf(file, "%8.4X: " , (base_offset + i)); |
229 | |
230 | /* Print 16 hex chars */ |
231 | |
232 | for (j = 0; j < 16;) { |
233 | if (i + j >= count) { |
234 | |
235 | /* Dump fill spaces */ |
236 | |
237 | fprintf(file, "%*s" , ((display * 2) + 1), " " ); |
238 | j += display; |
239 | continue; |
240 | } |
241 | |
242 | switch (display) { |
243 | case DB_BYTE_DISPLAY: |
244 | default: /* Default is BYTE display */ |
245 | |
246 | fprintf(file, "%02X " , |
247 | buffer[(acpi_size)i + j]); |
248 | break; |
249 | |
250 | case DB_WORD_DISPLAY: |
251 | |
252 | ACPI_MOVE_16_TO_32(&temp32, |
253 | &buffer[(acpi_size)i + j]); |
254 | fprintf(file, "%04X " , temp32); |
255 | break; |
256 | |
257 | case DB_DWORD_DISPLAY: |
258 | |
259 | ACPI_MOVE_32_TO_32(&temp32, |
260 | &buffer[(acpi_size)i + j]); |
261 | fprintf(file, "%08X " , temp32); |
262 | break; |
263 | |
264 | case DB_QWORD_DISPLAY: |
265 | |
266 | ACPI_MOVE_32_TO_32(&temp32, |
267 | &buffer[(acpi_size)i + j]); |
268 | fprintf(file, "%08X" , temp32); |
269 | |
270 | ACPI_MOVE_32_TO_32(&temp32, |
271 | &buffer[(acpi_size)i + j + |
272 | 4]); |
273 | fprintf(file, "%08X " , temp32); |
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 | */ |
284 | fprintf(file, " " ); |
285 | for (j = 0; j < 16; j++) { |
286 | if (i + j >= count) { |
287 | fprintf(file, "\n" ); |
288 | return; |
289 | } |
290 | |
291 | buf_char = buffer[(acpi_size)i + j]; |
292 | if (isprint(buf_char)) { |
293 | fprintf(file, "%c" , buf_char); |
294 | } else { |
295 | fprintf(file, "." ); |
296 | } |
297 | } |
298 | |
299 | /* Done with that line. */ |
300 | |
301 | fprintf(file, "\n" ); |
302 | i += 16; |
303 | } |
304 | |
305 | return; |
306 | } |
307 | #endif |
308 | |