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("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("%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("%*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 ", 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("%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("%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("%08X", temp32); 101 102 ACPI_MOVE_32_TO_32(&temp32, 103 &buffer[(acpi_size)i + j + 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 */ 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 } 138 } 139 140 /* Done with that line. */ 141 142 acpi_os_printf("\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, 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