^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: tbprint - Table output utilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "actables.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define _COMPONENT ACPI_TABLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) ACPI_MODULE_NAME("tbprint")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Local prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static void acpi_tb_fix_string(char *string, acpi_size length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct acpi_table_header *header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * FUNCTION: acpi_tb_fix_string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * PARAMETERS: string - String to be repaired
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * length - Maximum length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * RETURN: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * with a question mark '?'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static void acpi_tb_fix_string(char *string, acpi_size length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) while (length && *string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (!isprint((int)*string)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *string = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) length--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * FUNCTION: acpi_tb_cleanup_table_header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * PARAMETERS: out_header - Where the cleaned header is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * header - Input ACPI table header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * RETURN: Returns the cleaned header in out_header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * DESCRIPTION: Copy the table header and ensure that all "string" fields in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * the header consist of printable characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct acpi_table_header *header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) memcpy(out_header, header, sizeof(struct acpi_table_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) acpi_tb_fix_string(out_header->signature, ACPI_NAMESEG_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAMESEG_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * FUNCTION: acpi_tb_print_table_header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * PARAMETERS: address - Table physical address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * header - Table header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * RETURN: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) acpi_tb_print_table_header(acpi_physical_address address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct acpi_table_header *header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct acpi_table_header local_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* FACS only has signature and length fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ACPI_INFO(("%-4.4s 0x%8.8X%8.8X %06X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) header->signature, ACPI_FORMAT_UINT64(address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) header->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) } else if (ACPI_VALIDATE_RSDP_SIG(header->signature)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* RSDP has no common fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) memcpy(local_header.oem_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ACPI_CAST_PTR(struct acpi_table_rsdp, header)->oem_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ACPI_OEM_ID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ACPI_INFO(("RSDP 0x%8.8X%8.8X %06X (v%.2d %-6.6s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ACPI_FORMAT_UINT64(address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) revision >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) header)->length : 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ACPI_CAST_PTR(struct acpi_table_rsdp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) header)->revision,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) local_header.oem_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Standard ACPI table with full common header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) acpi_tb_cleanup_table_header(&local_header, header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ACPI_INFO(("%-4.4s 0x%8.8X%8.8X"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) local_header.signature, ACPI_FORMAT_UINT64(address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) local_header.length, local_header.revision,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) local_header.oem_id, local_header.oem_table_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) local_header.oem_revision,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) local_header.asl_compiler_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) local_header.asl_compiler_revision));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * FUNCTION: acpi_tb_validate_checksum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * PARAMETERS: table - ACPI table to verify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * length - Length of entire table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * exception on bad checksum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u8 checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * FACS/S3PT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * They are the odd tables, have no standard ACPI header and no checksum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Compute the checksum on the table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Checksum ok? (should be zero) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (checksum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ACPI_BIOS_WARNING((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) "should be 0x%2.2X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) table->signature, table->checksum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) (u8)(table->checksum - checksum)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #if (ACPI_CHECKSUM_ABORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return (AE_BAD_CHECKSUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * FUNCTION: acpi_tb_checksum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * PARAMETERS: buffer - Pointer to memory region to be checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * length - Length of this memory region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * RETURN: Checksum (u8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * DESCRIPTION: Calculates circular checksum of memory region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u8 acpi_tb_checksum(u8 *buffer, u32 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u8 sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 *end = buffer + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) while (buffer < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) sum = (u8)(sum + *(buffer++));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return (sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }