1 /******************************************************************************
3 * Module Name: tbutils - Table manipulation utilities
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #define _COMPONENT ACPI_TABLES
33 MODULE_NAME ("tbutils")
36 /*******************************************************************************
38 * FUNCTION: Acpi_tb_handle_to_object
40 * PARAMETERS: Table_id - Id for which the function is searching
41 * Table_desc - Pointer to return the matching table
44 * RETURN: Search the tables to find one with a matching Table_id and
45 * return a pointer to that table descriptor.
47 ******************************************************************************/
50 acpi_tb_handle_to_object (
52 ACPI_TABLE_DESC **table_desc)
55 ACPI_TABLE_DESC *list_head;
58 for (i = 0; i < ACPI_TABLE_MAX; i++) {
59 list_head = &acpi_gbl_acpi_tables[i];
61 if (list_head->table_id == table_id) {
62 *table_desc = list_head;
66 list_head = list_head->next;
68 } while (list_head != &acpi_gbl_acpi_tables[i]);
72 return (AE_BAD_PARAMETER);
76 /*******************************************************************************
78 * FUNCTION: Acpi_tb_system_table_pointer
80 * PARAMETERS: *Where - Pointer to be examined
82 * RETURN: TRUE if Where is within the AML stream (in one of the ACPI
83 * system tables such as the DSDT or an SSDT.)
86 ******************************************************************************/
89 acpi_tb_system_table_pointer (
93 ACPI_TABLE_DESC *table_desc;
94 ACPI_TABLE_HEADER *table;
97 /* No function trace, called too often! */
100 /* Ignore null pointer */
107 /* Check for a pointer within the DSDT */
109 if ((acpi_gbl_DSDT) &&
110 (IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT))) {
115 /* Check each of the loaded SSDTs (if any)*/
117 table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT];
119 for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) {
120 table = table_desc->pointer;
122 if (IS_IN_ACPI_TABLE (where, table)) {
126 table_desc = table_desc->next;
130 /* Check each of the loaded PSDTs (if any)*/
132 table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT];
134 for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) {
135 table = table_desc->pointer;
137 if (IS_IN_ACPI_TABLE (where, table)) {
141 table_desc = table_desc->next;
145 /* Pointer does not point into any system table */
151 /*******************************************************************************
153 * FUNCTION: Acpi_tb_validate_table_header
155 * PARAMETERS: Table_header - Logical pointer to the table
159 * DESCRIPTION: Check an ACPI table header for validity
161 * NOTE: Table pointers are validated as follows:
162 * 1) Table pointer must point to valid physical memory
163 * 2) Signature must be 4 ASCII chars, even if we don't recognize the
165 * 3) Table must be readable for length specified in the header
166 * 4) Table checksum must be valid (with the exception of the FACS
167 * which has no checksum for some odd reason)
169 ******************************************************************************/
172 acpi_tb_validate_table_header (
173 ACPI_TABLE_HEADER *table_header)
178 /* Verify that this is a valid address */
180 if (!acpi_os_readable (table_header, sizeof (ACPI_TABLE_HEADER))) {
181 return (AE_BAD_ADDRESS);
185 /* Ensure that the signature is 4 ASCII characters */
187 MOVE_UNALIGNED32_TO_32 (&signature, &table_header->signature);
188 if (!acpi_cm_valid_acpi_name (signature)) {
189 REPORT_WARNING (("Invalid table signature found\n"));
190 return (AE_BAD_SIGNATURE);
194 /* Validate the table length */
196 if (table_header->length < sizeof (ACPI_TABLE_HEADER)) {
197 REPORT_WARNING (("Invalid table header length found\n"));
198 return (AE_BAD_HEADER);
205 /*******************************************************************************
207 * FUNCTION: Acpi_tb_map_acpi_table
209 * PARAMETERS: Physical_address - Physical address of table to map
210 * *Size - Size of the table. If zero, the size
211 * from the table header is used.
212 * Actual size is returned here.
213 * **Logical_address - Logical address of mapped table
215 * RETURN: Logical address of the mapped table.
217 * DESCRIPTION: Maps the physical address of table into a logical address
219 ******************************************************************************/
222 acpi_tb_map_acpi_table (
223 ACPI_PHYSICAL_ADDRESS physical_address,
225 void **logical_address)
227 ACPI_TABLE_HEADER *table;
228 u32 table_size = *size;
229 ACPI_STATUS status = AE_OK;
232 /* If size is zero, look at the table header to get the actual size */
235 /* Get the table header so we can extract the table length */
237 status = acpi_os_map_memory (physical_address, sizeof (ACPI_TABLE_HEADER),
239 if (ACPI_FAILURE (status)) {
243 /* Extract the full table length before we delete the mapping */
245 table_size = table->length;
248 * Validate the header and delete the mapping.
249 * We will create a mapping for the full table below.
252 status = acpi_tb_validate_table_header (table);
254 /* Always unmap the memory for the header */
256 acpi_os_unmap_memory (table, sizeof (ACPI_TABLE_HEADER));
258 /* Exit if header invalid */
260 if (ACPI_FAILURE (status)) {
266 /* Map the physical memory for the correct length */
268 status = acpi_os_map_memory (physical_address, table_size, (void **) &table);
269 if (ACPI_FAILURE (status)) {
274 *logical_address = table;
280 /*******************************************************************************
282 * FUNCTION: Acpi_tb_verify_table_checksum
284 * PARAMETERS: *Table_header - ACPI table to verify
286 * RETURN: 8 bit checksum of table
288 * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct
289 * table should have a checksum of 0.
291 ******************************************************************************/
294 acpi_tb_verify_table_checksum (
295 ACPI_TABLE_HEADER *table_header)
298 ACPI_STATUS status = AE_OK;
301 /* Compute the checksum on the table */
303 checksum = acpi_tb_checksum (table_header, table_header->length);
305 /* Return the appropriate exception */
308 REPORT_WARNING (("Invalid checksum (%X) in table %4.4s\n",
309 checksum, &table_header->signature));
311 status = AE_BAD_CHECKSUM;
319 /*******************************************************************************
321 * FUNCTION: Acpi_tb_checksum
323 * PARAMETERS: Buffer - Buffer to checksum
324 * Length - Size of the buffer
326 * RETURNS 8 bit checksum of buffer
328 * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
330 ******************************************************************************/
342 if (buffer && length) {
343 /* Buffer and Length are valid */
345 limit = (u8 *) buffer + length;
347 for (rover = buffer; rover < limit; rover++) {
348 sum = (u8) (sum + *rover);