142f47869SBob Moore /****************************************************************************** 242f47869SBob Moore * 342f47869SBob Moore * Module Name: tbprint - Table output utilities 442f47869SBob Moore * 542f47869SBob Moore *****************************************************************************/ 642f47869SBob Moore 742f47869SBob Moore /* 842f47869SBob Moore * Copyright (C) 2000 - 2013, Intel Corp. 942f47869SBob Moore * All rights reserved. 1042f47869SBob Moore * 1142f47869SBob Moore * Redistribution and use in source and binary forms, with or without 1242f47869SBob Moore * modification, are permitted provided that the following conditions 1342f47869SBob Moore * are met: 1442f47869SBob Moore * 1. Redistributions of source code must retain the above copyright 1542f47869SBob Moore * notice, this list of conditions, and the following disclaimer, 1642f47869SBob Moore * without modification. 1742f47869SBob Moore * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1842f47869SBob Moore * substantially similar to the "NO WARRANTY" disclaimer below 1942f47869SBob Moore * ("Disclaimer") and any redistribution must be conditioned upon 2042f47869SBob Moore * including a substantially similar Disclaimer requirement for further 2142f47869SBob Moore * binary redistribution. 2242f47869SBob Moore * 3. Neither the names of the above-listed copyright holders nor the names 2342f47869SBob Moore * of any contributors may be used to endorse or promote products derived 2442f47869SBob Moore * from this software without specific prior written permission. 2542f47869SBob Moore * 2642f47869SBob Moore * Alternatively, this software may be distributed under the terms of the 2742f47869SBob Moore * GNU General Public License ("GPL") version 2 as published by the Free 2842f47869SBob Moore * Software Foundation. 2942f47869SBob Moore * 3042f47869SBob Moore * NO WARRANTY 3142f47869SBob Moore * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3242f47869SBob Moore * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3342f47869SBob Moore * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3442f47869SBob Moore * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3542f47869SBob Moore * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3642f47869SBob Moore * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3742f47869SBob Moore * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3842f47869SBob Moore * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3942f47869SBob Moore * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4042f47869SBob Moore * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4142f47869SBob Moore * POSSIBILITY OF SUCH DAMAGES. 4242f47869SBob Moore */ 4342f47869SBob Moore 4442f47869SBob Moore #include <acpi/acpi.h> 4542f47869SBob Moore #include "accommon.h" 4642f47869SBob Moore #include "actables.h" 4742f47869SBob Moore 4842f47869SBob Moore #define _COMPONENT ACPI_TABLES 4942f47869SBob Moore ACPI_MODULE_NAME("tbprint") 5042f47869SBob Moore 5142f47869SBob Moore /* Local prototypes */ 5242f47869SBob Moore static void acpi_tb_fix_string(char *string, acpi_size length); 5342f47869SBob Moore 5442f47869SBob Moore static void 5542f47869SBob Moore acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, 5642f47869SBob Moore struct acpi_table_header *header); 5742f47869SBob Moore 5842f47869SBob Moore /******************************************************************************* 5942f47869SBob Moore * 6042f47869SBob Moore * FUNCTION: acpi_tb_fix_string 6142f47869SBob Moore * 6242f47869SBob Moore * PARAMETERS: string - String to be repaired 6342f47869SBob Moore * length - Maximum length 6442f47869SBob Moore * 6542f47869SBob Moore * RETURN: None 6642f47869SBob Moore * 6742f47869SBob Moore * DESCRIPTION: Replace every non-printable or non-ascii byte in the string 6842f47869SBob Moore * with a question mark '?'. 6942f47869SBob Moore * 7042f47869SBob Moore ******************************************************************************/ 7142f47869SBob Moore 7242f47869SBob Moore static void acpi_tb_fix_string(char *string, acpi_size length) 7342f47869SBob Moore { 7442f47869SBob Moore 7542f47869SBob Moore while (length && *string) { 7642f47869SBob Moore if (!ACPI_IS_PRINT(*string)) { 7742f47869SBob Moore *string = '?'; 7842f47869SBob Moore } 7942f47869SBob Moore string++; 8042f47869SBob Moore length--; 8142f47869SBob Moore } 8242f47869SBob Moore } 8342f47869SBob Moore 8442f47869SBob Moore /******************************************************************************* 8542f47869SBob Moore * 8642f47869SBob Moore * FUNCTION: acpi_tb_cleanup_table_header 8742f47869SBob Moore * 8842f47869SBob Moore * PARAMETERS: out_header - Where the cleaned header is returned 8942f47869SBob Moore * header - Input ACPI table header 9042f47869SBob Moore * 9142f47869SBob Moore * RETURN: Returns the cleaned header in out_header 9242f47869SBob Moore * 9342f47869SBob Moore * DESCRIPTION: Copy the table header and ensure that all "string" fields in 9442f47869SBob Moore * the header consist of printable characters. 9542f47869SBob Moore * 9642f47869SBob Moore ******************************************************************************/ 9742f47869SBob Moore 9842f47869SBob Moore static void 9942f47869SBob Moore acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, 10042f47869SBob Moore struct acpi_table_header *header) 10142f47869SBob Moore { 10242f47869SBob Moore 10342f47869SBob Moore ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header)); 10442f47869SBob Moore 10542f47869SBob Moore acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE); 10642f47869SBob Moore acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE); 10742f47869SBob Moore acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE); 10842f47869SBob Moore acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE); 10942f47869SBob Moore } 11042f47869SBob Moore 11142f47869SBob Moore /******************************************************************************* 11242f47869SBob Moore * 11342f47869SBob Moore * FUNCTION: acpi_tb_print_table_header 11442f47869SBob Moore * 11542f47869SBob Moore * PARAMETERS: address - Table physical address 11642f47869SBob Moore * header - Table header 11742f47869SBob Moore * 11842f47869SBob Moore * RETURN: None 11942f47869SBob Moore * 12042f47869SBob Moore * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. 12142f47869SBob Moore * 12242f47869SBob Moore ******************************************************************************/ 12342f47869SBob Moore 12442f47869SBob Moore void 12542f47869SBob Moore acpi_tb_print_table_header(acpi_physical_address address, 12642f47869SBob Moore struct acpi_table_header *header) 12742f47869SBob Moore { 12842f47869SBob Moore struct acpi_table_header local_header; 12942f47869SBob Moore 13042f47869SBob Moore /* 13142f47869SBob Moore * The reason that the Address is cast to a void pointer is so that we 13242f47869SBob Moore * can use %p which will work properly on both 32-bit and 64-bit hosts. 13342f47869SBob Moore */ 13442f47869SBob Moore if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { 13542f47869SBob Moore 13642f47869SBob Moore /* FACS only has signature and length fields */ 13742f47869SBob Moore 13842f47869SBob Moore ACPI_INFO((AE_INFO, "%4.4s %p %05X", 13942f47869SBob Moore header->signature, ACPI_CAST_PTR(void, address), 14042f47869SBob Moore header->length)); 14142f47869SBob Moore } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) { 14242f47869SBob Moore 14342f47869SBob Moore /* RSDP has no common fields */ 14442f47869SBob Moore 14542f47869SBob Moore ACPI_MEMCPY(local_header.oem_id, 14642f47869SBob Moore ACPI_CAST_PTR(struct acpi_table_rsdp, 14742f47869SBob Moore header)->oem_id, ACPI_OEM_ID_SIZE); 14842f47869SBob Moore acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); 14942f47869SBob Moore 15042f47869SBob Moore ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", 15142f47869SBob Moore ACPI_CAST_PTR(void, address), 15242f47869SBob Moore (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> 15342f47869SBob Moore revision > 15442f47869SBob Moore 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, 15542f47869SBob Moore header)->length : 20, 15642f47869SBob Moore ACPI_CAST_PTR(struct acpi_table_rsdp, 15742f47869SBob Moore header)->revision, 15842f47869SBob Moore local_header.oem_id)); 15942f47869SBob Moore } else { 16042f47869SBob Moore /* Standard ACPI table with full common header */ 16142f47869SBob Moore 16242f47869SBob Moore acpi_tb_cleanup_table_header(&local_header, header); 16342f47869SBob Moore 16442f47869SBob Moore ACPI_INFO((AE_INFO, 16542f47869SBob Moore "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", 16642f47869SBob Moore local_header.signature, ACPI_CAST_PTR(void, address), 16742f47869SBob Moore local_header.length, local_header.revision, 16842f47869SBob Moore local_header.oem_id, local_header.oem_table_id, 16942f47869SBob Moore local_header.oem_revision, 17042f47869SBob Moore local_header.asl_compiler_id, 17142f47869SBob Moore local_header.asl_compiler_revision)); 17242f47869SBob Moore } 17342f47869SBob Moore } 17442f47869SBob Moore 17542f47869SBob Moore /******************************************************************************* 17642f47869SBob Moore * 17742f47869SBob Moore * FUNCTION: acpi_tb_validate_checksum 17842f47869SBob Moore * 17942f47869SBob Moore * PARAMETERS: table - ACPI table to verify 18042f47869SBob Moore * length - Length of entire table 18142f47869SBob Moore * 18242f47869SBob Moore * RETURN: Status 18342f47869SBob Moore * 18442f47869SBob Moore * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns 18542f47869SBob Moore * exception on bad checksum. 18642f47869SBob Moore * 18742f47869SBob Moore ******************************************************************************/ 18842f47869SBob Moore 18942f47869SBob Moore acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) 19042f47869SBob Moore { 19142f47869SBob Moore u8 checksum; 19242f47869SBob Moore 19342f47869SBob Moore /* Compute the checksum on the table */ 19442f47869SBob Moore 19542f47869SBob Moore checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); 19642f47869SBob Moore 19742f47869SBob Moore /* Checksum ok? (should be zero) */ 19842f47869SBob Moore 19942f47869SBob Moore if (checksum) { 20042f47869SBob Moore ACPI_BIOS_WARNING((AE_INFO, 20142f47869SBob Moore "Incorrect checksum in table [%4.4s] - 0x%2.2X, " 20242f47869SBob Moore "should be 0x%2.2X", 20342f47869SBob Moore table->signature, table->checksum, 20442f47869SBob Moore (u8)(table->checksum - checksum))); 20542f47869SBob Moore 20642f47869SBob Moore #if (ACPI_CHECKSUM_ABORT) 20742f47869SBob Moore return (AE_BAD_CHECKSUM); 20842f47869SBob Moore #endif 20942f47869SBob Moore } 21042f47869SBob Moore 21142f47869SBob Moore return (AE_OK); 21242f47869SBob Moore } 21342f47869SBob Moore 21442f47869SBob Moore /******************************************************************************* 21542f47869SBob Moore * 21642f47869SBob Moore * FUNCTION: acpi_tb_checksum 21742f47869SBob Moore * 21842f47869SBob Moore * PARAMETERS: buffer - Pointer to memory region to be checked 21942f47869SBob Moore * length - Length of this memory region 22042f47869SBob Moore * 22142f47869SBob Moore * RETURN: Checksum (u8) 22242f47869SBob Moore * 22342f47869SBob Moore * DESCRIPTION: Calculates circular checksum of memory region. 22442f47869SBob Moore * 22542f47869SBob Moore ******************************************************************************/ 22642f47869SBob Moore 22742f47869SBob Moore u8 acpi_tb_checksum(u8 *buffer, u32 length) 22842f47869SBob Moore { 22942f47869SBob Moore u8 sum = 0; 23042f47869SBob Moore u8 *end = buffer + length; 23142f47869SBob Moore 23242f47869SBob Moore while (buffer < end) { 23342f47869SBob Moore sum = (u8)(sum + *(buffer++)); 23442f47869SBob Moore } 23542f47869SBob Moore 23642f47869SBob Moore return (sum); 23742f47869SBob Moore } 238