2005-04-16 15:20:36 -07:00
/******************************************************************************
*
* Module Name : tbgetall - Get all required ACPI tables
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright ( C ) 2000 - 2005 , R . Byron Moore
* 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 <acpi/actables.h>
# define _COMPONENT ACPI_TABLES
2005-08-05 00:44:28 -04:00
ACPI_MODULE_NAME ( " tbgetall " )
2005-04-16 15:20:36 -07:00
2005-04-18 22:49:35 -04:00
/* Local prototypes */
static acpi_status
2005-08-05 00:44:28 -04:00
acpi_tb_get_primary_table ( struct acpi_pointer * address ,
struct acpi_table_desc * table_info ) ;
2005-04-18 22:49:35 -04:00
static acpi_status
2005-08-05 00:44:28 -04:00
acpi_tb_get_secondary_table ( struct acpi_pointer * address ,
acpi_string signature ,
struct acpi_table_desc * table_info ) ;
2005-04-16 15:20:36 -07:00
/*******************************************************************************
*
* FUNCTION : acpi_tb_get_primary_table
*
* PARAMETERS : Address - Physical address of table to retrieve
* * table_info - Where the table info is returned
*
* RETURN : Status
*
* DESCRIPTION : Maps the physical address of table into a logical address
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-18 22:49:35 -04:00
static acpi_status
2005-08-05 00:44:28 -04:00
acpi_tb_get_primary_table ( struct acpi_pointer * address ,
struct acpi_table_desc * table_info )
2005-04-16 15:20:36 -07:00
{
2005-08-05 00:44:28 -04:00
acpi_status status ;
struct acpi_table_header header ;
2005-04-16 15:20:36 -07:00
2005-08-05 00:44:28 -04:00
ACPI_FUNCTION_TRACE ( " tb_get_primary_table " ) ;
2005-04-16 15:20:36 -07:00
/* Ignore a NULL address in the RSDT */
if ( ! address - > pointer . value ) {
2005-08-05 00:44:28 -04:00
return_ACPI_STATUS ( AE_OK ) ;
2005-04-16 15:20:36 -07:00
}
2005-04-18 22:49:35 -04:00
/* Get the header in order to get signature and table size */
2005-08-05 00:44:28 -04:00
status = acpi_tb_get_table_header ( address , & header ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/* Clear the table_info */
2005-08-05 00:44:28 -04:00
ACPI_MEMSET ( table_info , 0 , sizeof ( struct acpi_table_desc ) ) ;
2005-04-16 15:20:36 -07:00
/*
* Check the table signature and make sure it is recognized .
* Also checks the header checksum
*/
table_info - > pointer = & header ;
2005-08-05 00:44:28 -04:00
status = acpi_tb_recognize_table ( table_info , ACPI_TABLE_PRIMARY ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/* Get the entire table */
2005-08-05 00:44:28 -04:00
status = acpi_tb_get_table_body ( address , & header , table_info ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/* Install the table */
2005-08-05 00:44:28 -04:00
status = acpi_tb_install_table ( table_info ) ;
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/*******************************************************************************
*
* FUNCTION : acpi_tb_get_secondary_table
*
* PARAMETERS : Address - Physical address of table to retrieve
* * table_info - Where the table info is returned
*
* RETURN : Status
*
* DESCRIPTION : Maps the physical address of table into a logical address
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-18 22:49:35 -04:00
static acpi_status
2005-08-05 00:44:28 -04:00
acpi_tb_get_secondary_table ( struct acpi_pointer * address ,
acpi_string signature ,
struct acpi_table_desc * table_info )
2005-04-16 15:20:36 -07:00
{
2005-08-05 00:44:28 -04:00
acpi_status status ;
struct acpi_table_header header ;
2005-04-16 15:20:36 -07:00
2005-08-05 00:44:28 -04:00
ACPI_FUNCTION_TRACE_STR ( " tb_get_secondary_table " , signature ) ;
2005-04-16 15:20:36 -07:00
/* Get the header in order to match the signature */
2005-08-05 00:44:28 -04:00
status = acpi_tb_get_table_header ( address , & header ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/* Signature must match request */
2005-08-05 00:44:28 -04:00
if ( ACPI_STRNCMP ( header . signature , signature , ACPI_NAME_SIZE ) ) {
ACPI_REPORT_ERROR ( ( " Incorrect table signature - wanted [%s] found [%4.4s] \n " , signature , header . signature ) ) ;
return_ACPI_STATUS ( AE_BAD_SIGNATURE ) ;
2005-04-16 15:20:36 -07:00
}
/*
* Check the table signature and make sure it is recognized .
* Also checks the header checksum
*/
table_info - > pointer = & header ;
2005-08-05 00:44:28 -04:00
status = acpi_tb_recognize_table ( table_info , ACPI_TABLE_SECONDARY ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/* Get the entire table */
2005-08-05 00:44:28 -04:00
status = acpi_tb_get_table_body ( address , & header , table_info ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/* Install the table */
2005-08-05 00:44:28 -04:00
status = acpi_tb_install_table ( table_info ) ;
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/*******************************************************************************
*
* FUNCTION : acpi_tb_get_required_tables
*
* PARAMETERS : None
*
* RETURN : Status
*
* DESCRIPTION : Load and validate tables other than the RSDT . The RSDT must
* already be loaded and validated .
*
* Get the minimum set of ACPI tables , namely :
*
* 1 ) FADT ( via RSDT in loop below )
* 2 ) FACS ( via FADT )
* 3 ) DSDT ( via FADT )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-08-05 00:44:28 -04:00
acpi_status acpi_tb_get_required_tables ( void )
2005-04-16 15:20:36 -07:00
{
2005-08-05 00:44:28 -04:00
acpi_status status = AE_OK ;
u32 i ;
struct acpi_table_desc table_info ;
struct acpi_pointer address ;
2005-04-16 15:20:36 -07:00
2005-08-05 00:44:28 -04:00
ACPI_FUNCTION_TRACE ( " tb_get_required_tables " ) ;
2005-04-16 15:20:36 -07:00
2005-08-05 00:44:28 -04:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_INFO , " %d ACPI tables in RSDT \n " ,
acpi_gbl_rsdt_table_count ) ) ;
2005-04-16 15:20:36 -07:00
2005-08-05 00:44:28 -04:00
address . pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING ;
2005-04-16 15:20:36 -07:00
/*
* Loop through all table pointers found in RSDT .
* This will NOT include the FACS and DSDT - we must get
* them after the loop .
*
* The only tables we are interested in getting here is the FADT and
* any SSDTs .
*/
for ( i = 0 ; i < acpi_gbl_rsdt_table_count ; i + + ) {
/* Get the table address from the common internal XSDT */
2005-08-05 00:44:28 -04:00
address . pointer . value = acpi_gbl_XSDT - > table_offset_entry [ i ] ;
2005-04-16 15:20:36 -07:00
/*
* Get the tables needed by this subsystem ( FADT and any SSDTs ) .
* NOTE : All other tables are completely ignored at this time .
*/
2005-08-05 00:44:28 -04:00
status = acpi_tb_get_primary_table ( & address , & table_info ) ;
2005-04-16 15:20:36 -07:00
if ( ( status ! = AE_OK ) & & ( status ! = AE_TABLE_NOT_SUPPORTED ) ) {
2005-08-05 00:44:28 -04:00
ACPI_REPORT_WARNING ( ( " %s, while getting table at %8.8X%8.8X \n " , acpi_format_exception ( status ) , ACPI_FORMAT_UINT64 ( address . pointer . value ) ) ) ;
2005-04-16 15:20:36 -07:00
}
}
/* We must have a FADT to continue */
if ( ! acpi_gbl_FADT ) {
2005-08-05 00:44:28 -04:00
ACPI_REPORT_ERROR ( ( " No FADT present in RSDT/XSDT \n " ) ) ;
return_ACPI_STATUS ( AE_NO_ACPI_TABLES ) ;
2005-04-16 15:20:36 -07:00
}
/*
2005-04-18 22:49:35 -04:00
* Convert the FADT to a common format . This allows earlier revisions of
* the table to coexist with newer versions , using common access code .
2005-04-16 15:20:36 -07:00
*/
2005-08-05 00:44:28 -04:00
status = acpi_tb_convert_table_fadt ( ) ;
if ( ACPI_FAILURE ( status ) ) {
ACPI_REPORT_ERROR ( ( " Could not convert FADT to internal common format \n " ) ) ;
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
2005-04-18 22:49:35 -04:00
/* Get the FACS (Pointed to by the FADT) */
2005-04-16 15:20:36 -07:00
address . pointer . value = acpi_gbl_FADT - > xfirmware_ctrl ;
2005-08-05 00:44:28 -04:00
status = acpi_tb_get_secondary_table ( & address , FACS_SIG , & table_info ) ;
if ( ACPI_FAILURE ( status ) ) {
ACPI_REPORT_ERROR ( ( " Could not get/install the FACS, %s \n " ,
acpi_format_exception ( status ) ) ) ;
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/*
* Create the common FACS pointer table
* ( Contains pointers to the original table )
*/
2005-08-05 00:44:28 -04:00
status = acpi_tb_build_common_facs ( & table_info ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
2005-04-18 22:49:35 -04:00
/* Get/install the DSDT (Pointed to by the FADT) */
2005-04-16 15:20:36 -07:00
address . pointer . value = acpi_gbl_FADT - > Xdsdt ;
2005-08-05 00:44:28 -04:00
status = acpi_tb_get_secondary_table ( & address , DSDT_SIG , & table_info ) ;
if ( ACPI_FAILURE ( status ) ) {
ACPI_REPORT_ERROR ( ( " Could not get/install the DSDT \n " ) ) ;
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}
/* Set Integer Width (32/64) based upon DSDT revision */
2005-08-05 00:44:28 -04:00
acpi_ut_set_integer_width ( acpi_gbl_DSDT - > revision ) ;
2005-04-16 15:20:36 -07:00
/* Dump the entire DSDT */
2005-08-05 00:44:28 -04:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_TABLES ,
" Hex dump of entire DSDT, size %d (0x%X), Integer width = %d \n " ,
acpi_gbl_DSDT - > length , acpi_gbl_DSDT - > length ,
acpi_gbl_integer_bit_width ) ) ;
ACPI_DUMP_BUFFER ( ( u8 * ) acpi_gbl_DSDT , acpi_gbl_DSDT - > length ) ;
2005-04-16 15:20:36 -07:00
/* Always delete the RSDP mapping, we are done with it */
2005-08-05 00:44:28 -04:00
acpi_tb_delete_tables_by_type ( ACPI_TABLE_RSDP ) ;
return_ACPI_STATUS ( status ) ;
2005-04-16 15:20:36 -07:00
}