Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: tbprint - Table output utilities
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "actables.h"
0013 
0014 #define _COMPONENT          ACPI_TABLES
0015 ACPI_MODULE_NAME("tbprint")
0016 
0017 /* Local prototypes */
0018 static void acpi_tb_fix_string(char *string, acpi_size length);
0019 
0020 static void
0021 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
0022                  struct acpi_table_header *header);
0023 
0024 /*******************************************************************************
0025  *
0026  * FUNCTION:    acpi_tb_fix_string
0027  *
0028  * PARAMETERS:  string              - String to be repaired
0029  *              length              - Maximum length
0030  *
0031  * RETURN:      None
0032  *
0033  * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
0034  *              with a question mark '?'.
0035  *
0036  ******************************************************************************/
0037 
0038 static void acpi_tb_fix_string(char *string, acpi_size length)
0039 {
0040 
0041     while (length && *string) {
0042         if (!isprint((int)*string)) {
0043             *string = '?';
0044         }
0045 
0046         string++;
0047         length--;
0048     }
0049 }
0050 
0051 /*******************************************************************************
0052  *
0053  * FUNCTION:    acpi_tb_cleanup_table_header
0054  *
0055  * PARAMETERS:  out_header          - Where the cleaned header is returned
0056  *              header              - Input ACPI table header
0057  *
0058  * RETURN:      Returns the cleaned header in out_header
0059  *
0060  * DESCRIPTION: Copy the table header and ensure that all "string" fields in
0061  *              the header consist of printable characters.
0062  *
0063  ******************************************************************************/
0064 
0065 static void
0066 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
0067                  struct acpi_table_header *header)
0068 {
0069 
0070     memcpy(out_header, header, sizeof(struct acpi_table_header));
0071 
0072     acpi_tb_fix_string(out_header->signature, ACPI_NAMESEG_SIZE);
0073     acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
0074     acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
0075     acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAMESEG_SIZE);
0076 }
0077 
0078 /*******************************************************************************
0079  *
0080  * FUNCTION:    acpi_tb_print_table_header
0081  *
0082  * PARAMETERS:  address             - Table physical address
0083  *              header              - Table header
0084  *
0085  * RETURN:      None
0086  *
0087  * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
0088  *
0089  ******************************************************************************/
0090 
0091 void
0092 acpi_tb_print_table_header(acpi_physical_address address,
0093                struct acpi_table_header *header)
0094 {
0095     struct acpi_table_header local_header;
0096 
0097     if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) {
0098 
0099         /* FACS only has signature and length fields */
0100 
0101         ACPI_INFO(("%-4.4s 0x%8.8X%8.8X %06X",
0102                header->signature, ACPI_FORMAT_UINT64(address),
0103                header->length));
0104     } else if (ACPI_VALIDATE_RSDP_SIG(ACPI_CAST_PTR(struct acpi_table_rsdp,
0105                             header)->signature)) {
0106 
0107         /* RSDP has no common fields */
0108 
0109         memcpy(local_header.oem_id,
0110                ACPI_CAST_PTR(struct acpi_table_rsdp, header)->oem_id,
0111                ACPI_OEM_ID_SIZE);
0112         acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
0113 
0114         ACPI_INFO(("RSDP 0x%8.8X%8.8X %06X (v%.2d %-6.6s)",
0115                ACPI_FORMAT_UINT64(address),
0116                (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
0117                 revision >
0118                 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
0119                            header)->length : 20,
0120                ACPI_CAST_PTR(struct acpi_table_rsdp,
0121                      header)->revision,
0122                local_header.oem_id));
0123     } else {
0124         /* Standard ACPI table with full common header */
0125 
0126         acpi_tb_cleanup_table_header(&local_header, header);
0127 
0128         ACPI_INFO(("%-4.4s 0x%8.8X%8.8X"
0129                " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)",
0130                local_header.signature, ACPI_FORMAT_UINT64(address),
0131                local_header.length, local_header.revision,
0132                local_header.oem_id, local_header.oem_table_id,
0133                local_header.oem_revision,
0134                local_header.asl_compiler_id,
0135                local_header.asl_compiler_revision));
0136     }
0137 }
0138 
0139 /*******************************************************************************
0140  *
0141  * FUNCTION:    acpi_tb_validate_checksum
0142  *
0143  * PARAMETERS:  table               - ACPI table to verify
0144  *              length              - Length of entire table
0145  *
0146  * RETURN:      Status
0147  *
0148  * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
0149  *              exception on bad checksum.
0150  *
0151  ******************************************************************************/
0152 
0153 acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
0154 {
0155     u8 checksum;
0156 
0157     /*
0158      * FACS/S3PT:
0159      * They are the odd tables, have no standard ACPI header and no checksum
0160      */
0161 
0162     if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
0163         ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
0164         return (AE_OK);
0165     }
0166 
0167     /* Compute the checksum on the table */
0168 
0169     checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
0170 
0171     /* Checksum ok? (should be zero) */
0172 
0173     if (checksum) {
0174         ACPI_BIOS_WARNING((AE_INFO,
0175                    "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
0176                    "should be 0x%2.2X",
0177                    table->signature, table->checksum,
0178                    (u8)(table->checksum - checksum)));
0179 
0180 #if (ACPI_CHECKSUM_ABORT)
0181         return (AE_BAD_CHECKSUM);
0182 #endif
0183     }
0184 
0185     return (AE_OK);
0186 }
0187 
0188 /*******************************************************************************
0189  *
0190  * FUNCTION:    acpi_tb_checksum
0191  *
0192  * PARAMETERS:  buffer          - Pointer to memory region to be checked
0193  *              length          - Length of this memory region
0194  *
0195  * RETURN:      Checksum (u8)
0196  *
0197  * DESCRIPTION: Calculates circular checksum of memory region.
0198  *
0199  ******************************************************************************/
0200 
0201 u8 acpi_tb_checksum(u8 *buffer, u32 length)
0202 {
0203     u8 sum = 0;
0204     u8 *end = buffer + length;
0205 
0206     while (buffer < end) {
0207         sum = (u8)(sum + *(buffer++));
0208     }
0209 
0210     return (sum);
0211 }