162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: utbuffer - Buffer dump routines
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2000 - 2023, Intel Corp.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *****************************************************************************/
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <acpi/acpi.h>
1162306a36Sopenharmony_ci#include "accommon.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define _COMPONENT          ACPI_UTILITIES
1462306a36Sopenharmony_ciACPI_MODULE_NAME("utbuffer")
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/*******************************************************************************
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci * FUNCTION:    acpi_ut_dump_buffer
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci * PARAMETERS:  buffer              - Buffer to dump
2162306a36Sopenharmony_ci *              count               - Amount to dump, in bytes
2262306a36Sopenharmony_ci *              display             - BYTE, WORD, DWORD, or QWORD display:
2362306a36Sopenharmony_ci *                                      DB_BYTE_DISPLAY
2462306a36Sopenharmony_ci *                                      DB_WORD_DISPLAY
2562306a36Sopenharmony_ci *                                      DB_DWORD_DISPLAY
2662306a36Sopenharmony_ci *                                      DB_QWORD_DISPLAY
2762306a36Sopenharmony_ci *              base_offset         - Beginning buffer offset (display only)
2862306a36Sopenharmony_ci *
2962306a36Sopenharmony_ci * RETURN:      None
3062306a36Sopenharmony_ci *
3162306a36Sopenharmony_ci * DESCRIPTION: Generic dump buffer in both hex and ascii.
3262306a36Sopenharmony_ci *
3362306a36Sopenharmony_ci ******************************************************************************/
3462306a36Sopenharmony_civoid acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 base_offset)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	u32 i = 0;
3762306a36Sopenharmony_ci	u32 j;
3862306a36Sopenharmony_ci	u32 temp32;
3962306a36Sopenharmony_ci	u8 buf_char;
4062306a36Sopenharmony_ci	u32 display_data_only = display & DB_DISPLAY_DATA_ONLY;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	display &= ~DB_DISPLAY_DATA_ONLY;
4362306a36Sopenharmony_ci	if (!buffer) {
4462306a36Sopenharmony_ci		acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
4562306a36Sopenharmony_ci		return;
4662306a36Sopenharmony_ci	}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	if ((count < 4) || (count & 0x01)) {
4962306a36Sopenharmony_ci		display = DB_BYTE_DISPLAY;
5062306a36Sopenharmony_ci	}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	/* Nasty little dump buffer routine! */
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	while (i < count) {
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci		/* Print current offset */
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci		if (!display_data_only) {
5962306a36Sopenharmony_ci			acpi_os_printf("%8.4X: ", (base_offset + i));
6062306a36Sopenharmony_ci		}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci		/* Print 16 hex chars */
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci		for (j = 0; j < 16;) {
6562306a36Sopenharmony_ci			if (i + j >= count) {
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci				/* Dump fill spaces */
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci				acpi_os_printf("%*s", ((display * 2) + 1), " ");
7062306a36Sopenharmony_ci				j += display;
7162306a36Sopenharmony_ci				continue;
7262306a36Sopenharmony_ci			}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci			switch (display) {
7562306a36Sopenharmony_ci			case DB_BYTE_DISPLAY:
7662306a36Sopenharmony_ci			default:	/* Default is BYTE display */
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci				acpi_os_printf("%02X ",
7962306a36Sopenharmony_ci					       buffer[(acpi_size)i + j]);
8062306a36Sopenharmony_ci				break;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci			case DB_WORD_DISPLAY:
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci				ACPI_MOVE_16_TO_32(&temp32,
8562306a36Sopenharmony_ci						   &buffer[(acpi_size)i + j]);
8662306a36Sopenharmony_ci				acpi_os_printf("%04X ", temp32);
8762306a36Sopenharmony_ci				break;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci			case DB_DWORD_DISPLAY:
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci				ACPI_MOVE_32_TO_32(&temp32,
9262306a36Sopenharmony_ci						   &buffer[(acpi_size)i + j]);
9362306a36Sopenharmony_ci				acpi_os_printf("%08X ", temp32);
9462306a36Sopenharmony_ci				break;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci			case DB_QWORD_DISPLAY:
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci				ACPI_MOVE_32_TO_32(&temp32,
9962306a36Sopenharmony_ci						   &buffer[(acpi_size)i + j]);
10062306a36Sopenharmony_ci				acpi_os_printf("%08X", temp32);
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci				ACPI_MOVE_32_TO_32(&temp32,
10362306a36Sopenharmony_ci						   &buffer[(acpi_size)i + j +
10462306a36Sopenharmony_ci							   4]);
10562306a36Sopenharmony_ci				acpi_os_printf("%08X ", temp32);
10662306a36Sopenharmony_ci				break;
10762306a36Sopenharmony_ci			}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci			j += display;
11062306a36Sopenharmony_ci		}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci		/*
11362306a36Sopenharmony_ci		 * Print the ASCII equivalent characters but watch out for the bad
11462306a36Sopenharmony_ci		 * unprintable ones (printable chars are 0x20 through 0x7E)
11562306a36Sopenharmony_ci		 */
11662306a36Sopenharmony_ci		if (!display_data_only) {
11762306a36Sopenharmony_ci			acpi_os_printf(" ");
11862306a36Sopenharmony_ci			for (j = 0; j < 16; j++) {
11962306a36Sopenharmony_ci				if (i + j >= count) {
12062306a36Sopenharmony_ci					acpi_os_printf("\n");
12162306a36Sopenharmony_ci					return;
12262306a36Sopenharmony_ci				}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci				/*
12562306a36Sopenharmony_ci				 * Add comment characters so rest of line is ignored when
12662306a36Sopenharmony_ci				 * compiled
12762306a36Sopenharmony_ci				 */
12862306a36Sopenharmony_ci				if (j == 0) {
12962306a36Sopenharmony_ci					acpi_os_printf("// ");
13062306a36Sopenharmony_ci				}
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci				buf_char = buffer[(acpi_size)i + j];
13362306a36Sopenharmony_ci				if (isprint(buf_char)) {
13462306a36Sopenharmony_ci					acpi_os_printf("%c", buf_char);
13562306a36Sopenharmony_ci				} else {
13662306a36Sopenharmony_ci					acpi_os_printf(".");
13762306a36Sopenharmony_ci				}
13862306a36Sopenharmony_ci			}
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci			/* Done with that line. */
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci			acpi_os_printf("\n");
14362306a36Sopenharmony_ci		}
14462306a36Sopenharmony_ci		i += 16;
14562306a36Sopenharmony_ci	}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	return;
14862306a36Sopenharmony_ci}
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci/*******************************************************************************
15162306a36Sopenharmony_ci *
15262306a36Sopenharmony_ci * FUNCTION:    acpi_ut_debug_dump_buffer
15362306a36Sopenharmony_ci *
15462306a36Sopenharmony_ci * PARAMETERS:  buffer              - Buffer to dump
15562306a36Sopenharmony_ci *              count               - Amount to dump, in bytes
15662306a36Sopenharmony_ci *              display             - BYTE, WORD, DWORD, or QWORD display:
15762306a36Sopenharmony_ci *                                      DB_BYTE_DISPLAY
15862306a36Sopenharmony_ci *                                      DB_WORD_DISPLAY
15962306a36Sopenharmony_ci *                                      DB_DWORD_DISPLAY
16062306a36Sopenharmony_ci *                                      DB_QWORD_DISPLAY
16162306a36Sopenharmony_ci *              component_ID        - Caller's component ID
16262306a36Sopenharmony_ci *
16362306a36Sopenharmony_ci * RETURN:      None
16462306a36Sopenharmony_ci *
16562306a36Sopenharmony_ci * DESCRIPTION: Generic dump buffer in both hex and ascii.
16662306a36Sopenharmony_ci *
16762306a36Sopenharmony_ci ******************************************************************************/
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_civoid
17062306a36Sopenharmony_ciacpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)
17162306a36Sopenharmony_ci{
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	/* Only dump the buffer if tracing is enabled */
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	if (!((ACPI_LV_TABLES & acpi_dbg_level) &&
17662306a36Sopenharmony_ci	      (component_id & acpi_dbg_layer))) {
17762306a36Sopenharmony_ci		return;
17862306a36Sopenharmony_ci	}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	acpi_ut_dump_buffer(buffer, count, display, 0);
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci#ifdef ACPI_APPLICATION
18462306a36Sopenharmony_ci/*******************************************************************************
18562306a36Sopenharmony_ci *
18662306a36Sopenharmony_ci * FUNCTION:    acpi_ut_dump_buffer_to_file
18762306a36Sopenharmony_ci *
18862306a36Sopenharmony_ci * PARAMETERS:  file                - File descriptor
18962306a36Sopenharmony_ci *              buffer              - Buffer to dump
19062306a36Sopenharmony_ci *              count               - Amount to dump, in bytes
19162306a36Sopenharmony_ci *              display             - BYTE, WORD, DWORD, or QWORD display:
19262306a36Sopenharmony_ci *                                      DB_BYTE_DISPLAY
19362306a36Sopenharmony_ci *                                      DB_WORD_DISPLAY
19462306a36Sopenharmony_ci *                                      DB_DWORD_DISPLAY
19562306a36Sopenharmony_ci *                                      DB_QWORD_DISPLAY
19662306a36Sopenharmony_ci *              base_offset         - Beginning buffer offset (display only)
19762306a36Sopenharmony_ci *
19862306a36Sopenharmony_ci * RETURN:      None
19962306a36Sopenharmony_ci *
20062306a36Sopenharmony_ci * DESCRIPTION: Generic dump buffer in both hex and ascii to a file.
20162306a36Sopenharmony_ci *
20262306a36Sopenharmony_ci ******************************************************************************/
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_civoid
20562306a36Sopenharmony_ciacpi_ut_dump_buffer_to_file(ACPI_FILE file,
20662306a36Sopenharmony_ci			    u8 *buffer, u32 count, u32 display, u32 base_offset)
20762306a36Sopenharmony_ci{
20862306a36Sopenharmony_ci	u32 i = 0;
20962306a36Sopenharmony_ci	u32 j;
21062306a36Sopenharmony_ci	u32 temp32;
21162306a36Sopenharmony_ci	u8 buf_char;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	if (!buffer) {
21462306a36Sopenharmony_ci		fprintf(file, "Null Buffer Pointer in DumpBuffer!\n");
21562306a36Sopenharmony_ci		return;
21662306a36Sopenharmony_ci	}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	if ((count < 4) || (count & 0x01)) {
21962306a36Sopenharmony_ci		display = DB_BYTE_DISPLAY;
22062306a36Sopenharmony_ci	}
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	/* Nasty little dump buffer routine! */
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	while (i < count) {
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci		/* Print current offset */
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci		fprintf(file, "%8.4X: ", (base_offset + i));
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci		/* Print 16 hex chars */
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci		for (j = 0; j < 16;) {
23362306a36Sopenharmony_ci			if (i + j >= count) {
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci				/* Dump fill spaces */
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci				fprintf(file, "%*s", ((display * 2) + 1), " ");
23862306a36Sopenharmony_ci				j += display;
23962306a36Sopenharmony_ci				continue;
24062306a36Sopenharmony_ci			}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci			switch (display) {
24362306a36Sopenharmony_ci			case DB_BYTE_DISPLAY:
24462306a36Sopenharmony_ci			default:	/* Default is BYTE display */
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci				fprintf(file, "%02X ",
24762306a36Sopenharmony_ci					buffer[(acpi_size)i + j]);
24862306a36Sopenharmony_ci				break;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci			case DB_WORD_DISPLAY:
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci				ACPI_MOVE_16_TO_32(&temp32,
25362306a36Sopenharmony_ci						   &buffer[(acpi_size)i + j]);
25462306a36Sopenharmony_ci				fprintf(file, "%04X ", temp32);
25562306a36Sopenharmony_ci				break;
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci			case DB_DWORD_DISPLAY:
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci				ACPI_MOVE_32_TO_32(&temp32,
26062306a36Sopenharmony_ci						   &buffer[(acpi_size)i + j]);
26162306a36Sopenharmony_ci				fprintf(file, "%08X ", temp32);
26262306a36Sopenharmony_ci				break;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci			case DB_QWORD_DISPLAY:
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci				ACPI_MOVE_32_TO_32(&temp32,
26762306a36Sopenharmony_ci						   &buffer[(acpi_size)i + j]);
26862306a36Sopenharmony_ci				fprintf(file, "%08X", temp32);
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci				ACPI_MOVE_32_TO_32(&temp32,
27162306a36Sopenharmony_ci						   &buffer[(acpi_size)i + j +
27262306a36Sopenharmony_ci							   4]);
27362306a36Sopenharmony_ci				fprintf(file, "%08X ", temp32);
27462306a36Sopenharmony_ci				break;
27562306a36Sopenharmony_ci			}
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci			j += display;
27862306a36Sopenharmony_ci		}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci		/*
28162306a36Sopenharmony_ci		 * Print the ASCII equivalent characters but watch out for the bad
28262306a36Sopenharmony_ci		 * unprintable ones (printable chars are 0x20 through 0x7E)
28362306a36Sopenharmony_ci		 */
28462306a36Sopenharmony_ci		fprintf(file, " ");
28562306a36Sopenharmony_ci		for (j = 0; j < 16; j++) {
28662306a36Sopenharmony_ci			if (i + j >= count) {
28762306a36Sopenharmony_ci				fprintf(file, "\n");
28862306a36Sopenharmony_ci				return;
28962306a36Sopenharmony_ci			}
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci			buf_char = buffer[(acpi_size)i + j];
29262306a36Sopenharmony_ci			if (isprint(buf_char)) {
29362306a36Sopenharmony_ci				fprintf(file, "%c", buf_char);
29462306a36Sopenharmony_ci			} else {
29562306a36Sopenharmony_ci				fprintf(file, ".");
29662306a36Sopenharmony_ci			}
29762306a36Sopenharmony_ci		}
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci		/* Done with that line. */
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci		fprintf(file, "\n");
30262306a36Sopenharmony_ci		i += 16;
30362306a36Sopenharmony_ci	}
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	return;
30662306a36Sopenharmony_ci}
30762306a36Sopenharmony_ci#endif
308