| 
									
										
										
										
											2013-06-08 00:59:02 +00:00
										 |  |  | /******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Module Name: tbprint - Table output utilities | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (C) 2000 - 2013, Intel Corp. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions | 
					
						
							|  |  |  |  * are met: | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  |  *    notice, this list of conditions, and the following disclaimer, | 
					
						
							|  |  |  |  *    without modification. | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce at minimum a disclaimer | 
					
						
							|  |  |  |  *    substantially similar to the "NO WARRANTY" disclaimer below | 
					
						
							|  |  |  |  *    ("Disclaimer") and any redistribution must be conditioned upon | 
					
						
							|  |  |  |  *    including a substantially similar Disclaimer requirement for further | 
					
						
							|  |  |  |  *    binary redistribution. | 
					
						
							|  |  |  |  * 3. Neither the names of the above-listed copyright holders nor the names | 
					
						
							|  |  |  |  *    of any contributors may be used to endorse or promote products derived | 
					
						
							|  |  |  |  *    from this software without specific prior written permission. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Alternatively, this software may be distributed under the terms of the | 
					
						
							|  |  |  |  * GNU General Public License ("GPL") version 2 as published by the Free | 
					
						
							|  |  |  |  * Software Foundation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * NO WARRANTY | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
					
						
							|  |  |  |  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
					
						
							|  |  |  |  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | 
					
						
							|  |  |  |  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
					
						
							|  |  |  |  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
					
						
							|  |  |  |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
					
						
							|  |  |  |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 
					
						
							|  |  |  |  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | 
					
						
							|  |  |  |  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
					
						
							|  |  |  |  * POSSIBILITY OF SUCH DAMAGES. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <acpi/acpi.h>
 | 
					
						
							|  |  |  | #include "accommon.h"
 | 
					
						
							|  |  |  | #include "actables.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define _COMPONENT          ACPI_TABLES
 | 
					
						
							|  |  |  | ACPI_MODULE_NAME("tbprint") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Local prototypes */ | 
					
						
							|  |  |  | static void acpi_tb_fix_string(char *string, acpi_size length); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, | 
					
						
							|  |  |  | 			     struct acpi_table_header *header); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_tb_fix_string | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  string              - String to be repaired | 
					
						
							|  |  |  |  *              length              - Maximum length | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      None | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Replace every non-printable or non-ascii byte in the string | 
					
						
							|  |  |  |  *              with a question mark '?'. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void acpi_tb_fix_string(char *string, acpi_size length) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (length && *string) { | 
					
						
							|  |  |  | 		if (!ACPI_IS_PRINT(*string)) { | 
					
						
							|  |  |  | 			*string = '?'; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		string++; | 
					
						
							|  |  |  | 		length--; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_tb_cleanup_table_header | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  out_header          - Where the cleaned header is returned | 
					
						
							|  |  |  |  *              header              - Input ACPI table header | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      Returns the cleaned header in out_header | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Copy the table header and ensure that all "string" fields in | 
					
						
							|  |  |  |  *              the header consist of printable characters. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, | 
					
						
							|  |  |  | 			     struct acpi_table_header *header) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE); | 
					
						
							|  |  |  | 	acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE); | 
					
						
							|  |  |  | 	acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE); | 
					
						
							|  |  |  | 	acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_tb_print_table_header | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  address             - Table physical address | 
					
						
							|  |  |  |  *              header              - Table header | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      None | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | acpi_tb_print_table_header(acpi_physical_address address, | 
					
						
							|  |  |  | 			   struct acpi_table_header *header) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct acpi_table_header local_header; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The reason that the Address is cast to a void pointer is so that we | 
					
						
							|  |  |  | 	 * can use %p which will work properly on both 32-bit and 64-bit hosts. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* FACS only has signature and length fields */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-29 09:28:56 +08:00
										 |  |  | 		ACPI_INFO((AE_INFO, "%4.4s %p %06X", | 
					
						
							| 
									
										
										
										
											2013-06-08 00:59:02 +00:00
										 |  |  | 			   header->signature, ACPI_CAST_PTR(void, address), | 
					
						
							|  |  |  | 			   header->length)); | 
					
						
							| 
									
										
										
										
											2013-09-23 09:52:34 +08:00
										 |  |  | 	} else if (ACPI_VALIDATE_RSDP_SIG(header->signature)) { | 
					
						
							| 
									
										
										
										
											2013-06-08 00:59:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* RSDP has no common fields */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ACPI_MEMCPY(local_header.oem_id, | 
					
						
							|  |  |  | 			    ACPI_CAST_PTR(struct acpi_table_rsdp, | 
					
						
							|  |  |  | 					  header)->oem_id, ACPI_OEM_ID_SIZE); | 
					
						
							|  |  |  | 		acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-29 09:28:56 +08:00
										 |  |  | 		ACPI_INFO((AE_INFO, "RSDP %p %06X (v%.2d %6.6s)", | 
					
						
							| 
									
										
										
										
											2013-06-08 00:59:02 +00:00
										 |  |  | 			   ACPI_CAST_PTR(void, address), | 
					
						
							|  |  |  | 			   (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> | 
					
						
							|  |  |  | 			    revision > | 
					
						
							|  |  |  | 			    0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, | 
					
						
							|  |  |  | 					       header)->length : 20, | 
					
						
							|  |  |  | 			   ACPI_CAST_PTR(struct acpi_table_rsdp, | 
					
						
							|  |  |  | 					 header)->revision, | 
					
						
							|  |  |  | 			   local_header.oem_id)); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		/* Standard ACPI table with full common header */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		acpi_tb_cleanup_table_header(&local_header, header); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ACPI_INFO((AE_INFO, | 
					
						
							| 
									
										
										
										
											2013-10-29 09:28:56 +08:00
										 |  |  | 			   "%4.4s %p %06X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", | 
					
						
							| 
									
										
										
										
											2013-06-08 00:59:02 +00:00
										 |  |  | 			   local_header.signature, ACPI_CAST_PTR(void, address), | 
					
						
							|  |  |  | 			   local_header.length, local_header.revision, | 
					
						
							|  |  |  | 			   local_header.oem_id, local_header.oem_table_id, | 
					
						
							|  |  |  | 			   local_header.oem_revision, | 
					
						
							|  |  |  | 			   local_header.asl_compiler_id, | 
					
						
							|  |  |  | 			   local_header.asl_compiler_revision)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_tb_validate_checksum | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  table               - ACPI table to verify | 
					
						
							|  |  |  |  *              length              - Length of entire table | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      Status | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns | 
					
						
							|  |  |  |  *              exception on bad checksum. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u8 checksum; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-23 09:52:29 +08:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * FACS/S3PT: | 
					
						
							|  |  |  | 	 * They are the odd tables, have no standard ACPI header and no checksum | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_S3PT) || | 
					
						
							|  |  |  | 	    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_FACS)) { | 
					
						
							|  |  |  | 		return (AE_OK); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-08 00:59:02 +00:00
										 |  |  | 	/* Compute the checksum on the table */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Checksum ok? (should be zero) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (checksum) { | 
					
						
							|  |  |  | 		ACPI_BIOS_WARNING((AE_INFO, | 
					
						
							|  |  |  | 				   "Incorrect checksum in table [%4.4s] - 0x%2.2X, " | 
					
						
							|  |  |  | 				   "should be 0x%2.2X", | 
					
						
							|  |  |  | 				   table->signature, table->checksum, | 
					
						
							|  |  |  | 				   (u8)(table->checksum - checksum))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if (ACPI_CHECKSUM_ABORT)
 | 
					
						
							|  |  |  | 		return (AE_BAD_CHECKSUM); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (AE_OK); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_tb_checksum | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  buffer          - Pointer to memory region to be checked | 
					
						
							|  |  |  |  *              length          - Length of this memory region | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      Checksum (u8) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Calculates circular checksum of memory region. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u8 acpi_tb_checksum(u8 *buffer, u32 length) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u8 sum = 0; | 
					
						
							|  |  |  | 	u8 *end = buffer + length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (buffer < end) { | 
					
						
							|  |  |  | 		sum = (u8)(sum + *(buffer++)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (sum); | 
					
						
							|  |  |  | } |