1 /******************************************************************************
3 * Module Name: tbget - ACPI Table get* routines
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
32 #define RSDP_CHECKSUM_LENGTH 20
34 /*******************************************************************************
36 * FUNCTION: Acpi_tb_get_table_ptr
38 * PARAMETERS: Table_type - one of the defined table types
39 * Instance - Which table of this type
40 * Table_ptr_loc - pointer to location to place the pointer for
45 * DESCRIPTION: This function is called to get the pointer to an ACPI table.
47 ******************************************************************************/
50 acpi_tb_get_table_ptr (
51 ACPI_TABLE_TYPE table_type
,
53 ACPI_TABLE_HEADER
**table_ptr_loc
)
55 ACPI_TABLE_DESC
*table_desc
;
60 return (AE_NO_ACPI_TABLES
);
63 if (table_type
> ACPI_TABLE_MAX
) {
64 return (AE_BAD_PARAMETER
);
69 * For all table types (Single/Multiple), the first
70 * instance is always in the list head.
75 * Just pluck the pointer out of the global table!
76 * Will be null if no table is present
79 *table_ptr_loc
= acpi_gbl_acpi_tables
[table_type
].pointer
;
85 * Check for instance out of range
87 if (instance
> acpi_gbl_acpi_tables
[table_type
].count
) {
88 return (AE_NOT_EXIST
);
91 /* Walk the list to get the desired table
92 * Since the if (Instance == 1) check above checked for the
93 * first table, setting Table_desc equal to the .Next member
94 * is actually pointing to the second table. Therefore, we
95 * need to walk from the 2nd table until we reach the Instance
96 * that the user is looking for and return its table pointer.
98 table_desc
= acpi_gbl_acpi_tables
[table_type
].next
;
99 for (i
= 2; i
< instance
; i
++) {
100 table_desc
= table_desc
->next
;
103 /* We are now pointing to the requested table's descriptor */
105 *table_ptr_loc
= table_desc
->pointer
;
111 /*******************************************************************************
113 * FUNCTION: Acpi_tb_get_table
115 * PARAMETERS: Physical_address - Physical address of table to retrieve
116 * *Buffer_ptr - If Buffer_ptr is valid, read data from
117 * buffer rather than searching memory
118 * *Table_info - Where the table info is returned
122 * DESCRIPTION: Maps the physical address of table into a logical address
124 ******************************************************************************/
128 ACPI_PHYSICAL_ADDRESS physical_address
,
129 ACPI_TABLE_HEADER
*buffer_ptr
,
130 ACPI_TABLE_DESC
*table_info
)
132 ACPI_TABLE_HEADER
*table_header
= NULL
;
133 ACPI_TABLE_HEADER
*full_table
= NULL
;
136 ACPI_STATUS status
= AE_OK
;
140 return (AE_BAD_PARAMETER
);
146 * Getting data from a buffer, not BIOS tables
149 table_header
= buffer_ptr
;
150 status
= acpi_tb_validate_table_header (table_header
);
151 if (ACPI_FAILURE (status
)) {
152 /* Table failed verification, map all errors to BAD_DATA */
154 return (AE_BAD_DATA
);
157 /* Allocate buffer for the entire table */
159 full_table
= acpi_cm_allocate (table_header
->length
);
161 return (AE_NO_MEMORY
);
164 /* Copy the entire table (including header) to the local buffer */
166 size
= table_header
->length
;
167 MEMCPY (full_table
, buffer_ptr
, size
);
169 /* Save allocation type */
171 allocation
= ACPI_MEM_ALLOCATED
;
176 * Not reading from a buffer, just map the table's physical memory
177 * into our address space.
180 size
= SIZE_IN_HEADER
;
182 status
= acpi_tb_map_acpi_table (physical_address
, &size
,
183 (void **) &full_table
);
184 if (ACPI_FAILURE (status
)) {
188 /* Save allocation type */
190 allocation
= ACPI_MEM_MAPPED
;
196 table_info
->pointer
= full_table
;
197 table_info
->length
= size
;
198 table_info
->allocation
= allocation
;
199 table_info
->base_pointer
= full_table
;
205 /*******************************************************************************
207 * FUNCTION: Acpi_tb_get_all_tables
209 * PARAMETERS: Number_of_tables - Number of tables to get
210 * Table_ptr - Input buffer pointer, optional
214 * DESCRIPTION: Load and validate all tables other than the RSDT. The RSDT must
215 * already be loaded and validated.
217 ******************************************************************************/
220 acpi_tb_get_all_tables (
221 u32 number_of_tables
,
222 ACPI_TABLE_HEADER
*table_ptr
)
224 ACPI_STATUS status
= AE_OK
;
226 ACPI_TABLE_DESC table_info
;
230 * Loop through all table pointers found in RSDT.
231 * This will NOT include the FACS and DSDT - we must get
232 * them after the loop
235 for (index
= 0; index
< number_of_tables
; index
++) {
236 /* Clear the Table_info each time */
238 MEMSET (&table_info
, 0, sizeof (ACPI_TABLE_DESC
));
240 /* Get the table via the XSDT */
242 status
= acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS
)
243 ACPI_GET_ADDRESS (acpi_gbl_XSDT
->table_offset_entry
[index
]),
244 table_ptr
, &table_info
);
246 /* Ignore a table that failed verification */
248 if (status
== AE_BAD_DATA
) {
252 /* However, abort on serious errors */
254 if (ACPI_FAILURE (status
)) {
258 /* Recognize and install the table */
260 status
= acpi_tb_install_table (table_ptr
, &table_info
);
261 if (ACPI_FAILURE (status
)) {
263 * Unrecognized or unsupported table, delete it and ignore the
264 * error. Just get as many tables as we can, later we will
265 * determine if there are enough tables to continue.
268 acpi_tb_uninstall_table (&table_info
);
274 * Convert the FADT to a common format. This allows earlier revisions of the
275 * table to coexist with newer versions, using common access code.
277 status
= acpi_tb_convert_table_fadt ();
278 if (ACPI_FAILURE (status
)) {
284 * Get the minimum set of ACPI tables, namely:
286 * 1) FADT (via RSDT in loop above)
294 * Get the FACS (must have the FADT first, from loop above)
295 * Acpi_tb_get_table_facs will fail if FADT pointer is not valid
298 status
= acpi_tb_get_table_facs (table_ptr
, &table_info
);
299 if (ACPI_FAILURE (status
)) {
304 /* Install the FACS */
306 status
= acpi_tb_install_table (table_ptr
, &table_info
);
307 if (ACPI_FAILURE (status
)) {
312 * Create the common FACS pointer table
313 * (Contains pointers to the original table)
316 status
= acpi_tb_build_common_facs (&table_info
);
317 if (ACPI_FAILURE (status
)) {
323 * Get the DSDT (We know that the FADT is valid now)
326 status
= acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS
) ACPI_GET_ADDRESS (acpi_gbl_FADT
->Xdsdt
),
327 table_ptr
, &table_info
);
328 if (ACPI_FAILURE (status
)) {
332 /* Install the DSDT */
334 status
= acpi_tb_install_table (table_ptr
, &table_info
);
335 if (ACPI_FAILURE (status
)) {
339 /* Dump the DSDT Header */
341 /* Dump the entire DSDT */
344 * Initialize the capabilities flags.
345 * Assumes that platform supports ACPI_MODE since we have tables!
347 acpi_gbl_system_flags
|= acpi_hw_get_mode_capabilities ();
350 /* Always delete the RSDP mapping, we are done with it */
352 acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP
);
358 /*******************************************************************************
360 * FUNCTION: Acpi_tb_verify_rsdp
362 * PARAMETERS: Number_of_tables - Where the table count is placed
366 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
368 ******************************************************************************/
371 acpi_tb_verify_rsdp (
372 ACPI_PHYSICAL_ADDRESS rsdp_physical_address
)
374 ACPI_TABLE_DESC table_info
;
380 * Obtain access to the RSDP structure
382 status
= acpi_os_map_memory (rsdp_physical_address
,
383 sizeof (RSDP_DESCRIPTOR
),
384 (void **) &table_ptr
);
385 if (ACPI_FAILURE (status
)) {
390 * The signature and checksum must both be correct
392 if (STRNCMP ((NATIVE_CHAR
*) table_ptr
, RSDP_SIG
, sizeof (RSDP_SIG
)-1) != 0) {
393 /* Nope, BAD Signature */
395 status
= AE_BAD_SIGNATURE
;
399 if (acpi_tb_checksum (table_ptr
, RSDP_CHECKSUM_LENGTH
) != 0) {
400 /* Nope, BAD Checksum */
402 status
= AE_BAD_CHECKSUM
;
406 /* TBD: Check extended checksum if table version >= 2 */
408 /* The RSDP supplied is OK */
410 table_info
.pointer
= (ACPI_TABLE_HEADER
*) table_ptr
;
411 table_info
.length
= sizeof (RSDP_DESCRIPTOR
);
412 table_info
.allocation
= ACPI_MEM_MAPPED
;
413 table_info
.base_pointer
= table_ptr
;
415 /* Save the table pointers and allocation info */
417 status
= acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP
, &table_info
);
418 if (ACPI_FAILURE (status
)) {
423 /* Save the RSDP in a global for easy access */
425 acpi_gbl_RSDP
= (RSDP_DESCRIPTOR
*) table_info
.pointer
;
432 acpi_os_unmap_memory (table_ptr
, sizeof (RSDP_DESCRIPTOR
));
437 /*******************************************************************************
439 * FUNCTION: Acpi_tb_get_table_rsdt
441 * PARAMETERS: Number_of_tables - Where the table count is placed
445 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
447 ******************************************************************************/
450 acpi_tb_get_table_rsdt (
451 u32
*number_of_tables
)
453 ACPI_TABLE_DESC table_info
;
454 ACPI_STATUS status
= AE_OK
;
455 ACPI_PHYSICAL_ADDRESS physical_address
;
456 u32 signature_length
;
457 char *table_signature
;
461 * Get the RSDT from the RSDP
465 * For RSDP revision 0 or 1, we use the RSDT.
466 * For RSDP revision 2 (and above), we use the XSDT
468 if (acpi_gbl_RSDP
->revision
< 2) {
470 /* 0.71 RSDP has 64bit Rsdt address field */
471 physical_address
= ((RSDP_DESCRIPTOR_REV071
*)acpi_gbl_RSDP
)->rsdt_physical_address
;
473 physical_address
= (ACPI_PHYSICAL_ADDRESS
) acpi_gbl_RSDP
->rsdt_physical_address
;
475 table_signature
= RSDT_SIG
;
476 signature_length
= sizeof (RSDT_SIG
) -1;
479 physical_address
= (ACPI_PHYSICAL_ADDRESS
)
480 ACPI_GET_ADDRESS (acpi_gbl_RSDP
->xsdt_physical_address
);
481 table_signature
= XSDT_SIG
;
482 signature_length
= sizeof (XSDT_SIG
) -1;
486 /* Get the RSDT/XSDT */
488 status
= acpi_tb_get_table (physical_address
, NULL
, &table_info
);
489 if (ACPI_FAILURE (status
)) {
494 /* Check the RSDT or XSDT signature */
496 if (STRNCMP ((char *) table_info
.pointer
, table_signature
,
498 /* Invalid RSDT or XSDT signature */
500 REPORT_ERROR (("Invalid signature where RSDP indicates %s should be located\n",
503 return (AE_NO_ACPI_TABLES
);
507 /* Valid RSDT signature, verify the checksum */
509 status
= acpi_tb_verify_table_checksum (table_info
.pointer
);
512 /* Convert and/or copy to an XSDT structure */
514 status
= acpi_tb_convert_to_xsdt (&table_info
, number_of_tables
);
515 if (ACPI_FAILURE (status
)) {
519 /* Save the table pointers and allocation info */
521 status
= acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT
, &table_info
);
522 if (ACPI_FAILURE (status
)) {
526 acpi_gbl_XSDT
= (XSDT_DESCRIPTOR
*) table_info
.pointer
;
532 /******************************************************************************
534 * FUNCTION: Acpi_tb_get_table_facs
536 * PARAMETERS: *Buffer_ptr - If Buffer_ptr is valid, read data from
537 * buffer rather than searching memory
538 * *Table_info - Where the table info is returned
542 * DESCRIPTION: Returns a pointer to the FACS as defined in FADT. This
543 * function assumes the global variable FADT has been
544 * correctly initialized. The value of FADT->Firmware_ctrl
545 * into a far pointer which is returned.
547 *****************************************************************************/
550 acpi_tb_get_table_facs (
551 ACPI_TABLE_HEADER
*buffer_ptr
,
552 ACPI_TABLE_DESC
*table_info
)
554 void *table_ptr
= NULL
;
557 ACPI_STATUS status
= AE_OK
;
560 /* Must have a valid FADT pointer */
562 if (!acpi_gbl_FADT
) {
563 return (AE_NO_ACPI_TABLES
);
566 size
= sizeof (FACS_DESCRIPTOR
);
569 * Getting table from a file -- allocate a buffer and
572 table_ptr
= acpi_cm_allocate (size
);
574 return (AE_NO_MEMORY
);
577 MEMCPY (table_ptr
, buffer_ptr
, size
);
579 /* Save allocation type */
581 allocation
= ACPI_MEM_ALLOCATED
;
585 /* Just map the physical memory to our address space */
587 status
= acpi_tb_map_acpi_table ((ACPI_PHYSICAL_ADDRESS
) ACPI_GET_ADDRESS (acpi_gbl_FADT
->Xfirmware_ctrl
),
589 if (ACPI_FAILURE(status
)) {
593 /* Save allocation type */
595 allocation
= ACPI_MEM_MAPPED
;
601 table_info
->pointer
= table_ptr
;
602 table_info
->length
= size
;
603 table_info
->allocation
= allocation
;
604 table_info
->base_pointer
= table_ptr
;