1 /****************************************************************************** 2 * 3 * Module Name: tbprint - Table output utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "actables.h" 47 48 #define _COMPONENT ACPI_TABLES 49 ACPI_MODULE_NAME("tbprint") 50 51 /* Local prototypes */ 52 static void acpi_tb_fix_string(char *string, acpi_size length); 53 54 static void 55 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, 56 struct acpi_table_header *header); 57 58 /******************************************************************************* 59 * 60 * FUNCTION: acpi_tb_fix_string 61 * 62 * PARAMETERS: string - String to be repaired 63 * length - Maximum length 64 * 65 * RETURN: None 66 * 67 * DESCRIPTION: Replace every non-printable or non-ascii byte in the string 68 * with a question mark '?'. 69 * 70 ******************************************************************************/ 71 72 static void acpi_tb_fix_string(char *string, acpi_size length) 73 { 74 75 while (length && *string) { 76 if (!isprint((int)*string)) { 77 *string = '?'; 78 } 79 80 string++; 81 length--; 82 } 83 } 84 85 /******************************************************************************* 86 * 87 * FUNCTION: acpi_tb_cleanup_table_header 88 * 89 * PARAMETERS: out_header - Where the cleaned header is returned 90 * header - Input ACPI table header 91 * 92 * RETURN: Returns the cleaned header in out_header 93 * 94 * DESCRIPTION: Copy the table header and ensure that all "string" fields in 95 * the header consist of printable characters. 96 * 97 ******************************************************************************/ 98 99 static void 100 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, 101 struct acpi_table_header *header) 102 { 103 104 memcpy(out_header, header, sizeof(struct acpi_table_header)); 105 106 acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE); 107 acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE); 108 acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE); 109 acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE); 110 } 111 112 /******************************************************************************* 113 * 114 * FUNCTION: acpi_tb_print_table_header 115 * 116 * PARAMETERS: address - Table physical address 117 * header - Table header 118 * 119 * RETURN: None 120 * 121 * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. 122 * 123 ******************************************************************************/ 124 125 void 126 acpi_tb_print_table_header(acpi_physical_address address, 127 struct acpi_table_header *header) 128 { 129 struct acpi_table_header local_header; 130 131 if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { 132 133 /* FACS only has signature and length fields */ 134 135 ACPI_INFO(("%-4.4s 0x%8.8X%8.8X %06X", 136 header->signature, ACPI_FORMAT_UINT64(address), 137 header->length)); 138 } else if (ACPI_VALIDATE_RSDP_SIG(header->signature)) { 139 140 /* RSDP has no common fields */ 141 142 memcpy(local_header.oem_id, 143 ACPI_CAST_PTR(struct acpi_table_rsdp, header)->oem_id, 144 ACPI_OEM_ID_SIZE); 145 acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); 146 147 ACPI_INFO(("RSDP 0x%8.8X%8.8X %06X (v%.2d %-6.6s)", 148 ACPI_FORMAT_UINT64(address), 149 (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> 150 revision > 151 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, 152 header)->length : 20, 153 ACPI_CAST_PTR(struct acpi_table_rsdp, 154 header)->revision, 155 local_header.oem_id)); 156 } else { 157 /* Standard ACPI table with full common header */ 158 159 acpi_tb_cleanup_table_header(&local_header, header); 160 161 ACPI_INFO(("%-4.4s 0x%8.8X%8.8X" 162 " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)", 163 local_header.signature, ACPI_FORMAT_UINT64(address), 164 local_header.length, local_header.revision, 165 local_header.oem_id, local_header.oem_table_id, 166 local_header.oem_revision, 167 local_header.asl_compiler_id, 168 local_header.asl_compiler_revision)); 169 } 170 } 171 172 /******************************************************************************* 173 * 174 * FUNCTION: acpi_tb_validate_checksum 175 * 176 * PARAMETERS: table - ACPI table to verify 177 * length - Length of entire table 178 * 179 * RETURN: Status 180 * 181 * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns 182 * exception on bad checksum. 183 * 184 ******************************************************************************/ 185 186 acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) 187 { 188 u8 checksum; 189 190 /* 191 * FACS/S3PT: 192 * They are the odd tables, have no standard ACPI header and no checksum 193 */ 194 195 if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_S3PT) || 196 ACPI_COMPARE_NAME(table->signature, ACPI_SIG_FACS)) { 197 return (AE_OK); 198 } 199 200 /* Compute the checksum on the table */ 201 202 checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); 203 204 /* Checksum ok? (should be zero) */ 205 206 if (checksum) { 207 ACPI_BIOS_WARNING((AE_INFO, 208 "Incorrect checksum in table [%4.4s] - 0x%2.2X, " 209 "should be 0x%2.2X", 210 table->signature, table->checksum, 211 (u8)(table->checksum - checksum))); 212 213 #if (ACPI_CHECKSUM_ABORT) 214 return (AE_BAD_CHECKSUM); 215 #endif 216 } 217 218 return (AE_OK); 219 } 220 221 /******************************************************************************* 222 * 223 * FUNCTION: acpi_tb_checksum 224 * 225 * PARAMETERS: buffer - Pointer to memory region to be checked 226 * length - Length of this memory region 227 * 228 * RETURN: Checksum (u8) 229 * 230 * DESCRIPTION: Calculates circular checksum of memory region. 231 * 232 ******************************************************************************/ 233 234 u8 acpi_tb_checksum(u8 *buffer, u32 length) 235 { 236 u8 sum = 0; 237 u8 *end = buffer + length; 238 239 while (buffer < end) { 240 sum = (u8)(sum + *(buffer++)); 241 } 242 243 return (sum); 244 } 245