162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: tbprint - Table output utilities
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#include "actables.h"
1362306a36Sopenharmony_ci#include "acutils.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define _COMPONENT          ACPI_TABLES
1662306a36Sopenharmony_ciACPI_MODULE_NAME("tbprint")
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* Local prototypes */
1962306a36Sopenharmony_cistatic void acpi_tb_fix_string(char *string, acpi_size length);
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistatic void
2262306a36Sopenharmony_ciacpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
2362306a36Sopenharmony_ci			     struct acpi_table_header *header);
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/*******************************************************************************
2662306a36Sopenharmony_ci *
2762306a36Sopenharmony_ci * FUNCTION:    acpi_tb_fix_string
2862306a36Sopenharmony_ci *
2962306a36Sopenharmony_ci * PARAMETERS:  string              - String to be repaired
3062306a36Sopenharmony_ci *              length              - Maximum length
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci * RETURN:      None
3362306a36Sopenharmony_ci *
3462306a36Sopenharmony_ci * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
3562306a36Sopenharmony_ci *              with a question mark '?'.
3662306a36Sopenharmony_ci *
3762306a36Sopenharmony_ci ******************************************************************************/
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistatic void acpi_tb_fix_string(char *string, acpi_size length)
4062306a36Sopenharmony_ci{
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	while (length && *string) {
4362306a36Sopenharmony_ci		if (!isprint((int)(u8)*string)) {
4462306a36Sopenharmony_ci			*string = '?';
4562306a36Sopenharmony_ci		}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci		string++;
4862306a36Sopenharmony_ci		length--;
4962306a36Sopenharmony_ci	}
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/*******************************************************************************
5362306a36Sopenharmony_ci *
5462306a36Sopenharmony_ci * FUNCTION:    acpi_tb_cleanup_table_header
5562306a36Sopenharmony_ci *
5662306a36Sopenharmony_ci * PARAMETERS:  out_header          - Where the cleaned header is returned
5762306a36Sopenharmony_ci *              header              - Input ACPI table header
5862306a36Sopenharmony_ci *
5962306a36Sopenharmony_ci * RETURN:      Returns the cleaned header in out_header
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci * DESCRIPTION: Copy the table header and ensure that all "string" fields in
6262306a36Sopenharmony_ci *              the header consist of printable characters.
6362306a36Sopenharmony_ci *
6462306a36Sopenharmony_ci ******************************************************************************/
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic void
6762306a36Sopenharmony_ciacpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
6862306a36Sopenharmony_ci			     struct acpi_table_header *header)
6962306a36Sopenharmony_ci{
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	memcpy(out_header, header, sizeof(struct acpi_table_header));
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	acpi_tb_fix_string(out_header->signature, ACPI_NAMESEG_SIZE);
7462306a36Sopenharmony_ci	acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
7562306a36Sopenharmony_ci	acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
7662306a36Sopenharmony_ci	acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAMESEG_SIZE);
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/*******************************************************************************
8062306a36Sopenharmony_ci *
8162306a36Sopenharmony_ci * FUNCTION:    acpi_tb_print_table_header
8262306a36Sopenharmony_ci *
8362306a36Sopenharmony_ci * PARAMETERS:  address             - Table physical address
8462306a36Sopenharmony_ci *              header              - Table header
8562306a36Sopenharmony_ci *
8662306a36Sopenharmony_ci * RETURN:      None
8762306a36Sopenharmony_ci *
8862306a36Sopenharmony_ci * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
8962306a36Sopenharmony_ci *
9062306a36Sopenharmony_ci ******************************************************************************/
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_civoid
9362306a36Sopenharmony_ciacpi_tb_print_table_header(acpi_physical_address address,
9462306a36Sopenharmony_ci			   struct acpi_table_header *header)
9562306a36Sopenharmony_ci{
9662306a36Sopenharmony_ci	struct acpi_table_header local_header;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) {
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci		/* FACS only has signature and length fields */
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci		ACPI_INFO(("%-4.4s 0x%8.8X%8.8X %06X",
10362306a36Sopenharmony_ci			   header->signature, ACPI_FORMAT_UINT64(address),
10462306a36Sopenharmony_ci			   header->length));
10562306a36Sopenharmony_ci	} else if (ACPI_VALIDATE_RSDP_SIG(ACPI_CAST_PTR(struct acpi_table_rsdp,
10662306a36Sopenharmony_ci							header)->signature)) {
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci		/* RSDP has no common fields */
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci		memcpy(local_header.oem_id,
11162306a36Sopenharmony_ci		       ACPI_CAST_PTR(struct acpi_table_rsdp, header)->oem_id,
11262306a36Sopenharmony_ci		       ACPI_OEM_ID_SIZE);
11362306a36Sopenharmony_ci		acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci		ACPI_INFO(("RSDP 0x%8.8X%8.8X %06X (v%.2d %-6.6s)",
11662306a36Sopenharmony_ci			   ACPI_FORMAT_UINT64(address),
11762306a36Sopenharmony_ci			   (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
11862306a36Sopenharmony_ci			    revision >
11962306a36Sopenharmony_ci			    0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
12062306a36Sopenharmony_ci					       header)->length : 20,
12162306a36Sopenharmony_ci			   ACPI_CAST_PTR(struct acpi_table_rsdp,
12262306a36Sopenharmony_ci					 header)->revision,
12362306a36Sopenharmony_ci			   local_header.oem_id));
12462306a36Sopenharmony_ci	} else {
12562306a36Sopenharmony_ci		/* Standard ACPI table with full common header */
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci		acpi_tb_cleanup_table_header(&local_header, header);
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci		ACPI_INFO(("%-4.4s 0x%8.8X%8.8X"
13062306a36Sopenharmony_ci			   " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)",
13162306a36Sopenharmony_ci			   local_header.signature, ACPI_FORMAT_UINT64(address),
13262306a36Sopenharmony_ci			   local_header.length, local_header.revision,
13362306a36Sopenharmony_ci			   local_header.oem_id, local_header.oem_table_id,
13462306a36Sopenharmony_ci			   local_header.oem_revision,
13562306a36Sopenharmony_ci			   local_header.asl_compiler_id,
13662306a36Sopenharmony_ci			   local_header.asl_compiler_revision));
13762306a36Sopenharmony_ci	}
13862306a36Sopenharmony_ci}
139