提交 c9b77a40 编写于 作者: R Rafael J. Wysocki

Merge back earlier ACPICA material.

Conflicts:
	drivers/acpi/acpica/acglobal.h
...@@ -237,7 +237,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ...@@ -237,7 +237,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
This feature is enabled by default. This feature is enabled by default.
This option allows to turn off the feature. This option allows to turn off the feature.
acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT acpi_no_static_ssdt [HW,ACPI]
Disable installation of static SSDTs at early boot time
By default, SSDTs contained in the RSDT/XSDT will be
installed automatically and they will appear under
/sys/firmware/acpi/tables.
This option turns off this feature.
Note that specifying this option does not affect
dynamic table installation which will install SSDT
tables to /sys/firmware/acpi/tables/dynamic.
acpica_no_return_repair [HW, ACPI] acpica_no_return_repair [HW, ACPI]
Disable AML predefined validation mechanism Disable AML predefined validation mechanism
......
...@@ -135,6 +135,7 @@ acpi-y += \ ...@@ -135,6 +135,7 @@ acpi-y += \
rsxface.o rsxface.o
acpi-y += \ acpi-y += \
tbdata.o \
tbfadt.o \ tbfadt.o \
tbfind.o \ tbfind.o \
tbinstal.o \ tbinstal.o \
......
/******************************************************************************
*
* Module Name: acapps - common include for ACPI applications/tools
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, 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.
*/
#ifndef _ACAPPS
#define _ACAPPS
/* Common info for tool signons */
#define ACPICA_NAME "Intel ACPI Component Architecture"
#define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2014 Intel Corporation"
#if ACPI_MACHINE_WIDTH == 64
#define ACPI_WIDTH "-64"
#elif ACPI_MACHINE_WIDTH == 32
#define ACPI_WIDTH "-32"
#else
#error unknown ACPI_MACHINE_WIDTH
#define ACPI_WIDTH "-??"
#endif
/* Macros for signons and file headers */
#define ACPI_COMMON_SIGNON(utility_name) \
"\n%s\n%s version %8.8X%s [%s]\n%s\n\n", \
ACPICA_NAME, \
utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \
ACPICA_COPYRIGHT
#define ACPI_COMMON_HEADER(utility_name, prefix) \
"%s%s\n%s%s version %8.8X%s [%s]\n%s%s\n%s\n", \
prefix, ACPICA_NAME, \
prefix, utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \
prefix, ACPICA_COPYRIGHT, \
prefix
/* Macros for usage messages */
#define ACPI_USAGE_HEADER(usage) \
printf ("Usage: %s\nOptions:\n", usage);
#define ACPI_OPTION(name, description) \
printf (" %-18s%s\n", name, description);
#define FILE_SUFFIX_DISASSEMBLY "dsl"
#define ACPI_TABLE_FILE_SUFFIX ".dat"
/*
* getopt
*/
int acpi_getopt(int argc, char **argv, char *opts);
int acpi_getopt_argument(int argc, char **argv);
extern int acpi_gbl_optind;
extern int acpi_gbl_opterr;
extern int acpi_gbl_sub_opt_char;
extern char *acpi_gbl_optarg;
/*
* cmfsize - Common get file size function
*/
u32 cm_get_file_size(FILE * file);
#ifndef ACPI_DUMP_APP
/*
* adisasm
*/
acpi_status
ad_aml_disassemble(u8 out_to_file,
char *filename, char *prefix, char **out_filename);
void ad_print_statistics(void);
acpi_status ad_find_dsdt(u8 **dsdt_ptr, u32 *dsdt_length);
void ad_dump_tables(void);
acpi_status ad_get_local_tables(void);
acpi_status
ad_parse_table(struct acpi_table_header *table,
acpi_owner_id * owner_id, u8 load_table, u8 external);
acpi_status ad_display_tables(char *filename, struct acpi_table_header *table);
acpi_status ad_display_statistics(void);
/*
* adwalk
*/
void
acpi_dm_cross_reference_namespace(union acpi_parse_object *parse_tree_root,
struct acpi_namespace_node *namespace_root,
acpi_owner_id owner_id);
void acpi_dm_dump_tree(union acpi_parse_object *origin);
void acpi_dm_find_orphan_methods(union acpi_parse_object *origin);
void
acpi_dm_finish_namespace_load(union acpi_parse_object *parse_tree_root,
struct acpi_namespace_node *namespace_root,
acpi_owner_id owner_id);
void
acpi_dm_convert_resource_indexes(union acpi_parse_object *parse_tree_root,
struct acpi_namespace_node *namespace_root);
/*
* adfile
*/
acpi_status ad_initialize(void);
char *fl_generate_filename(char *input_filename, char *suffix);
acpi_status
fl_split_input_pathname(char *input_path,
char **out_directory_path, char **out_filename);
char *ad_generate_filename(char *prefix, char *table_id);
void
ad_write_table(struct acpi_table_header *table,
u32 length, char *table_name, char *oem_table_id);
#endif
#endif /* _ACAPPS */
...@@ -104,9 +104,10 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info); ...@@ -104,9 +104,10 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info);
*/ */
acpi_status acpi_status
acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
struct acpi_generic_address *gpe_block_address, u64 address,
u8 space_id,
u32 register_count, u32 register_count,
u8 gpe_block_base_number, u16 gpe_block_base_number,
u32 interrupt_number, u32 interrupt_number,
struct acpi_gpe_block_info **return_gpe_block); struct acpi_gpe_block_info **return_gpe_block);
......
...@@ -44,144 +44,14 @@ ...@@ -44,144 +44,14 @@
#ifndef __ACGLOBAL_H__ #ifndef __ACGLOBAL_H__
#define __ACGLOBAL_H__ #define __ACGLOBAL_H__
/*
* Ensure that the globals are actually defined and initialized only once.
*
* The use of these macros allows a single list of globals (here) in order
* to simplify maintenance of the code.
*/
#ifdef DEFINE_ACPI_GLOBALS
#define ACPI_GLOBAL(type,name) \
extern type name; \
type name
#define ACPI_INIT_GLOBAL(type,name,value) \
type name=value
#else
#define ACPI_GLOBAL(type,name) \
extern type name
#define ACPI_INIT_GLOBAL(type,name,value) \
extern type name
#endif
#ifdef DEFINE_ACPI_GLOBALS
/* Public globals, available from outside ACPICA subsystem */
/***************************************************************************** /*****************************************************************************
* *
* Runtime configuration (static defaults that can be overriden at runtime) * Globals related to the ACPI tables
* *
****************************************************************************/ ****************************************************************************/
/* /* Master list of all ACPI tables that were found in the RSDT/XSDT */
* Enable "slack" in the AML interpreter? Default is FALSE, and the
* interpreter strictly follows the ACPI specification. Setting to TRUE
* allows the interpreter to ignore certain errors and/or bad AML constructs.
*
* Currently, these features are enabled by this flag:
*
* 1) Allow "implicit return" of last value in a control method
* 2) Allow access beyond the end of an operation region
* 3) Allow access to uninitialized locals/args (auto-init to integer 0)
* 4) Allow ANY object type to be a source operand for the Store() operator
* 5) Allow unresolved references (invalid target name) in package objects
* 6) Enable warning messages for behavior that is not ACPI spec compliant
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_interpreter_slack, FALSE);
/*
* Automatically serialize all methods that create named objects? Default
* is TRUE, meaning that all non_serialized methods are scanned once at
* table load time to determine those that create named objects. Methods
* that create named objects are marked Serialized in order to prevent
* possible run-time problems if they are entered by more than one thread.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, TRUE);
/*
* Create the predefined _OSI method in the namespace? Default is TRUE
* because ACPI CA is fully compatible with other ACPI implementations.
* Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE);
/*
* Optionally use default values for the ACPI register widths. Set this to
* TRUE to use the defaults, if an FADT contains incorrect widths/lengths.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE);
/*
* Optionally enable output from the AML Debug Object.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_aml_debug_object, FALSE);
/*
* Optionally copy the entire DSDT to local memory (instead of simply
* mapping it.) There are some BIOSs that corrupt or replace the original
* DSDT, creating the need for this option. Default is FALSE, do not copy
* the DSDT.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_copy_dsdt_locally, FALSE);
/*
* Optionally ignore an XSDT if present and use the RSDT instead.
* Although the ACPI specification requires that an XSDT be used instead
* of the RSDT, the XSDT has been found to be corrupt or ill-formed on
* some machines. Default behavior is to use the XSDT if present.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE);
/*
* Optionally use 32-bit FADT addresses if and when there is a conflict
* (address mismatch) between the 32-bit and 64-bit versions of the
* address. Although ACPICA adheres to the ACPI specification which
* requires the use of the corresponding 64-bit address if it is non-zero,
* some machines have been found to have a corrupted non-zero 64-bit
* address. Default is TRUE, favor the 32-bit addresses.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, TRUE);
/*
* Optionally truncate I/O addresses to 16 bits. Provides compatibility
* with other ACPI implementations. NOTE: During ACPICA initialization,
* this value is set to TRUE if any Windows OSI strings have been
* requested by the BIOS.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_truncate_io_addresses, FALSE);
/*
* Disable runtime checking and repair of values returned by control methods.
* Use only if the repair is causing a problem on a particular machine.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_auto_repair, FALSE);
/*
* Optionally do not load any SSDTs from the RSDT/XSDT during initialization.
* This can be useful for debugging ACPI problems on some machines.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_ssdt_table_load, FALSE);
/*
* We keep track of the latest version of Windows that has been requested by
* the BIOS.
*/
ACPI_INIT_GLOBAL(u8, acpi_gbl_osi_data, 0);
#endif /* DEFINE_ACPI_GLOBALS */
/*****************************************************************************
*
* ACPI Table globals
*
****************************************************************************/
/*
* Master list of all ACPI tables that were found in the RSDT/XSDT.
*/
ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list); ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list);
/* DSDT information. Used to check for DSDT corruption */ /* DSDT information. Used to check for DSDT corruption */
...@@ -279,7 +149,6 @@ ACPI_GLOBAL(acpi_exception_handler, acpi_gbl_exception_handler); ...@@ -279,7 +149,6 @@ ACPI_GLOBAL(acpi_exception_handler, acpi_gbl_exception_handler);
ACPI_GLOBAL(acpi_init_handler, acpi_gbl_init_handler); ACPI_GLOBAL(acpi_init_handler, acpi_gbl_init_handler);
ACPI_GLOBAL(acpi_table_handler, acpi_gbl_table_handler); ACPI_GLOBAL(acpi_table_handler, acpi_gbl_table_handler);
ACPI_GLOBAL(void *, acpi_gbl_table_handler_context); ACPI_GLOBAL(void *, acpi_gbl_table_handler_context);
ACPI_GLOBAL(struct acpi_walk_state *, acpi_gbl_breakpoint_walk);
ACPI_GLOBAL(acpi_interface_handler, acpi_gbl_interface_handler); ACPI_GLOBAL(acpi_interface_handler, acpi_gbl_interface_handler);
ACPI_GLOBAL(struct acpi_sci_handler_info *, acpi_gbl_sci_handler_list); ACPI_GLOBAL(struct acpi_sci_handler_info *, acpi_gbl_sci_handler_list);
...@@ -296,7 +165,6 @@ ACPI_GLOBAL(u8, acpi_gbl_reg_methods_executed); ...@@ -296,7 +165,6 @@ ACPI_GLOBAL(u8, acpi_gbl_reg_methods_executed);
/* Misc */ /* Misc */
ACPI_GLOBAL(u32, acpi_gbl_original_mode); ACPI_GLOBAL(u32, acpi_gbl_original_mode);
ACPI_GLOBAL(u32, acpi_gbl_rsdp_original_location);
ACPI_GLOBAL(u32, acpi_gbl_ns_lookup_count); ACPI_GLOBAL(u32, acpi_gbl_ns_lookup_count);
ACPI_GLOBAL(u32, acpi_gbl_ps_find_count); ACPI_GLOBAL(u32, acpi_gbl_ps_find_count);
ACPI_GLOBAL(u16, acpi_gbl_pm1_enable_register_save); ACPI_GLOBAL(u16, acpi_gbl_pm1_enable_register_save);
...@@ -483,11 +351,6 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc); ...@@ -483,11 +351,6 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc);
ACPI_GLOBAL(u32, acpi_gbl_num_nodes); ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
ACPI_GLOBAL(u32, acpi_gbl_num_objects); ACPI_GLOBAL(u32, acpi_gbl_num_objects);
ACPI_GLOBAL(u32, acpi_gbl_size_of_parse_tree);
ACPI_GLOBAL(u32, acpi_gbl_size_of_method_trees);
ACPI_GLOBAL(u32, acpi_gbl_size_of_node_entries);
ACPI_GLOBAL(u32, acpi_gbl_size_of_acpi_objects);
#endif /* ACPI_DEBUGGER */ #endif /* ACPI_DEBUGGER */
/***************************************************************************** /*****************************************************************************
...@@ -509,5 +372,6 @@ ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); ...@@ -509,5 +372,6 @@ ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL);
****************************************************************************/ ****************************************************************************/
extern const struct ah_predefined_name asl_predefined_info[]; extern const struct ah_predefined_name asl_predefined_info[];
extern const struct ah_device_id asl_device_ids[];
#endif /* __ACGLOBAL_H__ */ #endif /* __ACGLOBAL_H__ */
...@@ -450,9 +450,9 @@ struct acpi_gpe_event_info { ...@@ -450,9 +450,9 @@ struct acpi_gpe_event_info {
struct acpi_gpe_register_info { struct acpi_gpe_register_info {
struct acpi_generic_address status_address; /* Address of status reg */ struct acpi_generic_address status_address; /* Address of status reg */
struct acpi_generic_address enable_address; /* Address of enable reg */ struct acpi_generic_address enable_address; /* Address of enable reg */
u16 base_gpe_number; /* Base GPE number for this register */
u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ u8 enable_for_wake; /* GPEs to keep enabled when sleeping */
u8 enable_for_run; /* GPEs to keep enabled when running */ u8 enable_for_run; /* GPEs to keep enabled when running */
u8 base_gpe_number; /* Base GPE number for this register */
}; };
/* /*
...@@ -466,11 +466,12 @@ struct acpi_gpe_block_info { ...@@ -466,11 +466,12 @@ struct acpi_gpe_block_info {
struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */ struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */
struct acpi_gpe_register_info *register_info; /* One per GPE register pair */ struct acpi_gpe_register_info *register_info; /* One per GPE register pair */
struct acpi_gpe_event_info *event_info; /* One for each GPE */ struct acpi_gpe_event_info *event_info; /* One for each GPE */
struct acpi_generic_address block_address; /* Base address of the block */ u64 address; /* Base address of the block */
u32 register_count; /* Number of register pairs in block */ u32 register_count; /* Number of register pairs in block */
u16 gpe_count; /* Number of individual GPEs in block */ u16 gpe_count; /* Number of individual GPEs in block */
u8 block_base_number; /* Base GPE number for this block */ u16 block_base_number; /* Base GPE number for this block */
u8 initialized; /* TRUE if this block is initialized */ u8 space_id;
u8 initialized; /* TRUE if this block is initialized */
}; };
/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
...@@ -733,7 +734,8 @@ union acpi_parse_value { ...@@ -733,7 +734,8 @@ union acpi_parse_value {
#define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ #define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */
#define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ #define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */
#define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ #define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */
#define ACPI_DASM_IGNORE 0x09 /* Not used at this time */ #define ACPI_DASM_HID_STRING 0x09 /* String is a _HID or _CID */
#define ACPI_DASM_IGNORE 0x0A /* Not used at this time */
/* /*
* Generic operation (for example: If, While, Store) * Generic operation (for example: If, While, Store)
...@@ -1147,4 +1149,9 @@ struct ah_predefined_name { ...@@ -1147,4 +1149,9 @@ struct ah_predefined_name {
#endif #endif
}; };
struct ah_device_id {
char *name;
char *description;
};
#endif /* __ACLOCAL_H__ */ #endif /* __ACLOCAL_H__ */
...@@ -586,6 +586,10 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { ...@@ -586,6 +586,10 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = {
{{"_LID", METHOD_0ARGS, {{"_LID", METHOD_0ARGS,
METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, METHOD_RETURNS(ACPI_RTYPE_INTEGER)}},
{{"_LPD", METHOD_0ARGS,
METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (1 Int(rev), n Pkg (2 Int) */
PACKAGE_INFO(ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_INTEGER, 2, 0, 0, 0),
{{"_MAT", METHOD_0ARGS, {{"_MAT", METHOD_0ARGS,
METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, METHOD_RETURNS(ACPI_RTYPE_BUFFER)}},
......
...@@ -53,6 +53,26 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); ...@@ -53,6 +53,26 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length);
/*
* tbdata - table data structure management
*/
acpi_status acpi_tb_get_next_root_index(u32 *table_index);
void
acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
acpi_physical_address address,
u8 flags, struct acpi_table_header *table);
acpi_status
acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
acpi_physical_address address, u8 flags);
void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc);
u8 acpi_tb_is_table_loaded(u32 table_index);
void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded);
/* /*
* tbfadt - FADT parse/convert/validate * tbfadt - FADT parse/convert/validate
*/ */
...@@ -72,22 +92,35 @@ acpi_tb_find_table(char *signature, ...@@ -72,22 +92,35 @@ acpi_tb_find_table(char *signature,
*/ */
acpi_status acpi_tb_resize_root_table_list(void); acpi_status acpi_tb_resize_root_table_list(void);
acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc);
struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc);
*table_header,
struct acpi_table_desc
*table_desc);
acpi_status acpi_status
acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index); acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature);
void acpi_tb_override_table(struct acpi_table_desc *old_table_desc);
acpi_status
acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
struct acpi_table_header **table_ptr,
u32 *table_length, u8 *table_flags);
void
acpi_tb_release_table(struct acpi_table_header *table,
u32 table_length, u8 table_flags);
acpi_status
acpi_tb_install_standard_table(acpi_physical_address address,
u8 flags,
u8 reload, u8 override, u32 *table_index);
acpi_status acpi_status
acpi_tb_store_table(acpi_physical_address address, acpi_tb_store_table(acpi_physical_address address,
struct acpi_table_header *table, struct acpi_table_header *table,
u32 length, u8 flags, u32 *table_index); u32 length, u8 flags, u32 *table_index);
void acpi_tb_delete_table(struct acpi_table_desc *table_desc); void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc);
void acpi_tb_terminate(void); void acpi_tb_terminate(void);
...@@ -99,10 +132,6 @@ acpi_status acpi_tb_release_owner_id(u32 table_index); ...@@ -99,10 +132,6 @@ acpi_status acpi_tb_release_owner_id(u32 table_index);
acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id); acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id);
u8 acpi_tb_is_table_loaded(u32 table_index);
void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded);
/* /*
* tbutils - table manager utilities * tbutils - table manager utilities
*/ */
...@@ -124,8 +153,13 @@ void acpi_tb_check_dsdt_header(void); ...@@ -124,8 +153,13 @@ void acpi_tb_check_dsdt_header(void);
struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index);
void void
acpi_tb_install_table(acpi_physical_address address, acpi_tb_install_table_with_override(u32 table_index,
char *signature, u32 table_index); struct acpi_table_desc *new_table_desc,
u8 override);
acpi_status
acpi_tb_install_fixed_table(acpi_physical_address address,
char *signature, u32 table_index);
acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
......
...@@ -176,8 +176,7 @@ acpi_status acpi_ut_init_globals(void); ...@@ -176,8 +176,7 @@ acpi_status acpi_ut_init_globals(void);
char *acpi_ut_get_mutex_name(u32 mutex_id); char *acpi_ut_get_mutex_name(u32 mutex_id);
const char *acpi_ut_get_notify_name(u32 notify_value); const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type);
#endif #endif
char *acpi_ut_get_type_name(acpi_object_type type); char *acpi_ut_get_type_name(acpi_object_type type);
...@@ -737,4 +736,11 @@ acpi_ut_method_error(const char *module_name, ...@@ -737,4 +736,11 @@ acpi_ut_method_error(const char *module_name,
struct acpi_namespace_node *node, struct acpi_namespace_node *node,
const char *path, acpi_status lookup_status); const char *path, acpi_status lookup_status);
/*
* Utility functions for ACPI names and IDs
*/
const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg);
const struct ah_device_id *acpi_ah_match_hardware_id(char *hid);
#endif /* _ACUTILS_H */ #endif /* _ACUTILS_H */
...@@ -383,7 +383,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) ...@@ -383,7 +383,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
if (!(gpe_register_info->enable_for_run | if (!(gpe_register_info->enable_for_run |
gpe_register_info->enable_for_wake)) { gpe_register_info->enable_for_wake)) {
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
"Ignore disabled registers for GPE%02X-GPE%02X: " "Ignore disabled registers for GPE %02X-%02X: "
"RunEnable=%02X, WakeEnable=%02X\n", "RunEnable=%02X, WakeEnable=%02X\n",
gpe_register_info-> gpe_register_info->
base_gpe_number, base_gpe_number,
...@@ -416,7 +416,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) ...@@ -416,7 +416,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
} }
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
"Read registers for GPE%02X-GPE%02X: Status=%02X, Enable=%02X, " "Read registers for GPE %02X-%02X: Status=%02X, Enable=%02X, "
"RunEnable=%02X, WakeEnable=%02X\n", "RunEnable=%02X, WakeEnable=%02X\n",
gpe_register_info->base_gpe_number, gpe_register_info->base_gpe_number,
gpe_register_info->base_gpe_number + gpe_register_info->base_gpe_number +
...@@ -706,7 +706,8 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, ...@@ -706,7 +706,8 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
status = acpi_hw_clear_gpe(gpe_event_info); status = acpi_hw_clear_gpe(gpe_event_info);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, ACPI_EXCEPTION((AE_INFO, status,
"Unable to clear GPE%02X", gpe_number)); "Unable to clear GPE %02X",
gpe_number));
return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
} }
} }
...@@ -723,7 +724,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, ...@@ -723,7 +724,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, ACPI_EXCEPTION((AE_INFO, status,
"Unable to disable GPE%02X", gpe_number)); "Unable to disable GPE %02X", gpe_number));
return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
} }
...@@ -764,7 +765,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, ...@@ -764,7 +765,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
gpe_event_info); gpe_event_info);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, ACPI_EXCEPTION((AE_INFO, status,
"Unable to queue handler for GPE%02X - event disabled", "Unable to queue handler for GPE %02X - event disabled",
gpe_number)); gpe_number));
} }
break; break;
...@@ -776,7 +777,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, ...@@ -776,7 +777,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
* a GPE to be enabled if it has no handler or method. * a GPE to be enabled if it has no handler or method.
*/ */
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"No handler or method for GPE%02X, disabling event", "No handler or method for GPE %02X, disabling event",
gpe_number)); gpe_number));
break; break;
......
...@@ -252,21 +252,17 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) ...@@ -252,21 +252,17 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
/* Init the register_info for this GPE register (8 GPEs) */ /* Init the register_info for this GPE register (8 GPEs) */
this_register->base_gpe_number = this_register->base_gpe_number = (u16)
(u8) (gpe_block->block_base_number + (gpe_block->block_base_number +
(i * ACPI_GPE_REGISTER_WIDTH)); (i * ACPI_GPE_REGISTER_WIDTH));
this_register->status_address.address = this_register->status_address.address = gpe_block->address + i;
gpe_block->block_address.address + i;
this_register->enable_address.address = this_register->enable_address.address =
gpe_block->block_address.address + i + gpe_block->address + i + gpe_block->register_count;
gpe_block->register_count;
this_register->status_address.space_id = this_register->status_address.space_id = gpe_block->space_id;
gpe_block->block_address.space_id; this_register->enable_address.space_id = gpe_block->space_id;
this_register->enable_address.space_id =
gpe_block->block_address.space_id;
this_register->status_address.bit_width = this_register->status_address.bit_width =
ACPI_GPE_REGISTER_WIDTH; ACPI_GPE_REGISTER_WIDTH;
this_register->enable_address.bit_width = this_register->enable_address.bit_width =
...@@ -334,9 +330,10 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) ...@@ -334,9 +330,10 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
acpi_status acpi_status
acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
struct acpi_generic_address *gpe_block_address, u64 address,
u8 space_id,
u32 register_count, u32 register_count,
u8 gpe_block_base_number, u16 gpe_block_base_number,
u32 interrupt_number, u32 interrupt_number,
struct acpi_gpe_block_info **return_gpe_block) struct acpi_gpe_block_info **return_gpe_block)
{ {
...@@ -359,15 +356,14 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, ...@@ -359,15 +356,14 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
/* Initialize the new GPE block */ /* Initialize the new GPE block */
gpe_block->address = address;
gpe_block->space_id = space_id;
gpe_block->node = gpe_device; gpe_block->node = gpe_device;
gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
gpe_block->initialized = FALSE; gpe_block->initialized = FALSE;
gpe_block->register_count = register_count; gpe_block->register_count = register_count;
gpe_block->block_base_number = gpe_block_base_number; gpe_block->block_base_number = gpe_block_base_number;
ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
sizeof(struct acpi_generic_address));
/* /*
* Create the register_info and event_info sub-structures * Create the register_info and event_info sub-structures
* Note: disables and clears all GPEs in the block * Note: disables and clears all GPEs in the block
...@@ -408,12 +404,14 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, ...@@ -408,12 +404,14 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
} }
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
" Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X\n", " Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X%s\n",
(u32)gpe_block->block_base_number, (u32)gpe_block->block_base_number,
(u32)(gpe_block->block_base_number + (u32)(gpe_block->block_base_number +
(gpe_block->gpe_count - 1)), (gpe_block->gpe_count - 1)),
gpe_device->name.ascii, gpe_block->register_count, gpe_device->name.ascii, gpe_block->register_count,
interrupt_number)); interrupt_number,
interrupt_number ==
acpi_gbl_FADT.sci_interrupt ? " (SCI)" : ""));
/* Update global count of currently available GPEs */ /* Update global count of currently available GPEs */
......
...@@ -131,8 +131,10 @@ acpi_status acpi_ev_gpe_initialize(void) ...@@ -131,8 +131,10 @@ acpi_status acpi_ev_gpe_initialize(void)
/* Install GPE Block 0 */ /* Install GPE Block 0 */
status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
&acpi_gbl_FADT.xgpe0_block, acpi_gbl_FADT.xgpe0_block.
register_count0, 0, address,
acpi_gbl_FADT.xgpe0_block.
space_id, register_count0, 0,
acpi_gbl_FADT.sci_interrupt, acpi_gbl_FADT.sci_interrupt,
&acpi_gbl_gpe_fadt_blocks[0]); &acpi_gbl_gpe_fadt_blocks[0]);
...@@ -169,8 +171,10 @@ acpi_status acpi_ev_gpe_initialize(void) ...@@ -169,8 +171,10 @@ acpi_status acpi_ev_gpe_initialize(void)
status = status =
acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
&acpi_gbl_FADT.xgpe1_block, acpi_gbl_FADT.xgpe1_block.
register_count1, address,
acpi_gbl_FADT.xgpe1_block.
space_id, register_count1,
acpi_gbl_FADT.gpe1_base, acpi_gbl_FADT.gpe1_base,
acpi_gbl_FADT. acpi_gbl_FADT.
sci_interrupt, sci_interrupt,
......
...@@ -167,7 +167,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, ...@@ -167,7 +167,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
"Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
acpi_ut_get_node_name(node), acpi_ut_get_node_name(node),
acpi_ut_get_type_name(node->type), notify_value, acpi_ut_get_type_name(node->type), notify_value,
acpi_ut_get_notify_name(notify_value), node)); acpi_ut_get_notify_name(notify_value, ACPI_TYPE_ANY),
node));
status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
info); info);
......
...@@ -117,7 +117,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) ...@@ -117,7 +117,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)
ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler);
/* /*
* We are guaranteed by the ACPI CA initialization/shutdown code that * We are guaranteed by the ACPICA initialization/shutdown code that
* if this interrupt handler is installed, ACPI is enabled. * if this interrupt handler is installed, ACPI is enabled.
*/ */
......
...@@ -239,7 +239,7 @@ acpi_remove_notify_handler(acpi_handle device, ...@@ -239,7 +239,7 @@ acpi_remove_notify_handler(acpi_handle device,
union acpi_operand_object *obj_desc; union acpi_operand_object *obj_desc;
union acpi_operand_object *handler_obj; union acpi_operand_object *handler_obj;
union acpi_operand_object *previous_handler_obj; union acpi_operand_object *previous_handler_obj;
acpi_status status; acpi_status status = AE_OK;
u32 i; u32 i;
ACPI_FUNCTION_TRACE(acpi_remove_notify_handler); ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
...@@ -251,20 +251,17 @@ acpi_remove_notify_handler(acpi_handle device, ...@@ -251,20 +251,17 @@ acpi_remove_notify_handler(acpi_handle device,
return_ACPI_STATUS(AE_BAD_PARAMETER); return_ACPI_STATUS(AE_BAD_PARAMETER);
} }
/* Make sure all deferred notify tasks are completed */
acpi_os_wait_events_complete();
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Root Object. Global handlers are removed here */ /* Root Object. Global handlers are removed here */
if (device == ACPI_ROOT_OBJECT) { if (device == ACPI_ROOT_OBJECT) {
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
if (handler_type & (i + 1)) { if (handler_type & (i + 1)) {
status =
acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
if (!acpi_gbl_global_notify[i].handler || if (!acpi_gbl_global_notify[i].handler ||
(acpi_gbl_global_notify[i].handler != (acpi_gbl_global_notify[i].handler !=
handler)) { handler)) {
...@@ -277,31 +274,40 @@ acpi_remove_notify_handler(acpi_handle device, ...@@ -277,31 +274,40 @@ acpi_remove_notify_handler(acpi_handle device,
acpi_gbl_global_notify[i].handler = NULL; acpi_gbl_global_notify[i].handler = NULL;
acpi_gbl_global_notify[i].context = NULL; acpi_gbl_global_notify[i].context = NULL;
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
/* Make sure all deferred notify tasks are completed */
acpi_os_wait_events_complete();
} }
} }
goto unlock_and_exit; return_ACPI_STATUS(AE_OK);
} }
/* All other objects: Are Notifies allowed on this object? */ /* All other objects: Are Notifies allowed on this object? */
if (!acpi_ev_is_notify_object(node)) { if (!acpi_ev_is_notify_object(node)) {
status = AE_TYPE; return_ACPI_STATUS(AE_TYPE);
goto unlock_and_exit;
} }
/* Must have an existing internal object */ /* Must have an existing internal object */
obj_desc = acpi_ns_get_attached_object(node); obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) { if (!obj_desc) {
status = AE_NOT_EXIST; return_ACPI_STATUS(AE_NOT_EXIST);
goto unlock_and_exit;
} }
/* Internal object exists. Find the handler and remove it */ /* Internal object exists. Find the handler and remove it */
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
if (handler_type & (i + 1)) { if (handler_type & (i + 1)) {
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
handler_obj = obj_desc->common_notify.notify_list[i]; handler_obj = obj_desc->common_notify.notify_list[i];
previous_handler_obj = NULL; previous_handler_obj = NULL;
...@@ -329,10 +335,17 @@ acpi_remove_notify_handler(acpi_handle device, ...@@ -329,10 +335,17 @@ acpi_remove_notify_handler(acpi_handle device,
handler_obj->notify.next[i]; handler_obj->notify.next[i];
} }
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
/* Make sure all deferred notify tasks are completed */
acpi_os_wait_events_complete();
acpi_ut_remove_reference(handler_obj); acpi_ut_remove_reference(handler_obj);
} }
} }
return_ACPI_STATUS(status);
unlock_and_exit: unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -457,6 +470,8 @@ acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context) ...@@ -457,6 +470,8 @@ acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context)
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
ACPI_EXPORT_SYMBOL(acpi_install_sci_handler)
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_remove_sci_handler * FUNCTION: acpi_remove_sci_handler
...@@ -468,7 +483,6 @@ acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context) ...@@ -468,7 +483,6 @@ acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context)
* DESCRIPTION: Remove a handler for a System Control Interrupt. * DESCRIPTION: Remove a handler for a System Control Interrupt.
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_remove_sci_handler(acpi_sci_handler address) acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
{ {
struct acpi_sci_handler_info *prev_sci_handler; struct acpi_sci_handler_info *prev_sci_handler;
...@@ -522,6 +536,8 @@ acpi_status acpi_remove_sci_handler(acpi_sci_handler address) ...@@ -522,6 +536,8 @@ acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
ACPI_EXPORT_SYMBOL(acpi_remove_sci_handler)
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_install_global_event_handler * FUNCTION: acpi_install_global_event_handler
...@@ -537,7 +553,6 @@ acpi_status acpi_remove_sci_handler(acpi_sci_handler address) ...@@ -537,7 +553,6 @@ acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
* Can be used to update event counters, etc. * Can be used to update event counters, etc.
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context)
{ {
...@@ -840,10 +855,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, ...@@ -840,10 +855,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
return_ACPI_STATUS(AE_BAD_PARAMETER); return_ACPI_STATUS(AE_BAD_PARAMETER);
} }
/* Make sure all deferred GPE tasks are completed */
acpi_os_wait_events_complete();
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -895,9 +906,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, ...@@ -895,9 +906,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
(void)acpi_ev_add_gpe_reference(gpe_event_info); (void)acpi_ev_add_gpe_reference(gpe_event_info);
} }
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
/* Make sure all deferred GPE tasks are completed */
acpi_os_wait_events_complete();
/* Now we can free the handler object */ /* Now we can free the handler object */
ACPI_FREE(handler); ACPI_FREE(handler);
return_ACPI_STATUS(status);
unlock_and_exit: unlock_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags); acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
......
...@@ -599,9 +599,10 @@ acpi_install_gpe_block(acpi_handle gpe_device, ...@@ -599,9 +599,10 @@ acpi_install_gpe_block(acpi_handle gpe_device,
* For user-installed GPE Block Devices, the gpe_block_base_number * For user-installed GPE Block Devices, the gpe_block_base_number
* is always zero * is always zero
*/ */
status = status = acpi_ev_create_gpe_block(node, gpe_block_address->address,
acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, gpe_block_address->space_id,
interrupt_number, &gpe_block); register_count, 0, interrupt_number,
&gpe_block);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto unlock_and_exit;
} }
......
...@@ -343,16 +343,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -343,16 +343,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
struct acpi_walk_state *walk_state) struct acpi_walk_state *walk_state)
{ {
union acpi_operand_object *ddb_handle; union acpi_operand_object *ddb_handle;
struct acpi_table_header *table_header;
struct acpi_table_header *table; struct acpi_table_header *table;
struct acpi_table_desc table_desc;
u32 table_index; u32 table_index;
acpi_status status; acpi_status status;
u32 length; u32 length;
ACPI_FUNCTION_TRACE(ex_load_op); ACPI_FUNCTION_TRACE(ex_load_op);
ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
/* Source Object can be either an op_region or a Buffer/Field */ /* Source Object can be either an op_region or a Buffer/Field */
switch (obj_desc->common.type) { switch (obj_desc->common.type) {
...@@ -380,17 +378,17 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -380,17 +378,17 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Get the table header first so we can get the table length */ /* Get the table header first so we can get the table length */
table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); table_header = ACPI_ALLOCATE(sizeof(struct acpi_table_header));
if (!table) { if (!table_header) {
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
status = status =
acpi_ex_region_read(obj_desc, acpi_ex_region_read(obj_desc,
sizeof(struct acpi_table_header), sizeof(struct acpi_table_header),
ACPI_CAST_PTR(u8, table)); ACPI_CAST_PTR(u8, table_header));
length = table->length; length = table_header->length;
ACPI_FREE(table); ACPI_FREE(table_header);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -420,22 +418,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -420,22 +418,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Allocate a buffer for the table */ /* Allocate a buffer for the table */
table_desc.pointer = ACPI_ALLOCATE(length); table = ACPI_ALLOCATE(length);
if (!table_desc.pointer) { if (!table) {
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
/* Read the entire table */ /* Read the entire table */
status = acpi_ex_region_read(obj_desc, length, status = acpi_ex_region_read(obj_desc, length,
ACPI_CAST_PTR(u8, ACPI_CAST_PTR(u8, table));
table_desc.pointer));
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_FREE(table_desc.pointer); ACPI_FREE(table);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
table_desc.address = obj_desc->region.address;
break; break;
case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
...@@ -452,10 +447,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -452,10 +447,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Get the actual table length from the table header */ /* Get the actual table length from the table header */
table = table_header =
ACPI_CAST_PTR(struct acpi_table_header, ACPI_CAST_PTR(struct acpi_table_header,
obj_desc->buffer.pointer); obj_desc->buffer.pointer);
length = table->length; length = table_header->length;
/* Table cannot extend beyond the buffer */ /* Table cannot extend beyond the buffer */
...@@ -470,13 +465,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -470,13 +465,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
* Copy the table from the buffer because the buffer could be modified * Copy the table from the buffer because the buffer could be modified
* or even deleted in the future * or even deleted in the future
*/ */
table_desc.pointer = ACPI_ALLOCATE(length); table = ACPI_ALLOCATE(length);
if (!table_desc.pointer) { if (!table) {
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
ACPI_MEMCPY(table_desc.pointer, table, length); ACPI_MEMCPY(table, table_header, length);
table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
break; break;
default: default:
...@@ -484,27 +478,32 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -484,27 +478,32 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
return_ACPI_STATUS(AE_AML_OPERAND_TYPE); return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
} }
/* Validate table checksum (will not get validated in tb_add_table) */ /* Install the new table into the local data structures */
status = acpi_tb_verify_checksum(table_desc.pointer, length);
if (ACPI_FAILURE(status)) {
ACPI_FREE(table_desc.pointer);
return_ACPI_STATUS(status);
}
/* Complete the table descriptor */
table_desc.length = length; ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:"));
table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
/* Install the new table into the local data structures */ status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
TRUE, TRUE, &table_index);
status = acpi_tb_add_table(&table_desc, &table_index); (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/* Delete allocated table buffer */ /* Delete allocated table buffer */
acpi_tb_delete_table(&table_desc); ACPI_FREE(table);
return_ACPI_STATUS(status);
}
/*
* Note: Now table is "INSTALLED", it must be validated before
* loading.
*/
status =
acpi_tb_validate_table(&acpi_gbl_root_table_list.
tables[table_index]);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -536,9 +535,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -536,9 +535,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:"));
acpi_tb_print_table_header(0, table_desc.pointer);
/* Remove the reference by added by acpi_ex_store above */ /* Remove the reference by added by acpi_ex_store above */
acpi_ut_remove_reference(ddb_handle); acpi_ut_remove_reference(ddb_handle);
...@@ -546,8 +542,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -546,8 +542,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Invoke table handler if present */ /* Invoke table handler if present */
if (acpi_gbl_table_handler) { if (acpi_gbl_table_handler) {
(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
table_desc.pointer,
acpi_gbl_table_handler_context); acpi_gbl_table_handler_context);
} }
...@@ -575,6 +570,13 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) ...@@ -575,6 +570,13 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
ACPI_FUNCTION_TRACE(ex_unload_table); ACPI_FUNCTION_TRACE(ex_unload_table);
/*
* Temporarily emit a warning so that the ASL for the machine can be
* hopefully obtained. This is to say that the Unload() operator is
* extremely rare if not completely unused.
*/
ACPI_WARNING((AE_INFO, "Received request to unload an ACPI table"));
/* /*
* Validate the handle * Validate the handle
* Although the handle is partially validated in acpi_ex_reconfiguration() * Although the handle is partially validated in acpi_ex_reconfiguration()
......
...@@ -134,9 +134,11 @@ static struct acpi_exdump_info acpi_ex_dump_method[9] = { ...@@ -134,9 +134,11 @@ static struct acpi_exdump_info acpi_ex_dump_method[9] = {
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"}
}; };
static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { static struct acpi_exdump_info acpi_ex_dump_mutex[6] = {
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL},
{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"},
{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.original_sync_level),
"Original Sync Level"},
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"},
{ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth),
"Acquire Depth"}, "Acquire Depth"},
......
...@@ -140,11 +140,12 @@ acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, ...@@ -140,11 +140,12 @@ acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id,
/* Walk the list, updating the PCI device/function/bus numbers */ /* Walk the list, updating the PCI device/function/bus numbers */
status = acpi_hw_process_pci_list(pci_id, list_head); status = acpi_hw_process_pci_list(pci_id, list_head);
}
/* Always delete the list */ /* Delete the list */
acpi_hw_delete_pci_list(list_head);
}
acpi_hw_delete_pci_list(list_head);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -187,6 +188,10 @@ acpi_hw_build_pci_list(acpi_handle root_pci_device, ...@@ -187,6 +188,10 @@ acpi_hw_build_pci_list(acpi_handle root_pci_device,
while (1) { while (1) {
status = acpi_get_parent(current_device, &parent_device); status = acpi_get_parent(current_device, &parent_device);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/* Must delete the list before exit */
acpi_hw_delete_pci_list(*return_list_head);
return (status); return (status);
} }
...@@ -199,6 +204,10 @@ acpi_hw_build_pci_list(acpi_handle root_pci_device, ...@@ -199,6 +204,10 @@ acpi_hw_build_pci_list(acpi_handle root_pci_device,
list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device)); list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device));
if (!list_element) { if (!list_element) {
/* Must delete the list before exit */
acpi_hw_delete_pci_list(*return_list_head);
return (AE_NO_MEMORY); return (AE_NO_MEMORY);
} }
......
...@@ -72,6 +72,8 @@ acpi_buffer_to_resource(u8 *aml_buffer, ...@@ -72,6 +72,8 @@ acpi_buffer_to_resource(u8 *aml_buffer,
void *resource; void *resource;
void *current_resource_ptr; void *current_resource_ptr;
ACPI_FUNCTION_TRACE(acpi_buffer_to_resource);
/* /*
* Note: we allow AE_AML_NO_RESOURCE_END_TAG, since an end tag * Note: we allow AE_AML_NO_RESOURCE_END_TAG, since an end tag
* is not required here. * is not required here.
...@@ -85,7 +87,7 @@ acpi_buffer_to_resource(u8 *aml_buffer, ...@@ -85,7 +87,7 @@ acpi_buffer_to_resource(u8 *aml_buffer,
status = AE_OK; status = AE_OK;
} }
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return_ACPI_STATUS(status);
} }
/* Allocate a buffer for the converted resource */ /* Allocate a buffer for the converted resource */
...@@ -93,7 +95,7 @@ acpi_buffer_to_resource(u8 *aml_buffer, ...@@ -93,7 +95,7 @@ acpi_buffer_to_resource(u8 *aml_buffer,
resource = ACPI_ALLOCATE_ZEROED(list_size_needed); resource = ACPI_ALLOCATE_ZEROED(list_size_needed);
current_resource_ptr = resource; current_resource_ptr = resource;
if (!resource) { if (!resource) {
return (AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
/* Perform the AML-to-Resource conversion */ /* Perform the AML-to-Resource conversion */
...@@ -110,9 +112,11 @@ acpi_buffer_to_resource(u8 *aml_buffer, ...@@ -110,9 +112,11 @@ acpi_buffer_to_resource(u8 *aml_buffer,
*resource_ptr = resource; *resource_ptr = resource;
} }
return (status); return_ACPI_STATUS(status);
} }
ACPI_EXPORT_SYMBOL(acpi_buffer_to_resource)
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_rs_create_resource_list * FUNCTION: acpi_rs_create_resource_list
...@@ -130,10 +134,9 @@ acpi_buffer_to_resource(u8 *aml_buffer, ...@@ -130,10 +134,9 @@ acpi_buffer_to_resource(u8 *aml_buffer,
* of device resources. * of device resources.
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer,
struct acpi_buffer * output_buffer) struct acpi_buffer *output_buffer)
{ {
acpi_status status; acpi_status status;
......
此差异已折叠。
...@@ -52,7 +52,8 @@ ACPI_MODULE_NAME("tbfadt") ...@@ -52,7 +52,8 @@ ACPI_MODULE_NAME("tbfadt")
static void static void
acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
u8 space_id, u8 space_id,
u8 byte_width, u64 address, char *register_name); u8 byte_width,
u64 address, char *register_name, u8 flags);
static void acpi_tb_convert_fadt(void); static void acpi_tb_convert_fadt(void);
...@@ -69,13 +70,14 @@ typedef struct acpi_fadt_info { ...@@ -69,13 +70,14 @@ typedef struct acpi_fadt_info {
u16 address32; u16 address32;
u16 length; u16 length;
u8 default_length; u8 default_length;
u8 type; u8 flags;
} acpi_fadt_info; } acpi_fadt_info;
#define ACPI_FADT_OPTIONAL 0 #define ACPI_FADT_OPTIONAL 0
#define ACPI_FADT_REQUIRED 1 #define ACPI_FADT_REQUIRED 1
#define ACPI_FADT_SEPARATE_LENGTH 2 #define ACPI_FADT_SEPARATE_LENGTH 2
#define ACPI_FADT_GPE_REGISTER 4
static struct acpi_fadt_info fadt_info_table[] = { static struct acpi_fadt_info fadt_info_table[] = {
{"Pm1aEventBlock", {"Pm1aEventBlock",
...@@ -125,14 +127,14 @@ static struct acpi_fadt_info fadt_info_table[] = { ...@@ -125,14 +127,14 @@ static struct acpi_fadt_info fadt_info_table[] = {
ACPI_FADT_OFFSET(gpe0_block), ACPI_FADT_OFFSET(gpe0_block),
ACPI_FADT_OFFSET(gpe0_block_length), ACPI_FADT_OFFSET(gpe0_block_length),
0, 0,
ACPI_FADT_SEPARATE_LENGTH}, ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER},
{"Gpe1Block", {"Gpe1Block",
ACPI_FADT_OFFSET(xgpe1_block), ACPI_FADT_OFFSET(xgpe1_block),
ACPI_FADT_OFFSET(gpe1_block), ACPI_FADT_OFFSET(gpe1_block),
ACPI_FADT_OFFSET(gpe1_block_length), ACPI_FADT_OFFSET(gpe1_block_length),
0, 0,
ACPI_FADT_SEPARATE_LENGTH} ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}
}; };
#define ACPI_FADT_INFO_ENTRIES \ #define ACPI_FADT_INFO_ENTRIES \
...@@ -189,19 +191,29 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = { ...@@ -189,19 +191,29 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
static void static void
acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
u8 space_id, u8 space_id,
u8 byte_width, u64 address, char *register_name) u8 byte_width,
u64 address, char *register_name, u8 flags)
{ {
u8 bit_width; u8 bit_width;
/* Bit width field in the GAS is only one byte long, 255 max */ /*
* Bit width field in the GAS is only one byte long, 255 max.
* Check for bit_width overflow in GAS.
*/
bit_width = (u8)(byte_width * 8); bit_width = (u8)(byte_width * 8);
if (byte_width > 31) { /* (31*8)=248, (32*8)=256 */
if (byte_width > 31) { /* (31*8)=248 */ /*
ACPI_ERROR((AE_INFO, * No error for GPE blocks, because we do not use the bit_width
"%s - 32-bit FADT register is too long (%u bytes, %u bits) " * for GPEs, the legacy length (byte_width) is used instead to
"to convert to GAS struct - 255 bits max, truncating", * allow for a large number of GPEs.
register_name, byte_width, (byte_width * 8))); */
if (!(flags & ACPI_FADT_GPE_REGISTER)) {
ACPI_ERROR((AE_INFO,
"%s - 32-bit FADT register is too long (%u bytes, %u bits) "
"to convert to GAS struct - 255 bits max, truncating",
register_name, byte_width,
(byte_width * 8)));
}
bit_width = 255; bit_width = 255;
} }
...@@ -332,15 +344,15 @@ void acpi_tb_parse_fadt(u32 table_index) ...@@ -332,15 +344,15 @@ void acpi_tb_parse_fadt(u32 table_index)
/* Obtain the DSDT and FACS tables via their addresses within the FADT */ /* Obtain the DSDT and FACS tables via their addresses within the FADT */
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
/* If Hardware Reduced flag is set, there is no FACS */ /* If Hardware Reduced flag is set, there is no FACS */
if (!acpi_gbl_reduced_hardware) { if (!acpi_gbl_reduced_hardware) {
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT. acpi_tb_install_fixed_table((acpi_physical_address)
Xfacs, ACPI_SIG_FACS, acpi_gbl_FADT.Xfacs, ACPI_SIG_FACS,
ACPI_TABLE_INDEX_FACS); ACPI_TABLE_INDEX_FACS);
} }
} }
...@@ -450,6 +462,7 @@ static void acpi_tb_convert_fadt(void) ...@@ -450,6 +462,7 @@ static void acpi_tb_convert_fadt(void)
struct acpi_generic_address *address64; struct acpi_generic_address *address64;
u32 address32; u32 address32;
u8 length; u8 length;
u8 flags;
u32 i; u32 i;
/* /*
...@@ -515,6 +528,7 @@ static void acpi_tb_convert_fadt(void) ...@@ -515,6 +528,7 @@ static void acpi_tb_convert_fadt(void)
fadt_info_table[i].length); fadt_info_table[i].length);
name = fadt_info_table[i].name; name = fadt_info_table[i].name;
flags = fadt_info_table[i].flags;
/* /*
* Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
...@@ -554,7 +568,7 @@ static void acpi_tb_convert_fadt(void) ...@@ -554,7 +568,7 @@ static void acpi_tb_convert_fadt(void)
[i]. [i].
length), length),
(u64)address32, (u64)address32,
name); name, flags);
} else if (address64->address != (u64)address32) { } else if (address64->address != (u64)address32) {
/* Address mismatch */ /* Address mismatch */
...@@ -582,7 +596,8 @@ static void acpi_tb_convert_fadt(void) ...@@ -582,7 +596,8 @@ static void acpi_tb_convert_fadt(void)
length), length),
(u64) (u64)
address32, address32,
name); name,
flags);
} }
} }
} }
...@@ -603,7 +618,7 @@ static void acpi_tb_convert_fadt(void) ...@@ -603,7 +618,7 @@ static void acpi_tb_convert_fadt(void)
address64->bit_width)); address64->bit_width));
} }
if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { if (fadt_info_table[i].flags & ACPI_FADT_REQUIRED) {
/* /*
* Field is required (Pm1a_event, Pm1a_control). * Field is required (Pm1a_event, Pm1a_control).
* Both the address and length must be non-zero. * Both the address and length must be non-zero.
...@@ -617,7 +632,7 @@ static void acpi_tb_convert_fadt(void) ...@@ -617,7 +632,7 @@ static void acpi_tb_convert_fadt(void)
address), address),
length)); length));
} }
} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { } else if (fadt_info_table[i].flags & ACPI_FADT_SEPARATE_LENGTH) {
/* /*
* Field is optional (Pm2_control, GPE0, GPE1) AND has its own * Field is optional (Pm2_control, GPE0, GPE1) AND has its own
* length field. If present, both the address and length must * length field. If present, both the address and length must
...@@ -726,7 +741,7 @@ static void acpi_tb_setup_fadt_registers(void) ...@@ -726,7 +741,7 @@ static void acpi_tb_setup_fadt_registers(void)
(fadt_pm_info_table[i]. (fadt_pm_info_table[i].
register_num * register_num *
pm1_register_byte_width), pm1_register_byte_width),
"PmRegisters"); "PmRegisters", 0);
} }
} }
} }
...@@ -99,8 +99,8 @@ acpi_tb_find_table(char *signature, ...@@ -99,8 +99,8 @@ acpi_tb_find_table(char *signature,
/* Table is not currently mapped, map it */ /* Table is not currently mapped, map it */
status = status =
acpi_tb_verify_table(&acpi_gbl_root_table_list. acpi_tb_validate_table(&acpi_gbl_root_table_list.
tables[i]); tables[i]);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
......
此差异已折叠。
...@@ -49,8 +49,6 @@ ...@@ -49,8 +49,6 @@
ACPI_MODULE_NAME("tbutils") ACPI_MODULE_NAME("tbutils")
/* Local prototypes */ /* Local prototypes */
static acpi_status acpi_tb_validate_xsdt(acpi_physical_address address);
static acpi_physical_address static acpi_physical_address
acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
...@@ -178,9 +176,13 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) ...@@ -178,9 +176,13 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
} }
ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length);
acpi_tb_delete_table(table_desc); acpi_tb_uninstall_table(table_desc);
table_desc->pointer = new_table;
table_desc->flags = ACPI_TABLE_ORIGIN_ALLOCATED; acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.
tables[ACPI_TABLE_INDEX_DSDT],
ACPI_PTR_TO_PHYSADDR(new_table),
ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
new_table);
ACPI_INFO((AE_INFO, ACPI_INFO((AE_INFO,
"Forced DSDT copy: length 0x%05X copied locally, original unmapped", "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
...@@ -189,116 +191,6 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) ...@@ -189,116 +191,6 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
return (new_table); return (new_table);
} }
/*******************************************************************************
*
* FUNCTION: acpi_tb_install_table
*
* PARAMETERS: address - Physical address of DSDT or FACS
* signature - Table signature, NULL if no need to
* match
* table_index - Index into root table array
*
* RETURN: None
*
* DESCRIPTION: Install an ACPI table into the global data structure. The
* table override mechanism is called to allow the host
* OS to replace any table before it is installed in the root
* table array.
*
******************************************************************************/
void
acpi_tb_install_table(acpi_physical_address address,
char *signature, u32 table_index)
{
struct acpi_table_header *table;
struct acpi_table_header *final_table;
struct acpi_table_desc *table_desc;
if (!address) {
ACPI_ERROR((AE_INFO,
"Null physical address for ACPI table [%s]",
signature));
return;
}
/* Map just the table header */
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
if (!table) {
ACPI_ERROR((AE_INFO,
"Could not map memory for table [%s] at %p",
signature, ACPI_CAST_PTR(void, address)));
return;
}
/* If a particular signature is expected (DSDT/FACS), it must match */
if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
ACPI_BIOS_ERROR((AE_INFO,
"Invalid signature 0x%X for ACPI table, expected [%s]",
*ACPI_CAST_PTR(u32, table->signature),
signature));
goto unmap_and_exit;
}
/*
* Initialize the table entry. Set the pointer to NULL, since the
* table is not fully mapped at this time.
*/
table_desc = &acpi_gbl_root_table_list.tables[table_index];
table_desc->address = address;
table_desc->pointer = NULL;
table_desc->length = table->length;
table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED;
ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
/*
* ACPI Table Override:
*
* Before we install the table, let the host OS override it with a new
* one if desired. Any table within the RSDT/XSDT can be replaced,
* including the DSDT which is pointed to by the FADT.
*
* NOTE: If the table is overridden, then final_table will contain a
* mapped pointer to the full new table. If the table is not overridden,
* or if there has been a physical override, then the table will be
* fully mapped later (in verify table). In any case, we must
* unmap the header that was mapped above.
*/
final_table = acpi_tb_table_override(table, table_desc);
if (!final_table) {
final_table = table; /* There was no override */
}
acpi_tb_print_table_header(table_desc->address, final_table);
/* Set the global integer width (based upon revision of the DSDT) */
if (table_index == ACPI_TABLE_INDEX_DSDT) {
acpi_ut_set_integer_width(final_table->revision);
}
/*
* If we have a physical override during this early loading of the ACPI
* tables, unmap the table for now. It will be mapped again later when
* it is actually used. This supports very early loading of ACPI tables,
* before virtual memory is fully initialized and running within the
* host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE
* flag set and will not be deleted below.
*/
if (final_table != table) {
acpi_tb_delete_table(table_desc);
}
unmap_and_exit:
/* Always unmap the table header that we mapped above */
acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_tb_get_root_table_entry * FUNCTION: acpi_tb_get_root_table_entry
...@@ -355,87 +247,6 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) ...@@ -355,87 +247,6 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
} }
} }
/*******************************************************************************
*
* FUNCTION: acpi_tb_validate_xsdt
*
* PARAMETERS: address - Physical address of the XSDT (from RSDP)
*
* RETURN: Status. AE_OK if the table appears to be valid.
*
* DESCRIPTION: Validate an XSDT to ensure that it is of minimum size and does
* not contain any NULL entries. A problem that is seen in the
* field is that the XSDT exists, but is actually useless because
* of one or more (or all) NULL entries.
*
******************************************************************************/
static acpi_status acpi_tb_validate_xsdt(acpi_physical_address xsdt_address)
{
struct acpi_table_header *table;
u8 *next_entry;
acpi_physical_address address;
u32 length;
u32 entry_count;
acpi_status status;
u32 i;
/* Get the XSDT length */
table =
acpi_os_map_memory(xsdt_address, sizeof(struct acpi_table_header));
if (!table) {
return (AE_NO_MEMORY);
}
length = table->length;
acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
/*
* Minimum XSDT length is the size of the standard ACPI header
* plus one physical address entry
*/
if (length < (sizeof(struct acpi_table_header) + ACPI_XSDT_ENTRY_SIZE)) {
return (AE_INVALID_TABLE_LENGTH);
}
/* Map the entire XSDT */
table = acpi_os_map_memory(xsdt_address, length);
if (!table) {
return (AE_NO_MEMORY);
}
/* Get the number of entries and pointer to first entry */
status = AE_OK;
next_entry = ACPI_ADD_PTR(u8, table, sizeof(struct acpi_table_header));
entry_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
ACPI_XSDT_ENTRY_SIZE);
/* Validate each entry (physical address) within the XSDT */
for (i = 0; i < entry_count; i++) {
address =
acpi_tb_get_root_table_entry(next_entry,
ACPI_XSDT_ENTRY_SIZE);
if (!address) {
/* Detected a NULL entry, XSDT is invalid */
status = AE_NULL_ENTRY;
break;
}
next_entry += ACPI_XSDT_ENTRY_SIZE;
}
/* Unmap table */
acpi_os_unmap_memory(table, length);
return (status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_tb_parse_root_table * FUNCTION: acpi_tb_parse_root_table
...@@ -461,10 +272,10 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) ...@@ -461,10 +272,10 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
u32 table_count; u32 table_count;
struct acpi_table_header *table; struct acpi_table_header *table;
acpi_physical_address address; acpi_physical_address address;
acpi_physical_address rsdt_address;
u32 length; u32 length;
u8 *table_entry; u8 *table_entry;
acpi_status status; acpi_status status;
u32 table_index;
ACPI_FUNCTION_TRACE(tb_parse_root_table); ACPI_FUNCTION_TRACE(tb_parse_root_table);
...@@ -489,14 +300,11 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) ...@@ -489,14 +300,11 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
* as per the ACPI specification. * as per the ACPI specification.
*/ */
address = (acpi_physical_address) rsdp->xsdt_physical_address; address = (acpi_physical_address) rsdp->xsdt_physical_address;
rsdt_address =
(acpi_physical_address) rsdp->rsdt_physical_address;
table_entry_size = ACPI_XSDT_ENTRY_SIZE; table_entry_size = ACPI_XSDT_ENTRY_SIZE;
} else { } else {
/* Root table is an RSDT (32-bit physical addresses) */ /* Root table is an RSDT (32-bit physical addresses) */
address = (acpi_physical_address) rsdp->rsdt_physical_address; address = (acpi_physical_address) rsdp->rsdt_physical_address;
rsdt_address = address;
table_entry_size = ACPI_RSDT_ENTRY_SIZE; table_entry_size = ACPI_RSDT_ENTRY_SIZE;
} }
...@@ -506,24 +314,6 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) ...@@ -506,24 +314,6 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
*/ */
acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
/*
* If it is present and used, validate the XSDT for access/size
* and ensure that all table entries are at least non-NULL
*/
if (table_entry_size == ACPI_XSDT_ENTRY_SIZE) {
status = acpi_tb_validate_xsdt(address);
if (ACPI_FAILURE(status)) {
ACPI_BIOS_WARNING((AE_INFO,
"XSDT is invalid (%s), using RSDT",
acpi_format_exception(status)));
/* Fall back to the RSDT */
address = rsdt_address;
table_entry_size = ACPI_RSDT_ENTRY_SIZE;
}
}
/* Map the RSDT/XSDT table header to get the full table length */ /* Map the RSDT/XSDT table header to get the full table length */
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
...@@ -576,31 +366,33 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) ...@@ -576,31 +366,33 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
/* Initialize the root table array from the RSDT/XSDT */ /* Initialize the root table array from the RSDT/XSDT */
for (i = 0; i < table_count; i++) { for (i = 0; i < table_count; i++) {
if (acpi_gbl_root_table_list.current_table_count >=
acpi_gbl_root_table_list.max_table_count) {
/* There is no more room in the root table array, attempt resize */
status = acpi_tb_resize_root_table_list();
if (ACPI_FAILURE(status)) {
ACPI_WARNING((AE_INFO,
"Truncating %u table entries!",
(unsigned) (table_count -
(acpi_gbl_root_table_list.
current_table_count -
2))));
break;
}
}
/* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. address =
current_table_count].address =
acpi_tb_get_root_table_entry(table_entry, table_entry_size); acpi_tb_get_root_table_entry(table_entry, table_entry_size);
/* Skip NULL entries in RSDT/XSDT */
if (!address) {
goto next_table;
}
status = acpi_tb_install_standard_table(address,
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
FALSE, TRUE,
&table_index);
if (ACPI_SUCCESS(status) &&
ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
tables[table_index].signature,
ACPI_SIG_FADT)) {
acpi_tb_parse_fadt(table_index);
}
next_table:
table_entry += table_entry_size; table_entry += table_entry_size;
acpi_gbl_root_table_list.current_table_count++;
} }
/* /*
...@@ -609,22 +401,5 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) ...@@ -609,22 +401,5 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
*/ */
acpi_os_unmap_memory(table, length); acpi_os_unmap_memory(table, length);
/*
* Complete the initialization of the root table array by examining
* the header of each table
*/
for (i = 2; i < acpi_gbl_root_table_list.current_table_count; i++) {
acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
address, NULL, i);
/* Special case for FADT - validate it then get the DSDT and FACS */
if (ACPI_COMPARE_NAME
(&acpi_gbl_root_table_list.tables[i].signature,
ACPI_SIG_FADT)) {
acpi_tb_parse_fadt(i);
}
}
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
...@@ -206,8 +206,8 @@ acpi_status ...@@ -206,8 +206,8 @@ acpi_status
acpi_get_table_header(char *signature, acpi_get_table_header(char *signature,
u32 instance, struct acpi_table_header *out_table_header) u32 instance, struct acpi_table_header *out_table_header)
{ {
u32 i; u32 i;
u32 j; u32 j;
struct acpi_table_header *header; struct acpi_table_header *header;
/* Parameter validation */ /* Parameter validation */
...@@ -233,7 +233,7 @@ acpi_get_table_header(char *signature, ...@@ -233,7 +233,7 @@ acpi_get_table_header(char *signature,
if (!acpi_gbl_root_table_list.tables[i].pointer) { if (!acpi_gbl_root_table_list.tables[i].pointer) {
if ((acpi_gbl_root_table_list.tables[i].flags & if ((acpi_gbl_root_table_list.tables[i].flags &
ACPI_TABLE_ORIGIN_MASK) == ACPI_TABLE_ORIGIN_MASK) ==
ACPI_TABLE_ORIGIN_MAPPED) { ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) {
header = header =
acpi_os_map_memory(acpi_gbl_root_table_list. acpi_os_map_memory(acpi_gbl_root_table_list.
tables[i].address, tables[i].address,
...@@ -321,8 +321,8 @@ acpi_get_table_with_size(char *signature, ...@@ -321,8 +321,8 @@ acpi_get_table_with_size(char *signature,
u32 instance, struct acpi_table_header **out_table, u32 instance, struct acpi_table_header **out_table,
acpi_size *tbl_size) acpi_size *tbl_size)
{ {
u32 i; u32 i;
u32 j; u32 j;
acpi_status status; acpi_status status;
/* Parameter validation */ /* Parameter validation */
...@@ -346,7 +346,7 @@ acpi_get_table_with_size(char *signature, ...@@ -346,7 +346,7 @@ acpi_get_table_with_size(char *signature,
} }
status = status =
acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
*out_table = acpi_gbl_root_table_list.tables[i].pointer; *out_table = acpi_gbl_root_table_list.tables[i].pointer;
*tbl_size = acpi_gbl_root_table_list.tables[i].length; *tbl_size = acpi_gbl_root_table_list.tables[i].length;
...@@ -390,7 +390,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table) ...@@ -390,7 +390,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) acpi_get_table_by_index(u32 table_index, struct acpi_table_header ** table)
{ {
acpi_status status; acpi_status status;
...@@ -416,8 +416,8 @@ acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) ...@@ -416,8 +416,8 @@ acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table)
/* Table is not mapped, map it */ /* Table is not mapped, map it */
status = status =
acpi_tb_verify_table(&acpi_gbl_root_table_list. acpi_tb_validate_table(&acpi_gbl_root_table_list.
tables[table_index]); tables[table_index]);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES); (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
......
...@@ -117,7 +117,7 @@ static acpi_status acpi_tb_load_namespace(void) ...@@ -117,7 +117,7 @@ static acpi_status acpi_tb_load_namespace(void)
tables[ACPI_TABLE_INDEX_DSDT].signature), tables[ACPI_TABLE_INDEX_DSDT].signature),
ACPI_SIG_DSDT) ACPI_SIG_DSDT)
|| ||
ACPI_FAILURE(acpi_tb_verify_table ACPI_FAILURE(acpi_tb_validate_table
(&acpi_gbl_root_table_list. (&acpi_gbl_root_table_list.
tables[ACPI_TABLE_INDEX_DSDT]))) { tables[ACPI_TABLE_INDEX_DSDT]))) {
status = AE_NO_ACPI_TABLES; status = AE_NO_ACPI_TABLES;
...@@ -128,7 +128,7 @@ static acpi_status acpi_tb_load_namespace(void) ...@@ -128,7 +128,7 @@ static acpi_status acpi_tb_load_namespace(void)
* Save the DSDT pointer for simple access. This is the mapped memory * Save the DSDT pointer for simple access. This is the mapped memory
* address. We must take care here because the address of the .Tables * address. We must take care here because the address of the .Tables
* array can change dynamically as tables are loaded at run-time. Note: * array can change dynamically as tables are loaded at run-time. Note:
* .Pointer field is not validated until after call to acpi_tb_verify_table. * .Pointer field is not validated until after call to acpi_tb_validate_table.
*/ */
acpi_gbl_DSDT = acpi_gbl_DSDT =
acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer;
...@@ -174,24 +174,11 @@ static acpi_status acpi_tb_load_namespace(void) ...@@ -174,24 +174,11 @@ static acpi_status acpi_tb_load_namespace(void)
(acpi_gbl_root_table_list.tables[i]. (acpi_gbl_root_table_list.tables[i].
signature), ACPI_SIG_PSDT)) signature), ACPI_SIG_PSDT))
|| ||
ACPI_FAILURE(acpi_tb_verify_table ACPI_FAILURE(acpi_tb_validate_table
(&acpi_gbl_root_table_list.tables[i]))) { (&acpi_gbl_root_table_list.tables[i]))) {
continue; continue;
} }
/*
* Optionally do not load any SSDTs from the RSDT/XSDT. This can
* be useful for debugging ACPI problems on some machines.
*/
if (acpi_gbl_disable_ssdt_table_load) {
ACPI_INFO((AE_INFO, "Ignoring %4.4s at %p",
acpi_gbl_root_table_list.tables[i].signature.
ascii, ACPI_CAST_PTR(void,
acpi_gbl_root_table_list.
tables[i].address)));
continue;
}
/* Ignore errors while loading tables, get as many as possible */ /* Ignore errors while loading tables, get as many as possible */
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES); (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
...@@ -206,6 +193,45 @@ static acpi_status acpi_tb_load_namespace(void) ...@@ -206,6 +193,45 @@ static acpi_status acpi_tb_load_namespace(void)
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/*******************************************************************************
*
* FUNCTION: acpi_install_table
*
* PARAMETERS: address - Address of the ACPI table to be installed.
* physical - Whether the address is a physical table
* address or not
*
* RETURN: Status
*
* DESCRIPTION: Dynamically install an ACPI table.
* Note: This function should only be invoked after
* acpi_initialize_tables() and before acpi_load_tables().
*
******************************************************************************/
acpi_status __init
acpi_install_table(acpi_physical_address address, u8 physical)
{
acpi_status status;
u8 flags;
u32 table_index;
ACPI_FUNCTION_TRACE(acpi_install_table);
if (physical) {
flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
} else {
flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
}
status = acpi_tb_install_standard_table(address, flags,
FALSE, FALSE, &table_index);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL_INIT(acpi_install_table)
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_load_table * FUNCTION: acpi_load_table
...@@ -222,11 +248,9 @@ static acpi_status acpi_tb_load_namespace(void) ...@@ -222,11 +248,9 @@ static acpi_status acpi_tb_load_namespace(void)
* to ensure that the table is not deleted or unmapped. * to ensure that the table is not deleted or unmapped.
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_load_table(struct acpi_table_header *table) acpi_status acpi_load_table(struct acpi_table_header *table)
{ {
acpi_status status; acpi_status status;
struct acpi_table_desc table_desc;
u32 table_index; u32 table_index;
ACPI_FUNCTION_TRACE(acpi_load_table); ACPI_FUNCTION_TRACE(acpi_load_table);
...@@ -237,14 +261,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table) ...@@ -237,14 +261,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table)
return_ACPI_STATUS(AE_BAD_PARAMETER); return_ACPI_STATUS(AE_BAD_PARAMETER);
} }
/* Init local table descriptor */
ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
table_desc.address = ACPI_PTR_TO_PHYSADDR(table);
table_desc.pointer = table;
table_desc.length = table->length;
table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN;
/* Must acquire the interpreter lock during this operation */ /* Must acquire the interpreter lock during this operation */
status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
...@@ -255,7 +271,24 @@ acpi_status acpi_load_table(struct acpi_table_header *table) ...@@ -255,7 +271,24 @@ acpi_status acpi_load_table(struct acpi_table_header *table)
/* Install the table and load it into the namespace */ /* Install the table and load it into the namespace */
ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
status = acpi_tb_add_table(&table_desc, &table_index); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
TRUE, FALSE, &table_index);
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
/*
* Note: Now table is "INSTALLED", it must be validated before
* using.
*/
status =
acpi_tb_validate_table(&acpi_gbl_root_table_list.
tables[table_index]);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto unlock_and_exit;
} }
......
...@@ -462,7 +462,7 @@ char *acpi_ut_get_mutex_name(u32 mutex_id) ...@@ -462,7 +462,7 @@ char *acpi_ut_get_mutex_name(u32 mutex_id)
/* Names for Notify() values, used for debug output */ /* Names for Notify() values, used for debug output */
static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { static const char *acpi_gbl_generic_notify[ACPI_NOTIFY_MAX + 1] = {
/* 00 */ "Bus Check", /* 00 */ "Bus Check",
/* 01 */ "Device Check", /* 01 */ "Device Check",
/* 02 */ "Device Wake", /* 02 */ "Device Wake",
...@@ -473,23 +473,75 @@ static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { ...@@ -473,23 +473,75 @@ static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = {
/* 07 */ "Power Fault", /* 07 */ "Power Fault",
/* 08 */ "Capabilities Check", /* 08 */ "Capabilities Check",
/* 09 */ "Device PLD Check", /* 09 */ "Device PLD Check",
/* 10 */ "Reserved", /* 0A */ "Reserved",
/* 11 */ "System Locality Update", /* 0B */ "System Locality Update",
/* 12 */ "Shutdown Request" /* 0C */ "Shutdown Request"
}; };
const char *acpi_ut_get_notify_name(u32 notify_value) static const char *acpi_gbl_device_notify[4] = {
/* 80 */ "Status Change",
/* 81 */ "Information Change",
/* 82 */ "Device-Specific Change",
/* 83 */ "Device-Specific Change"
};
static const char *acpi_gbl_processor_notify[4] = {
/* 80 */ "Performance Capability Change",
/* 81 */ "C-State Change",
/* 82 */ "Throttling Capability Change",
/* 83 */ "Device-Specific Change"
};
static const char *acpi_gbl_thermal_notify[4] = {
/* 80 */ "Thermal Status Change",
/* 81 */ "Thermal Trip Point Change",
/* 82 */ "Thermal Device List Change",
/* 83 */ "Thermal Relationship Change"
};
const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type)
{ {
/* 00 - 0C are common to all object types */
if (notify_value <= ACPI_NOTIFY_MAX) { if (notify_value <= ACPI_NOTIFY_MAX) {
return (acpi_gbl_notify_value_names[notify_value]); return (acpi_gbl_generic_notify[notify_value]);
} else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { }
/* 0D - 7F are reserved */
if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
return ("Reserved"); return ("Reserved");
} else if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) {
return ("Device Specific");
} else {
return ("Hardware Specific");
} }
/* 80 - 83 are per-object-type */
if (notify_value <= 0x83) {
switch (type) {
case ACPI_TYPE_ANY:
case ACPI_TYPE_DEVICE:
return (acpi_gbl_device_notify[notify_value - 0x80]);
case ACPI_TYPE_PROCESSOR:
return (acpi_gbl_processor_notify[notify_value - 0x80]);
case ACPI_TYPE_THERMAL:
return (acpi_gbl_thermal_notify[notify_value - 0x80]);
default:
return ("Target object type does not support notifies");
}
}
/* 84 - BF are device-specific */
if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) {
return ("Device-Specific");
}
/* C0 and above are hardware-specific */
return ("Hardware-Specific");
} }
#endif #endif
......
...@@ -55,28 +55,7 @@ ACPI_MODULE_NAME("utglobal") ...@@ -55,28 +55,7 @@ ACPI_MODULE_NAME("utglobal")
* Static global variable initialization. * Static global variable initialization.
* *
******************************************************************************/ ******************************************************************************/
/* Debug output control masks */
u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT;
u32 acpi_dbg_layer = 0;
/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */
struct acpi_table_fadt acpi_gbl_FADT;
u32 acpi_gbl_trace_flags;
acpi_name acpi_gbl_trace_method_name;
u8 acpi_gbl_system_awake_and_running;
u32 acpi_current_gpe_count;
/*
* ACPI 5.0 introduces the concept of a "reduced hardware platform", meaning
* that the ACPI hardware is no longer required. A flag in the FADT indicates
* a reduced HW machine, and that flag is duplicated here for convenience.
*/
u8 acpi_gbl_reduced_hardware;
/* Various state name strings */ /* Various state name strings */
const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = {
"\\_S0_", "\\_S0_",
"\\_S1_", "\\_S1_",
...@@ -337,7 +316,6 @@ acpi_status acpi_ut_init_globals(void) ...@@ -337,7 +316,6 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_acpi_hardware_present = TRUE; acpi_gbl_acpi_hardware_present = TRUE;
acpi_gbl_last_owner_id_index = 0; acpi_gbl_last_owner_id_index = 0;
acpi_gbl_next_owner_id_offset = 0; acpi_gbl_next_owner_id_offset = 0;
acpi_gbl_trace_method_name = 0;
acpi_gbl_trace_dbg_level = 0; acpi_gbl_trace_dbg_level = 0;
acpi_gbl_trace_dbg_layer = 0; acpi_gbl_trace_dbg_layer = 0;
acpi_gbl_debugger_configuration = DEBUGGER_THREADING; acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
...@@ -377,9 +355,7 @@ acpi_status acpi_ut_init_globals(void) ...@@ -377,9 +355,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_disable_mem_tracking = FALSE; acpi_gbl_disable_mem_tracking = FALSE;
#endif #endif
#ifdef ACPI_DEBUGGER ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
acpi_gbl_db_terminate_threads = FALSE;
#endif
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
......
...@@ -353,7 +353,7 @@ void acpi_ut_print_string(char *string, u16 max_length) ...@@ -353,7 +353,7 @@ void acpi_ut_print_string(char *string, u16 max_length)
} }
acpi_os_printf("\""); acpi_os_printf("\"");
for (i = 0; string[i] && (i < max_length); i++) { for (i = 0; (i < max_length) && string[i]; i++) {
/* Escape sequences */ /* Escape sequences */
......
...@@ -53,6 +53,7 @@ ACPI_MODULE_NAME("utxferror") ...@@ -53,6 +53,7 @@ ACPI_MODULE_NAME("utxferror")
* This module is used for the in-kernel ACPICA as well as the ACPICA * This module is used for the in-kernel ACPICA as well as the ACPICA
* tools/applications. * tools/applications.
*/ */
#ifndef ACPI_NO_ERROR_MESSAGES /* Entire module */
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_error * FUNCTION: acpi_error
...@@ -249,3 +250,4 @@ acpi_bios_warning(const char *module_name, ...@@ -249,3 +250,4 @@ acpi_bios_warning(const char *module_name,
} }
ACPI_EXPORT_SYMBOL(acpi_bios_warning) ACPI_EXPORT_SYMBOL(acpi_bios_warning)
#endif /* ACPI_NO_ERROR_MESSAGES */
...@@ -1770,16 +1770,15 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) ...@@ -1770,16 +1770,15 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
} }
#endif #endif
static int __init acpi_no_auto_ssdt_setup(char *s) static int __init acpi_no_static_ssdt_setup(char *s)
{ {
printk(KERN_NOTICE PREFIX "SSDT auto-load disabled\n"); acpi_gbl_disable_ssdt_table_install = TRUE;
pr_info("ACPI: static SSDT installation disabled\n");
acpi_gbl_disable_ssdt_table_load = TRUE; return 0;
return 1;
} }
__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup); early_param("acpi_no_static_ssdt", acpi_no_static_ssdt_setup);
static int __init acpi_disable_return_repair(char *s) static int __init acpi_disable_return_repair(char *s)
{ {
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#define METHOD_NAME__HID "_HID" #define METHOD_NAME__HID "_HID"
#define METHOD_NAME__INI "_INI" #define METHOD_NAME__INI "_INI"
#define METHOD_NAME__PLD "_PLD" #define METHOD_NAME__PLD "_PLD"
#define METHOD_NAME__PRP "_PRP"
#define METHOD_NAME__PRS "_PRS" #define METHOD_NAME__PRS "_PRS"
#define METHOD_NAME__PRT "_PRT" #define METHOD_NAME__PRT "_PRT"
#define METHOD_NAME__PRW "_PRW" #define METHOD_NAME__PRW "_PRW"
......
此差异已折叠。
...@@ -367,12 +367,11 @@ struct acpi_table_desc { ...@@ -367,12 +367,11 @@ struct acpi_table_desc {
/* Masks for Flags field above */ /* Masks for Flags field above */
#define ACPI_TABLE_ORIGIN_UNKNOWN (0) #define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0) /* Virtual address, external maintained */
#define ACPI_TABLE_ORIGIN_MAPPED (1) #define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL (1) /* Physical address, internally mapped */
#define ACPI_TABLE_ORIGIN_ALLOCATED (2) #define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL (2) /* Virtual address, internallly allocated */
#define ACPI_TABLE_ORIGIN_OVERRIDE (4) #define ACPI_TABLE_ORIGIN_MASK (3)
#define ACPI_TABLE_ORIGIN_MASK (7) #define ACPI_TABLE_IS_LOADED (8)
#define ACPI_TABLE_IS_LOADED (8)
/* /*
* Get the remaining ACPI tables * Get the remaining ACPI tables
......
...@@ -675,7 +675,7 @@ enum acpi_madt_type { ...@@ -675,7 +675,7 @@ enum acpi_madt_type {
}; };
/* /*
* MADT Sub-tables, correspond to Type in struct acpi_subtable_header * MADT Subtables, correspond to Type in struct acpi_subtable_header
*/ */
/* 0: Processor Local APIC */ /* 0: Processor Local APIC */
...@@ -918,7 +918,7 @@ enum acpi_srat_type { ...@@ -918,7 +918,7 @@ enum acpi_srat_type {
}; };
/* /*
* SRAT Sub-tables, correspond to Type in struct acpi_subtable_header * SRAT Subtables, correspond to Type in struct acpi_subtable_header
*/ */
/* 0: Processor Local APIC/SAPIC Affinity */ /* 0: Processor Local APIC/SAPIC Affinity */
......
...@@ -70,6 +70,7 @@ ...@@ -70,6 +70,7 @@
#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */
#define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */ #define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */
#define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */ #define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */
#define ACPI_SIG_LPIT "LPIT" /* Low Power Idle Table */
#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ #define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */
#define ACPI_SIG_MCHI "MCHI" /* Management Controller Host Interface table */ #define ACPI_SIG_MCHI "MCHI" /* Management Controller Host Interface table */
#define ACPI_SIG_MTMR "MTMR" /* MID Timer table */ #define ACPI_SIG_MTMR "MTMR" /* MID Timer table */
...@@ -456,7 +457,7 @@ struct acpi_dmar_pci_path { ...@@ -456,7 +457,7 @@ struct acpi_dmar_pci_path {
}; };
/* /*
* DMAR Sub-tables, correspond to Type in struct acpi_dmar_header * DMAR Subtables, correspond to Type in struct acpi_dmar_header
*/ */
/* 0: Hardware Unit Definition */ /* 0: Hardware Unit Definition */
...@@ -820,7 +821,71 @@ struct acpi_ivrs_memory { ...@@ -820,7 +821,71 @@ struct acpi_ivrs_memory {
/******************************************************************************* /*******************************************************************************
* *
* MCFG - PCI Memory Mapped Configuration table and sub-table * LPIT - Low Power Idle Table
*
* Conforms to "ACPI Low Power Idle Table (LPIT) and _LPD Proposal (DRAFT)"
*
******************************************************************************/
struct acpi_table_lpit {
struct acpi_table_header header; /* Common ACPI table header */
};
/* LPIT subtable header */
struct acpi_lpit_header {
u32 type; /* Subtable type */
u32 length; /* Subtable length */
u16 unique_id;
u16 reserved;
u32 flags;
};
/* Values for subtable Type above */
enum acpi_lpit_type {
ACPI_LPIT_TYPE_NATIVE_CSTATE = 0x00,
ACPI_LPIT_TYPE_SIMPLE_IO = 0x01
};
/* Masks for Flags field above */
#define ACPI_LPIT_STATE_DISABLED (1)
#define ACPI_LPIT_NO_COUNTER (1<<1)
/*
* LPIT subtables, correspond to Type in struct acpi_lpit_header
*/
/* 0x00: Native C-state instruction based LPI structure */
struct acpi_lpit_native {
struct acpi_lpit_header header;
struct acpi_generic_address entry_trigger;
u32 residency;
u32 latency;
struct acpi_generic_address residency_counter;
u64 counter_frequency;
};
/* 0x01: Simple I/O based LPI structure */
struct acpi_lpit_io {
struct acpi_lpit_header header;
struct acpi_generic_address entry_trigger;
u32 trigger_action;
u64 trigger_value;
u64 trigger_mask;
struct acpi_generic_address minimum_idle_state;
u32 residency;
u32 latency;
struct acpi_generic_address residency_counter;
u64 counter_frequency;
};
/*******************************************************************************
*
* MCFG - PCI Memory Mapped Configuration table and subtable
* Version 1 * Version 1
* *
* Conforms to "PCI Firmware Specification", Revision 3.0, June 20, 2005 * Conforms to "PCI Firmware Specification", Revision 3.0, June 20, 2005
...@@ -923,7 +988,7 @@ enum acpi_slic_type { ...@@ -923,7 +988,7 @@ enum acpi_slic_type {
}; };
/* /*
* SLIC Sub-tables, correspond to Type in struct acpi_slic_header * SLIC Subtables, correspond to Type in struct acpi_slic_header
*/ */
/* 0: Public Key Structure */ /* 0: Public Key Structure */
......
...@@ -329,6 +329,15 @@ typedef u32 acpi_physical_address; ...@@ -329,6 +329,15 @@ typedef u32 acpi_physical_address;
* *
******************************************************************************/ ******************************************************************************/
#ifdef ACPI_NO_MEM_ALLOCATIONS
#define ACPI_ALLOCATE(a) NULL
#define ACPI_ALLOCATE_ZEROED(a) NULL
#define ACPI_FREE(a)
#define ACPI_MEM_TRACKING(a)
#else /* ACPI_NO_MEM_ALLOCATIONS */
#ifdef ACPI_DBG_TRACK_ALLOCATIONS #ifdef ACPI_DBG_TRACK_ALLOCATIONS
/* /*
* Memory allocation tracking (used by acpi_exec to detect memory leaks) * Memory allocation tracking (used by acpi_exec to detect memory leaks)
...@@ -350,6 +359,8 @@ typedef u32 acpi_physical_address; ...@@ -350,6 +359,8 @@ typedef u32 acpi_physical_address;
#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ #endif /* ACPI_DBG_TRACK_ALLOCATIONS */
#endif /* ACPI_NO_MEM_ALLOCATIONS */
/****************************************************************************** /******************************************************************************
* *
* ACPI Specification constants (Do not change unless the specification changes) * ACPI Specification constants (Do not change unless the specification changes)
...@@ -928,9 +939,19 @@ struct acpi_object_list { ...@@ -928,9 +939,19 @@ struct acpi_object_list {
* Miscellaneous common Data Structures used by the interfaces * Miscellaneous common Data Structures used by the interfaces
*/ */
#define ACPI_NO_BUFFER 0 #define ACPI_NO_BUFFER 0
#ifdef ACPI_NO_MEM_ALLOCATIONS
#define ACPI_ALLOCATE_BUFFER (acpi_size) (0)
#define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (0)
#else /* ACPI_NO_MEM_ALLOCATIONS */
#define ACPI_ALLOCATE_BUFFER (acpi_size) (-1) /* Let ACPICA allocate buffer */ #define ACPI_ALLOCATE_BUFFER (acpi_size) (-1) /* Let ACPICA allocate buffer */
#define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (-2) /* For internal use only (enables tracking) */ #define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (-2) /* For internal use only (enables tracking) */
#endif /* ACPI_NO_MEM_ALLOCATIONS */
struct acpi_buffer { struct acpi_buffer {
acpi_size length; /* Length in bytes of the buffer */ acpi_size length; /* Length in bytes of the buffer */
void *pointer; /* pointer to buffer */ void *pointer; /* pointer to buffer */
......
...@@ -64,4 +64,15 @@ ...@@ -64,4 +64,15 @@
*/ */
#define ACPI_UNUSED_VAR __attribute__ ((unused)) #define ACPI_UNUSED_VAR __attribute__ ((unused))
/*
* Some versions of gcc implement strchr() with a buggy macro. So,
* undef it here. Prevents error messages of this form (usually from the
* file getopt.c):
*
* error: logical '&&' with non-zero constant will always evaluate as true
*/
#ifdef strchr
#undef strchr
#endif
#endif /* __ACGCC_H__ */ #endif /* __ACGCC_H__ */
...@@ -73,6 +73,37 @@ ...@@ -73,6 +73,37 @@
#endif #endif
#include <asm/acpi.h> #include <asm/acpi.h>
#ifndef CONFIG_ACPI
/* External globals for __KERNEL__, stubs is needed */
#define ACPI_GLOBAL(t,a)
#define ACPI_INIT_GLOBAL(t,a,b)
/* Generating stubs for configurable ACPICA macros */
#define ACPI_NO_MEM_ALLOCATIONS
/* Generating stubs for configurable ACPICA functions */
#define ACPI_NO_ERROR_MESSAGES
#undef ACPI_DEBUG_OUTPUT
/* External interface for __KERNEL__, stub is needed */
#define ACPI_EXTERNAL_RETURN_STATUS(prototype) \
static ACPI_INLINE prototype {return(AE_NOT_CONFIGURED);}
#define ACPI_EXTERNAL_RETURN_OK(prototype) \
static ACPI_INLINE prototype {return(AE_OK);}
#define ACPI_EXTERNAL_RETURN_VOID(prototype) \
static ACPI_INLINE prototype {return;}
#define ACPI_EXTERNAL_RETURN_UINT32(prototype) \
static ACPI_INLINE prototype {return(0);}
#define ACPI_EXTERNAL_RETURN_PTR(prototype) \
static ACPI_INLINE prototype {return(NULL);}
#endif /* CONFIG_ACPI */
/* Host-dependent types and defines for in-kernel ACPICA */ /* Host-dependent types and defines for in-kernel ACPICA */
#define ACPI_MACHINE_WIDTH BITS_PER_LONG #define ACPI_MACHINE_WIDTH BITS_PER_LONG
...@@ -91,7 +122,7 @@ ...@@ -91,7 +122,7 @@
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #include <unistd.h>
/* Disable kernel specific declarators */ /* Define/disable kernel-specific declarators */
#ifndef __init #ifndef __init
#define __init #define __init
...@@ -106,7 +137,8 @@ ...@@ -106,7 +137,8 @@
#define ACPI_FLUSH_CPU_CACHE() #define ACPI_FLUSH_CPU_CACHE()
#define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread)) #define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread))
#if defined(__ia64__) || defined(__x86_64__) || defined(__aarch64__) #if defined(__ia64__) || defined(__x86_64__) ||\
defined(__aarch64__) || defined(__PPC64__)
#define ACPI_MACHINE_WIDTH 64 #define ACPI_MACHINE_WIDTH 64
#define COMPILER_DEPENDENT_INT64 long #define COMPILER_DEPENDENT_INT64 long
#define COMPILER_DEPENDENT_UINT64 unsigned long #define COMPILER_DEPENDENT_UINT64 unsigned long
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册