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
29 #define _COMPONENT ACPI_TABLES
30 MODULE_NAME ("tbutils")
33 /*******************************************************************************
35 * FUNCTION: Acpi_tb_handle_to_object
37 * PARAMETERS: Table_id - Id for which the function is searching
38 * Table_desc - Pointer to return the matching table
41 * RETURN: Search the tables to find one with a matching Table_id and
42 * return a pointer to that table descriptor.
44 ******************************************************************************/
47 acpi_tb_handle_to_object (
49 ACPI_TABLE_DESC
**table_desc
)
52 ACPI_TABLE_DESC
*list_head
;
55 for (i
= 0; i
< ACPI_TABLE_MAX
; i
++) {
56 list_head
= &acpi_gbl_acpi_tables
[i
];
58 if (list_head
->table_id
== table_id
) {
59 *table_desc
= list_head
;
63 list_head
= list_head
->next
;
65 } while (list_head
!= &acpi_gbl_acpi_tables
[i
]);
69 return (AE_BAD_PARAMETER
);
73 /*******************************************************************************
75 * FUNCTION: Acpi_tb_system_table_pointer
77 * PARAMETERS: *Where - Pointer to be examined
79 * RETURN: TRUE if Where is within the AML stream (in one of the ACPI
80 * system tables such as the DSDT or an SSDT.)
83 ******************************************************************************/
86 acpi_tb_system_table_pointer (
90 ACPI_TABLE_DESC
*table_desc
;
91 ACPI_TABLE_HEADER
*table
;
94 /* No function trace, called too often! */
97 /* Ignore null pointer */
104 /* Check for a pointer within the DSDT */
106 if ((acpi_gbl_DSDT
) &&
107 (IS_IN_ACPI_TABLE (where
, acpi_gbl_DSDT
))) {
112 /* Check each of the loaded SSDTs (if any)*/
114 table_desc
= &acpi_gbl_acpi_tables
[ACPI_TABLE_SSDT
];
116 for (i
= 0; i
< acpi_gbl_acpi_tables
[ACPI_TABLE_SSDT
].count
; i
++) {
117 table
= table_desc
->pointer
;
119 if (IS_IN_ACPI_TABLE (where
, table
)) {
123 table_desc
= table_desc
->next
;
127 /* Check each of the loaded PSDTs (if any)*/
129 table_desc
= &acpi_gbl_acpi_tables
[ACPI_TABLE_PSDT
];
131 for (i
= 0; i
< acpi_gbl_acpi_tables
[ACPI_TABLE_PSDT
].count
; i
++) {
132 table
= table_desc
->pointer
;
134 if (IS_IN_ACPI_TABLE (where
, table
)) {
138 table_desc
= table_desc
->next
;
142 /* Pointer does not point into any system table */
148 /*******************************************************************************
150 * FUNCTION: Acpi_tb_validate_table_header
152 * PARAMETERS: Table_header - Logical pointer to the table
156 * DESCRIPTION: Check an ACPI table header for validity
158 * NOTE: Table pointers are validated as follows:
159 * 1) Table pointer must point to valid physical memory
160 * 2) Signature must be 4 ASCII chars, even if we don't recognize the
162 * 3) Table must be readable for length specified in the header
163 * 4) Table checksum must be valid (with the exception of the FACS
164 * which has no checksum for some odd reason)
166 ******************************************************************************/
169 acpi_tb_validate_table_header (
170 ACPI_TABLE_HEADER
*table_header
)
175 /* Verify that this is a valid address */
177 if (!acpi_os_readable (table_header
, sizeof (ACPI_TABLE_HEADER
))) {
178 return (AE_BAD_ADDRESS
);
182 /* Ensure that the signature is 4 ASCII characters */
184 MOVE_UNALIGNED32_TO_32 (&signature
, &table_header
->signature
);
185 if (!acpi_cm_valid_acpi_name (signature
)) {
186 REPORT_WARNING (("Invalid table signature found\n"));
187 return (AE_BAD_SIGNATURE
);
191 /* Validate the table length */
193 if (table_header
->length
< sizeof (ACPI_TABLE_HEADER
)) {
194 REPORT_WARNING (("Invalid table header length found\n"));
195 return (AE_BAD_HEADER
);
202 /*******************************************************************************
204 * FUNCTION: Acpi_tb_map_acpi_table
206 * PARAMETERS: Physical_address - Physical address of table to map
207 * *Size - Size of the table. If zero, the size
208 * from the table header is used.
209 * Actual size is returned here.
210 * **Logical_address - Logical address of mapped table
212 * RETURN: Logical address of the mapped table.
214 * DESCRIPTION: Maps the physical address of table into a logical address
216 ******************************************************************************/
219 acpi_tb_map_acpi_table (
220 ACPI_PHYSICAL_ADDRESS physical_address
,
222 void **logical_address
)
224 ACPI_TABLE_HEADER
*table
;
225 u32 table_size
= *size
;
226 ACPI_STATUS status
= AE_OK
;
229 /* If size is zero, look at the table header to get the actual size */
232 /* Get the table header so we can extract the table length */
234 status
= acpi_os_map_memory (physical_address
, sizeof (ACPI_TABLE_HEADER
),
236 if (ACPI_FAILURE (status
)) {
240 /* Extract the full table length before we delete the mapping */
242 table_size
= table
->length
;
245 * Validate the header and delete the mapping.
246 * We will create a mapping for the full table below.
249 status
= acpi_tb_validate_table_header (table
);
251 /* Always unmap the memory for the header */
253 acpi_os_unmap_memory (table
, sizeof (ACPI_TABLE_HEADER
));
255 /* Exit if header invalid */
257 if (ACPI_FAILURE (status
)) {
263 /* Map the physical memory for the correct length */
265 status
= acpi_os_map_memory (physical_address
, table_size
, (void **) &table
);
266 if (ACPI_FAILURE (status
)) {
271 *logical_address
= table
;
277 /*******************************************************************************
279 * FUNCTION: Acpi_tb_verify_table_checksum
281 * PARAMETERS: *Table_header - ACPI table to verify
283 * RETURN: 8 bit checksum of table
285 * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct
286 * table should have a checksum of 0.
288 ******************************************************************************/
291 acpi_tb_verify_table_checksum (
292 ACPI_TABLE_HEADER
*table_header
)
295 ACPI_STATUS status
= AE_OK
;
298 /* Compute the checksum on the table */
300 checksum
= acpi_tb_checksum (table_header
, table_header
->length
);
302 /* Return the appropriate exception */
305 REPORT_WARNING (("Invalid checksum (%X) in table %4.4s\n",
306 checksum
, &table_header
->signature
));
308 status
= AE_BAD_CHECKSUM
;
316 /*******************************************************************************
318 * FUNCTION: Acpi_tb_checksum
320 * PARAMETERS: Buffer - Buffer to checksum
321 * Length - Size of the buffer
323 * RETURNS 8 bit checksum of buffer
325 * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
327 ******************************************************************************/
339 if (buffer
&& length
) {
340 /* Buffer and Length are valid */
342 limit
= (u8
*) buffer
+ length
;
344 for (rover
= buffer
; rover
< limit
; rover
++) {
345 sum
= (u8
) (sum
+ *rover
);