Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
23a75c52
Commit
23a75c52
authored
May 07, 2014
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back earlier ACPICA material.
parents
d48dc067
fd0c9405
Changes
38
Hide whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
4780 additions
and
1401 deletions
+4780
-1401
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+9
-1
drivers/acpi/acpica/Makefile
drivers/acpi/acpica/Makefile
+1
-0
drivers/acpi/acpica/acapps.h
drivers/acpi/acpica/acapps.h
+170
-0
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/acglobal.h
+5
-4
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/aclocal.h
+7
-1
drivers/acpi/acpica/actables.h
drivers/acpi/acpica/actables.h
+47
-13
drivers/acpi/acpica/acutils.h
drivers/acpi/acpica/acutils.h
+8
-2
drivers/acpi/acpica/evmisc.c
drivers/acpi/acpica/evmisc.c
+2
-1
drivers/acpi/acpica/evsci.c
drivers/acpi/acpica/evsci.c
+1
-1
drivers/acpi/acpica/evxface.c
drivers/acpi/acpica/evxface.c
+40
-21
drivers/acpi/acpica/exconfig.c
drivers/acpi/acpica/exconfig.c
+42
-40
drivers/acpi/acpica/exdump.c
drivers/acpi/acpica/exdump.c
+3
-1
drivers/acpi/acpica/tbdata.c
drivers/acpi/acpica/tbdata.c
+723
-0
drivers/acpi/acpica/tbfadt.c
drivers/acpi/acpica/tbfadt.c
+5
-5
drivers/acpi/acpica/tbfind.c
drivers/acpi/acpica/tbfind.c
+2
-2
drivers/acpi/acpica/tbinstal.c
drivers/acpi/acpica/tbinstal.c
+316
-521
drivers/acpi/acpica/tbutils.c
drivers/acpi/acpica/tbutils.c
+21
-150
drivers/acpi/acpica/tbxface.c
drivers/acpi/acpica/tbxface.c
+9
-9
drivers/acpi/acpica/tbxfload.c
drivers/acpi/acpica/tbxfload.c
+60
-27
drivers/acpi/acpica/utdecode.c
drivers/acpi/acpica/utdecode.c
+63
-11
drivers/acpi/acpica/utstring.c
drivers/acpi/acpica/utstring.c
+1
-1
drivers/acpi/osl.c
drivers/acpi/osl.c
+5
-6
include/acpi/acpixf.h
include/acpi/acpixf.h
+5
-2
include/acpi/actbl.h
include/acpi/actbl.h
+5
-6
include/acpi/platform/acgcc.h
include/acpi/platform/acgcc.h
+11
-0
include/acpi/platform/aclinux.h
include/acpi/platform/aclinux.h
+3
-2
tools/power/acpi/Makefile
tools/power/acpi/Makefile
+23
-3
tools/power/acpi/common/cmfsize.c
tools/power/acpi/common/cmfsize.c
+101
-0
tools/power/acpi/common/getopt.c
tools/power/acpi/common/getopt.c
+239
-0
tools/power/acpi/man/acpidump.8
tools/power/acpi/man/acpidump.8
+73
-12
tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
+1275
-0
tools/power/acpi/os_specific/service_layers/osunixdir.c
tools/power/acpi/os_specific/service_layers/osunixdir.c
+204
-0
tools/power/acpi/os_specific/service_layers/osunixmap.c
tools/power/acpi/os_specific/service_layers/osunixmap.c
+151
-0
tools/power/acpi/tools/acpidump/acpidump.c
tools/power/acpi/tools/acpidump/acpidump.c
+0
-559
tools/power/acpi/tools/acpidump/acpidump.h
tools/power/acpi/tools/acpidump/acpidump.h
+131
-0
tools/power/acpi/tools/acpidump/apdump.c
tools/power/acpi/tools/acpidump/apdump.c
+451
-0
tools/power/acpi/tools/acpidump/apfiles.c
tools/power/acpi/tools/acpidump/apfiles.c
+228
-0
tools/power/acpi/tools/acpidump/apmain.c
tools/power/acpi/tools/acpidump/apmain.c
+340
-0
No files found.
Documentation/kernel-parameters.txt
View file @
23a75c52
...
...
@@ -237,7 +237,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
This feature is enabled by default.
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]
Disable AML predefined validation mechanism
...
...
drivers/acpi/acpica/Makefile
View file @
23a75c52
...
...
@@ -135,6 +135,7 @@ acpi-y += \
rsxface.o
acpi-y
+=
\
tbdata.o
\
tbfadt.o
\
tbfind.o
\
tbinstal.o
\
...
...
drivers/acpi/acpica/acapps.h
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* 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 */
drivers/acpi/acpica/acglobal.h
View file @
23a75c52
...
...
@@ -103,8 +103,8 @@ 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.
* because ACPICA is fully compatible with other ACPI implementations.
* Changing this will revert ACPICA (and machine ASL) to pre-OSI behavior.
*/
ACPI_INIT_GLOBAL
(
u8
,
acpi_gbl_create_osi_method
,
TRUE
);
...
...
@@ -160,10 +160,10 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_truncate_io_addresses, FALSE);
ACPI_INIT_GLOBAL
(
u8
,
acpi_gbl_disable_auto_repair
,
FALSE
);
/*
* Optionally do not
load
any SSDTs from the RSDT/XSDT during initialization.
* Optionally do not
install
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
);
ACPI_INIT_GLOBAL
(
u8
,
acpi_gbl_disable_ssdt_table_
install
,
FALSE
);
/*
* We keep track of the latest version of Windows that has been requested by
...
...
@@ -509,5 +509,6 @@ ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL);
****************************************************************************/
extern
const
struct
ah_predefined_name
asl_predefined_info
[];
extern
const
struct
ah_device_id
asl_device_ids
[];
#endif
/* __ACGLOBAL_H__ */
drivers/acpi/acpica/aclocal.h
View file @
23a75c52
...
...
@@ -733,7 +733,8 @@ union acpi_parse_value {
#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_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)
...
...
@@ -1147,4 +1148,9 @@ struct ah_predefined_name {
#endif
};
struct
ah_device_id
{
char
*
name
;
char
*
description
;
};
#endif
/* __ACLOCAL_H__ */
drivers/acpi/acpica/actables.h
View file @
23a75c52
...
...
@@ -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
);
/*
* 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
*/
...
...
@@ -72,22 +92,35 @@ acpi_tb_find_table(char *signature,
*/
acpi_status
acpi_tb_resize_root_table_list
(
void
);
acpi_status
acpi_tb_v
erify
_table
(
struct
acpi_table_desc
*
table_desc
);
acpi_status
acpi_tb_v
alidate
_table
(
struct
acpi_table_desc
*
table_desc
);
struct
acpi_table_header
*
acpi_tb_table_override
(
struct
acpi_table_header
*
table_header
,
struct
acpi_table_desc
*
table_desc
);
void
acpi_tb_invalidate_table
(
struct
acpi_table_desc
*
table_desc
);
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_tb_store_table
(
acpi_physical_address
address
,
struct
acpi_table_header
*
table
,
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
);
...
...
@@ -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
);
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
*/
...
...
@@ -124,8 +153,13 @@ void acpi_tb_check_dsdt_header(void);
struct
acpi_table_header
*
acpi_tb_copy_dsdt
(
u32
table_index
);
void
acpi_tb_install_table
(
acpi_physical_address
address
,
char
*
signature
,
u32
table_index
);
acpi_tb_install_table_with_override
(
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
);
...
...
drivers/acpi/acpica/acutils.h
View file @
23a75c52
...
...
@@ -176,8 +176,7 @@ acpi_status acpi_ut_init_globals(void);
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
char
*
acpi_ut_get_type_name
(
acpi_object_type
type
);
...
...
@@ -737,4 +736,11 @@ acpi_ut_method_error(const char *module_name,
struct
acpi_namespace_node
*
node
,
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 */
drivers/acpi/acpica/evmisc.c
View file @
23a75c52
...
...
@@ -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
"
,
acpi_ut_get_node_name
(
node
),
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
,
info
);
...
...
drivers/acpi/acpica/evsci.c
View file @
23a75c52
...
...
@@ -117,7 +117,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)
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.
*/
...
...
drivers/acpi/acpica/evxface.c
View file @
23a75c52
...
...
@@ -239,7 +239,7 @@ acpi_remove_notify_handler(acpi_handle device,
union
acpi_operand_object
*
obj_desc
;
union
acpi_operand_object
*
handler_obj
;
union
acpi_operand_object
*
previous_handler_obj
;
acpi_status
status
;
acpi_status
status
=
AE_OK
;
u32
i
;
ACPI_FUNCTION_TRACE
(
acpi_remove_notify_handler
);
...
...
@@ -251,20 +251,17 @@ acpi_remove_notify_handler(acpi_handle device,
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 */
if
(
device
==
ACPI_ROOT_OBJECT
)
{
for
(
i
=
0
;
i
<
ACPI_NUM_NOTIFY_TYPES
;
i
++
)
{
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
||
(
acpi_gbl_global_notify
[
i
].
handler
!=
handler
))
{
...
...
@@ -277,31 +274,40 @@ acpi_remove_notify_handler(acpi_handle device,
acpi_gbl_global_notify
[
i
].
handler
=
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? */
if
(
!
acpi_ev_is_notify_object
(
node
))
{
status
=
AE_TYPE
;
goto
unlock_and_exit
;
return_ACPI_STATUS
(
AE_TYPE
);
}
/* Must have an existing internal object */
obj_desc
=
acpi_ns_get_attached_object
(
node
);
if
(
!
obj_desc
)
{
status
=
AE_NOT_EXIST
;
goto
unlock_and_exit
;
return_ACPI_STATUS
(
AE_NOT_EXIST
);
}
/* Internal object exists. Find the handler and remove it */
for
(
i
=
0
;
i
<
ACPI_NUM_NOTIFY_TYPES
;
i
++
)
{
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
];
previous_handler_obj
=
NULL
;
...
...
@@ -329,10 +335,17 @@ acpi_remove_notify_handler(acpi_handle device,
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
);
}
}
return_ACPI_STATUS
(
status
);
unlock_and_exit:
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_NAMESPACE
);
return_ACPI_STATUS
(
status
);
...
...
@@ -457,6 +470,8 @@ acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context)
return_ACPI_STATUS
(
status
);
}
ACPI_EXPORT_SYMBOL
(
acpi_install_sci_handler
)
/*******************************************************************************
*
* FUNCTION: acpi_remove_sci_handler
...
...
@@ -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.
*
******************************************************************************/
acpi_status
acpi_remove_sci_handler
(
acpi_sci_handler
address
)
{
struct
acpi_sci_handler_info
*
prev_sci_handler
;
...
...
@@ -522,6 +536,8 @@ acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
return_ACPI_STATUS
(
status
);
}
ACPI_EXPORT_SYMBOL
(
acpi_remove_sci_handler
)
/*******************************************************************************
*
* FUNCTION: acpi_install_global_event_handler
...
...
@@ -537,7 +553,6 @@ acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
* Can be used to update event counters, etc.
*
******************************************************************************/
acpi_status
acpi_install_global_event_handler
(
acpi_gbl_event_handler
handler
,
void
*
context
)
{
...
...
@@ -840,10 +855,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
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
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
...
...
@@ -895,9 +906,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
(
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 */
ACPI_FREE
(
handler
);
return_ACPI_STATUS
(
status
);
unlock_and_exit:
acpi_os_release_lock
(
acpi_gbl_gpe_lock
,
flags
);
...
...
drivers/acpi/acpica/exconfig.c
View file @
23a75c52
...
...
@@ -343,16 +343,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
struct
acpi_walk_state
*
walk_state
)
{
union
acpi_operand_object
*
ddb_handle
;
struct
acpi_table_header
*
table_header
;
struct
acpi_table_header
*
table
;
struct
acpi_table_desc
table_desc
;
u32
table_index
;
acpi_status
status
;
u32
length
;
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 */
switch
(
obj_desc
->
common
.
type
)
{
...
...
@@ -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 */
table
=
ACPI_ALLOCATE
(
sizeof
(
struct
acpi_table_header
));
if
(
!
table
)
{
table
_header
=
ACPI_ALLOCATE
(
sizeof
(
struct
acpi_table_header
));
if
(
!
table
_header
)
{
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
status
=
acpi_ex_region_read
(
obj_desc
,
sizeof
(
struct
acpi_table_header
),
ACPI_CAST_PTR
(
u8
,
table
));
length
=
table
->
length
;
ACPI_FREE
(
table
);
ACPI_CAST_PTR
(
u8
,
table
_header
));
length
=
table
_header
->
length
;
ACPI_FREE
(
table
_header
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
...
...
@@ -420,22 +418,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Allocate a buffer for the table */
table
_desc
.
pointer
=
ACPI_ALLOCATE
(
length
);
if
(
!
table
_desc
.
pointer
)
{
table
=
ACPI_ALLOCATE
(
length
);
if
(
!
table
)
{
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
/* Read the entire table */
status
=
acpi_ex_region_read
(
obj_desc
,
length
,
ACPI_CAST_PTR
(
u8
,
table_desc
.
pointer
));
ACPI_CAST_PTR
(
u8
,
table
));
if
(
ACPI_FAILURE
(
status
))
{
ACPI_FREE
(
table
_desc
.
pointer
);
ACPI_FREE
(
table
);
return_ACPI_STATUS
(
status
);
}
table_desc
.
address
=
obj_desc
->
region
.
address
;
break
;
case
ACPI_TYPE_BUFFER
:
/* Buffer or resolved region_field */
...
...
@@ -452,10 +447,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Get the actual table length from the table header */
table
=
table
_header
=
ACPI_CAST_PTR
(
struct
acpi_table_header
,
obj_desc
->
buffer
.
pointer
);
length
=
table
->
length
;
length
=
table
_header
->
length
;
/* Table cannot extend beyond the buffer */
...
...
@@ -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
* or even deleted in the future
*/
table
_desc
.
pointer
=
ACPI_ALLOCATE
(
length
);
if
(
!
table
_desc
.
pointer
)
{
table
=
ACPI_ALLOCATE
(
length
);
if
(
!
table
)
{
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
ACPI_MEMCPY
(
table_desc
.
pointer
,
table
,
length
);
table_desc
.
address
=
ACPI_TO_INTEGER
(
table_desc
.
pointer
);
ACPI_MEMCPY
(
table
,
table_header
,
length
);
break
;
default:
...
...
@@ -484,27 +478,32 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
return_ACPI_STATUS
(
AE_AML_OPERAND_TYPE
);
}
/* Validate table checksum (will not get validated in tb_add_table) */
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 */
/* Install the new table into the local data structures */
table_desc
.
length
=
length
;
table_desc
.
flags
=
ACPI_TABLE_ORIGIN_ALLOCATED
;
ACPI_INFO
((
AE_INFO
,
"Dynamic OEM Table Load:"
))
;
(
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
))
{
/* 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
);
}
...
...
@@ -536,9 +535,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
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 */
acpi_ut_remove_reference
(
ddb_handle
);
...
...
@@ -546,8 +542,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Invoke table handler if present */
if
(
acpi_gbl_table_handler
)
{
(
void
)
acpi_gbl_table_handler
(
ACPI_TABLE_EVENT_LOAD
,
table_desc
.
pointer
,
(
void
)
acpi_gbl_table_handler
(
ACPI_TABLE_EVENT_LOAD
,
table
,
acpi_gbl_table_handler_context
);
}
...
...
@@ -575,6 +570,13 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
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
* Although the handle is partially validated in acpi_ex_reconfiguration()
...
...
drivers/acpi/acpica/exdump.c
View file @
23a75c52
...
...
@@ -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"
}
};
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_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_UINT16
,
ACPI_EXD_OFFSET
(
mutex
.
acquisition_depth
),
"Acquire Depth"
},
...
...
drivers/acpi/acpica/tbdata.c
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: tbdata - Table manager data structure functions
*
*****************************************************************************/
/*
* 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.
*/
#include <acpi/acpi.h>
#include "accommon.h"
#include "acnamesp.h"
#include "actables.h"
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME
(
"tbdata"
)
/*******************************************************************************
*
* FUNCTION: acpi_tb_init_table_descriptor
*
* PARAMETERS: table_desc - Table descriptor
* address - Physical address of the table
* flags - Allocation flags of the table
* table - Pointer to the table
*
* RETURN: None
*
* DESCRIPTION: Initialize a new table descriptor
*
******************************************************************************/
void
acpi_tb_init_table_descriptor
(
struct
acpi_table_desc
*
table_desc
,
acpi_physical_address
address
,
u8
flags
,
struct
acpi_table_header
*
table
)
{
/*
* Initialize the table descriptor. Set the pointer to NULL, since the
* table is not fully mapped at this time.
*/
ACPI_MEMSET
(
table_desc
,
0
,
sizeof
(
struct
acpi_table_desc
));
table_desc
->
address
=
address
;
table_desc
->
length
=
table
->
length
;
table_desc
->
flags
=
flags
;
ACPI_MOVE_32_TO_32
(
table_desc
->
signature
.
ascii
,
table
->
signature
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_acquire_table
*
* PARAMETERS: table_desc - Table descriptor
* table_ptr - Where table is returned
* table_length - Where table length is returned
* table_flags - Where table allocation flags are returned
*
* RETURN: Status
*
* DESCRIPTION: Acquire an ACPI table. It can be used for tables not
* maintained in the acpi_gbl_root_table_list.
*
******************************************************************************/
acpi_status
acpi_tb_acquire_table
(
struct
acpi_table_desc
*
table_desc
,
struct
acpi_table_header
**
table_ptr
,
u32
*
table_length
,
u8
*
table_flags
)
{
struct
acpi_table_header
*
table
=
NULL
;
switch
(
table_desc
->
flags
&
ACPI_TABLE_ORIGIN_MASK
)
{
case
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL
:
table
=
acpi_os_map_memory
(
table_desc
->
address
,
table_desc
->
length
);
break
;
case
ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL
:
case
ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL
:
table
=
ACPI_CAST_PTR
(
struct
acpi_table_header
,
table_desc
->
address
);
break
;
default:
break
;
}
/* Table is not valid yet */
if
(
!
table
)
{
return
(
AE_NO_MEMORY
);
}
/* Fill the return values */
*
table_ptr
=
table
;
*
table_length
=
table_desc
->
length
;
*
table_flags
=
table_desc
->
flags
;
return
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_release_table
*
* PARAMETERS: table - Pointer for the table
* table_length - Length for the table
* table_flags - Allocation flags for the table
*
* RETURN: None
*
* DESCRIPTION: Release a table. The inverse of acpi_tb_acquire_table().
*
******************************************************************************/
void
acpi_tb_release_table
(
struct
acpi_table_header
*
table
,
u32
table_length
,
u8
table_flags
)
{
switch
(
table_flags
&
ACPI_TABLE_ORIGIN_MASK
)
{
case
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL
:
acpi_os_unmap_memory
(
table
,
table_length
);
break
;
case
ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL
:
case
ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL
:
default:
break
;
}
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_acquire_temp_table
*
* PARAMETERS: table_desc - Table descriptor to be acquired
* address - Address of the table
* flags - Allocation flags of the table
*
* RETURN: Status
*
* DESCRIPTION: This function validates the table header to obtain the length
* of a table and fills the table descriptor to make its state as
* "INSTALLED". Such a table descriptor is only used for verified
* installation.
*
******************************************************************************/
acpi_status
acpi_tb_acquire_temp_table
(
struct
acpi_table_desc
*
table_desc
,
acpi_physical_address
address
,
u8
flags
)
{
struct
acpi_table_header
*
table_header
;
switch
(
flags
&
ACPI_TABLE_ORIGIN_MASK
)
{
case
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL
:
/* Get the length of the full table from the header */
table_header
=
acpi_os_map_memory
(
address
,
sizeof
(
struct
acpi_table_header
));
if
(
!
table_header
)
{
return
(
AE_NO_MEMORY
);
}
acpi_tb_init_table_descriptor
(
table_desc
,
address
,
flags
,
table_header
);
acpi_os_unmap_memory
(
table_header
,
sizeof
(
struct
acpi_table_header
));
return
(
AE_OK
);
case
ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL
:
case
ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL
:
table_header
=
ACPI_CAST_PTR
(
struct
acpi_table_header
,
address
);
if
(
!
table_header
)
{
return
(
AE_NO_MEMORY
);
}
acpi_tb_init_table_descriptor
(
table_desc
,
address
,
flags
,
table_header
);
return
(
AE_OK
);
default:
break
;
}
/* Table is not valid yet */
return
(
AE_NO_MEMORY
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_release_temp_table
*
* PARAMETERS: table_desc - Table descriptor to be released
*
* RETURN: Status
*
* DESCRIPTION: The inverse of acpi_tb_acquire_temp_table().
*
*****************************************************************************/
void
acpi_tb_release_temp_table
(
struct
acpi_table_desc
*
table_desc
)
{
/*
* Note that the .Address is maintained by the callers of
* acpi_tb_acquire_temp_table(), thus do not invoke acpi_tb_uninstall_table()
* where .Address will be freed.
*/
acpi_tb_invalidate_table
(
table_desc
);
}
/******************************************************************************
*
* FUNCTION: acpi_tb_validate_table
*
* PARAMETERS: table_desc - Table descriptor
*
* RETURN: Status
*
* DESCRIPTION: This function is called to validate the table, the returned
* table descriptor is in "VALIDATED" state.
*
*****************************************************************************/
acpi_status
acpi_tb_validate_table
(
struct
acpi_table_desc
*
table_desc
)
{
acpi_status
status
=
AE_OK
;
ACPI_FUNCTION_TRACE
(
tb_validate_table
);
/* Validate the table if necessary */
if
(
!
table_desc
->
pointer
)
{
status
=
acpi_tb_acquire_table
(
table_desc
,
&
table_desc
->
pointer
,
&
table_desc
->
length
,
&
table_desc
->
flags
);
if
(
!
table_desc
->
pointer
)
{
status
=
AE_NO_MEMORY
;
}
}
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_invalidate_table
*
* PARAMETERS: table_desc - Table descriptor
*
* RETURN: None
*
* DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
* acpi_tb_validate_table().
*
******************************************************************************/
void
acpi_tb_invalidate_table
(
struct
acpi_table_desc
*
table_desc
)
{
ACPI_FUNCTION_TRACE
(
tb_invalidate_table
);
/* Table must be validated */
if
(
!
table_desc
->
pointer
)
{
return_VOID
;
}
acpi_tb_release_table
(
table_desc
->
pointer
,
table_desc
->
length
,
table_desc
->
flags
);
table_desc
->
pointer
=
NULL
;
return_VOID
;
}
/******************************************************************************
*
* FUNCTION: acpi_tb_verify_table
*
* PARAMETERS: table_desc - Table descriptor
* signature - Table signature to verify
*
* RETURN: Status
*
* DESCRIPTION: This function is called to validate and verify the table, the
* returned table descriptor is in "VALIDATED" state.
*
*****************************************************************************/
acpi_status
acpi_tb_verify_table
(
struct
acpi_table_desc
*
table_desc
,
char
*
signature
)
{
acpi_status
status
=
AE_OK
;
ACPI_FUNCTION_TRACE
(
tb_verify_table
);
/* Validate the table */
status
=
acpi_tb_validate_table
(
table_desc
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
/* If a particular signature is expected (DSDT/FACS), it must match */
if
(
signature
&&
!
ACPI_COMPARE_NAME
(
&
table_desc
->
signature
,
signature
))
{
ACPI_BIOS_ERROR
((
AE_INFO
,
"Invalid signature 0x%X for ACPI table, expected [%s]"
,
table_desc
->
signature
.
integer
,
signature
));
status
=
AE_BAD_SIGNATURE
;
goto
invalidate_and_exit
;
}
/* Verify the checksum */
status
=
acpi_tb_verify_checksum
(
table_desc
->
pointer
,
table_desc
->
length
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
AE_NO_MEMORY
,
"%4.4s "
ACPI_PRINTF_UINT
" Attempted table install failed"
,
acpi_ut_valid_acpi_name
(
table_desc
->
signature
.
ascii
)
?
table_desc
->
signature
.
ascii
:
"????"
,
ACPI_FORMAT_TO_UINT
(
table_desc
->
address
)));
goto
invalidate_and_exit
;
}
return_ACPI_STATUS
(
AE_OK
);
invalidate_and_exit:
acpi_tb_invalidate_table
(
table_desc
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_resize_root_table_list
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Expand the size of global table array
*
******************************************************************************/
acpi_status
acpi_tb_resize_root_table_list
(
void
)
{
struct
acpi_table_desc
*
tables
;
u32
table_count
;
ACPI_FUNCTION_TRACE
(
tb_resize_root_table_list
);
/* allow_resize flag is a parameter to acpi_initialize_tables */
if
(
!
(
acpi_gbl_root_table_list
.
flags
&
ACPI_ROOT_ALLOW_RESIZE
))
{
ACPI_ERROR
((
AE_INFO
,
"Resize of Root Table Array is not allowed"
));
return_ACPI_STATUS
(
AE_SUPPORT
);
}
/* Increase the Table Array size */
if
(
acpi_gbl_root_table_list
.
flags
&
ACPI_ROOT_ORIGIN_ALLOCATED
)
{
table_count
=
acpi_gbl_root_table_list
.
max_table_count
;
}
else
{
table_count
=
acpi_gbl_root_table_list
.
current_table_count
;
}
tables
=
ACPI_ALLOCATE_ZEROED
(((
acpi_size
)
table_count
+
ACPI_ROOT_TABLE_SIZE_INCREMENT
)
*
sizeof
(
struct
acpi_table_desc
));
if
(
!
tables
)
{
ACPI_ERROR
((
AE_INFO
,
"Could not allocate new root table array"
));
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
/* Copy and free the previous table array */
if
(
acpi_gbl_root_table_list
.
tables
)
{
ACPI_MEMCPY
(
tables
,
acpi_gbl_root_table_list
.
tables
,
(
acpi_size
)
table_count
*
sizeof
(
struct
acpi_table_desc
));
if
(
acpi_gbl_root_table_list
.
flags
&
ACPI_ROOT_ORIGIN_ALLOCATED
)
{
ACPI_FREE
(
acpi_gbl_root_table_list
.
tables
);
}
}
acpi_gbl_root_table_list
.
tables
=
tables
;
acpi_gbl_root_table_list
.
max_table_count
=
table_count
+
ACPI_ROOT_TABLE_SIZE_INCREMENT
;
acpi_gbl_root_table_list
.
flags
|=
ACPI_ROOT_ORIGIN_ALLOCATED
;
return_ACPI_STATUS
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_next_root_index
*
* PARAMETERS: table_index - Where table index is returned
*
* RETURN: Status and table index.
*
* DESCRIPTION: Allocate a new ACPI table entry to the global table list
*
******************************************************************************/
acpi_status
acpi_tb_get_next_root_index
(
u32
*
table_index
)
{
acpi_status
status
;
/* Ensure that there is room for the table in the Root Table List */
if
(
acpi_gbl_root_table_list
.
current_table_count
>=
acpi_gbl_root_table_list
.
max_table_count
)
{
status
=
acpi_tb_resize_root_table_list
();
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
}
*
table_index
=
acpi_gbl_root_table_list
.
current_table_count
;
acpi_gbl_root_table_list
.
current_table_count
++
;
return
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_terminate
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Delete all internal ACPI tables
*
******************************************************************************/
void
acpi_tb_terminate
(
void
)
{
u32
i
;
ACPI_FUNCTION_TRACE
(
tb_terminate
);
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
/* Delete the individual tables */
for
(
i
=
0
;
i
<
acpi_gbl_root_table_list
.
current_table_count
;
i
++
)
{
acpi_tb_uninstall_table
(
&
acpi_gbl_root_table_list
.
tables
[
i
]);
}
/*
* Delete the root table array if allocated locally. Array cannot be
* mapped, so we don't need to check for that flag.
*/
if
(
acpi_gbl_root_table_list
.
flags
&
ACPI_ROOT_ORIGIN_ALLOCATED
)
{
ACPI_FREE
(
acpi_gbl_root_table_list
.
tables
);
}
acpi_gbl_root_table_list
.
tables
=
NULL
;
acpi_gbl_root_table_list
.
flags
=
0
;
acpi_gbl_root_table_list
.
current_table_count
=
0
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"ACPI Tables freed
\n
"
));
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_VOID
;
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_delete_namespace_by_owner
*
* PARAMETERS: table_index - Table index
*
* RETURN: Status
*
* DESCRIPTION: Delete all namespace objects created when this table was loaded.
*
******************************************************************************/
acpi_status
acpi_tb_delete_namespace_by_owner
(
u32
table_index
)
{
acpi_owner_id
owner_id
;
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
tb_delete_namespace_by_owner
);
status
=
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
if
(
table_index
>=
acpi_gbl_root_table_list
.
current_table_count
)
{
/* The table index does not exist */
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
AE_NOT_EXIST
);
}
/* Get the owner ID for this table, used to delete namespace nodes */
owner_id
=
acpi_gbl_root_table_list
.
tables
[
table_index
].
owner_id
;
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
/*
* Need to acquire the namespace writer lock to prevent interference
* with any concurrent namespace walks. The interpreter must be
* released during the deletion since the acquisition of the deletion
* lock may block, and also since the execution of a namespace walk
* must be allowed to use the interpreter.
*/
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_INTERPRETER
);
status
=
acpi_ut_acquire_write_lock
(
&
acpi_gbl_namespace_rw_lock
);
acpi_ns_delete_namespace_by_owner
(
owner_id
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
acpi_ut_release_write_lock
(
&
acpi_gbl_namespace_rw_lock
);
status
=
acpi_ut_acquire_mutex
(
ACPI_MTX_INTERPRETER
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_allocate_owner_id
*
* PARAMETERS: table_index - Table index
*
* RETURN: Status
*
* DESCRIPTION: Allocates owner_id in table_desc
*
******************************************************************************/
acpi_status
acpi_tb_allocate_owner_id
(
u32
table_index
)
{
acpi_status
status
=
AE_BAD_PARAMETER
;
ACPI_FUNCTION_TRACE
(
tb_allocate_owner_id
);
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
status
=
acpi_ut_allocate_owner_id
(
&
(
acpi_gbl_root_table_list
.
tables
[
table_index
].
owner_id
));
}
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_release_owner_id
*
* PARAMETERS: table_index - Table index
*
* RETURN: Status
*
* DESCRIPTION: Releases owner_id in table_desc
*
******************************************************************************/
acpi_status
acpi_tb_release_owner_id
(
u32
table_index
)
{
acpi_status
status
=
AE_BAD_PARAMETER
;
ACPI_FUNCTION_TRACE
(
tb_release_owner_id
);
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
acpi_ut_release_owner_id
(
&
(
acpi_gbl_root_table_list
.
tables
[
table_index
].
owner_id
));
status
=
AE_OK
;
}
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_owner_id
*
* PARAMETERS: table_index - Table index
* owner_id - Where the table owner_id is returned
*
* RETURN: Status
*
* DESCRIPTION: returns owner_id for the ACPI table
*
******************************************************************************/
acpi_status
acpi_tb_get_owner_id
(
u32
table_index
,
acpi_owner_id
*
owner_id
)
{
acpi_status
status
=
AE_BAD_PARAMETER
;
ACPI_FUNCTION_TRACE
(
tb_get_owner_id
);
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
*
owner_id
=
acpi_gbl_root_table_list
.
tables
[
table_index
].
owner_id
;
status
=
AE_OK
;
}
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_is_table_loaded
*
* PARAMETERS: table_index - Index into the root table
*
* RETURN: Table Loaded Flag
*
******************************************************************************/
u8
acpi_tb_is_table_loaded
(
u32
table_index
)
{
u8
is_loaded
=
FALSE
;
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
is_loaded
=
(
u8
)
(
acpi_gbl_root_table_list
.
tables
[
table_index
].
flags
&
ACPI_TABLE_IS_LOADED
);
}
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return
(
is_loaded
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_set_table_loaded_flag
*
* PARAMETERS: table_index - Table index
* is_loaded - TRUE if table is loaded, FALSE otherwise
*
* RETURN: None
*
* DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
*
******************************************************************************/
void
acpi_tb_set_table_loaded_flag
(
u32
table_index
,
u8
is_loaded
)
{
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
if
(
is_loaded
)
{
acpi_gbl_root_table_list
.
tables
[
table_index
].
flags
|=
ACPI_TABLE_IS_LOADED
;
}
else
{
acpi_gbl_root_table_list
.
tables
[
table_index
].
flags
&=
~
ACPI_TABLE_IS_LOADED
;
}
}
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
}
drivers/acpi/acpica/tbfadt.c
View file @
23a75c52
...
...
@@ -332,15 +332,15 @@ void acpi_tb_parse_fadt(u32 table_index)
/* Obtain the DSDT and FACS tables via their addresses within the FADT */
acpi_tb_install_table
((
acpi_physical_address
)
acpi_gbl_FADT
.
Xdsdt
,
ACPI_SIG_DSDT
,
ACPI_TABLE_INDEX_DSDT
);
acpi_tb_install_
fixed_
table
((
acpi_physical_address
)
acpi_gbl_FADT
.
Xdsdt
,
ACPI_SIG_DSDT
,
ACPI_TABLE_INDEX_DSDT
);
/* If Hardware Reduced flag is set, there is no FACS */
if
(
!
acpi_gbl_reduced_hardware
)
{
acpi_tb_install_
table
((
acpi_physical_address
)
acpi_gbl_FADT
.
Xfacs
,
ACPI_SIG_FACS
,
ACPI_TABLE_INDEX_FACS
);
acpi_tb_install_
fixed_table
((
acpi_physical_address
)
acpi_gbl_FADT
.
Xfacs
,
ACPI_SIG_FACS
,
ACPI_TABLE_INDEX_FACS
);
}
}
...
...
drivers/acpi/acpica/tbfind.c
View file @
23a75c52
...
...
@@ -99,8 +99,8 @@ acpi_tb_find_table(char *signature,
/* Table is not currently mapped, map it */
status
=
acpi_tb_v
erify
_table
(
&
acpi_gbl_root_table_list
.
tables
[
i
]);
acpi_tb_v
alidate
_table
(
&
acpi_gbl_root_table_list
.
tables
[
i
]);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
...
...
drivers/acpi/acpica/tbinstal.c
View file @
23a75c52
...
...
@@ -43,688 +43,483 @@
#include <acpi/acpi.h>
#include "accommon.h"
#include "acnamesp.h"
#include "actables.h"
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME
(
"tbinstal"
)
/******************************************************************************
/* Local prototypes */
static
u8
acpi_tb_compare_tables
(
struct
acpi_table_desc
*
table_desc
,
u32
table_index
);
/*******************************************************************************
*
* FUNCTION: acpi_tb_
verify_table
* FUNCTION: acpi_tb_
compare_tables
*
* PARAMETERS: table_desc - table
* PARAMETERS: table_desc - Table 1 descriptor to be compared
* table_index - Index of table 2 to be compared
*
* RETURN:
Status
* RETURN:
TRUE if both tables are identical.
*
* DESCRIPTION: this function is called to verify and map table
* DESCRIPTION: This function compares a table with another table that has
* already been installed in the root table list.
*
*****************************************************************************/
acpi_status
acpi_tb_verify_table
(
struct
acpi_table_desc
*
table_desc
)
******************************************************************************/
static
u8
acpi_tb_compare_tables
(
struct
acpi_table_desc
*
table_desc
,
u32
table_index
)
{
acpi_status
status
=
AE_OK
;
u8
is_identical
;
struct
acpi_table_header
*
table
;
u32
table_length
;
u8
table_flags
;
ACPI_FUNCTION_TRACE
(
tb_verify_table
);
/* Map the table if necessary */
if
(
!
table_desc
->
pointer
)
{
if
((
table_desc
->
flags
&
ACPI_TABLE_ORIGIN_MASK
)
==
ACPI_TABLE_ORIGIN_MAPPED
)
{
table_desc
->
pointer
=
acpi_os_map_memory
(
table_desc
->
address
,
table_desc
->
length
);
}
if
(
!
table_desc
->
pointer
)
{
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
status
=
acpi_tb_acquire_table
(
&
acpi_gbl_root_table_list
.
tables
[
table_index
],
&
table
,
&
table_length
,
&
table_flags
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
FALSE
);
}
/* Always calculate checksum, ignore bad checksum if requested */
/*
* Check for a table match on the entire table length,
* not just the header.
*/
is_identical
=
(
u8
)((
table_desc
->
length
!=
table_length
||
ACPI_MEMCMP
(
table_desc
->
pointer
,
table
,
table_length
))
?
FALSE
:
TRUE
);
status
=
acpi_tb_verify_checksum
(
table_desc
->
pointer
,
table_desc
->
length
);
/* Release the acquired table */
return_ACPI_STATUS
(
status
);
acpi_tb_release_table
(
table
,
table_length
,
table_flags
);
return
(
is_identical
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_
add_tabl
e
* FUNCTION: acpi_tb_
install_table_with_overrid
e
*
* PARAMETERS: table_desc - Table descriptor
* table_index - Where the table index is returned
* PARAMETERS: table_index - Index into root table array
* new_table_desc - New table descriptor to install
* override - Whether override should be performed
*
* RETURN:
Status
* RETURN:
None
*
* DESCRIPTION: This function is called to add an ACPI table. It is used to
* dynamically load tables via the Load and load_table AML
* operators.
* 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.
*
******************************************************************************/
acpi_status
acpi_tb_add_table
(
struct
acpi_table_desc
*
table_desc
,
u32
*
table_index
)
void
acpi_tb_install_table_with_override
(
u32
table_index
,
struct
acpi_table_desc
*
new_table_desc
,
u8
override
)
{
u32
i
;
acpi_status
status
=
AE_OK
;
ACPI_FUNCTION_TRACE
(
tb_add_table
);
if
(
!
table_desc
->
pointer
)
{
status
=
acpi_tb_verify_table
(
table_desc
);
if
(
ACPI_FAILURE
(
status
)
||
!
table_desc
->
pointer
)
{
return_ACPI_STATUS
(
status
);
}
if
(
table_index
>=
acpi_gbl_root_table_list
.
current_table_count
)
{
return
;
}
/*
*
Validate the incoming table signature.
*
ACPI Table Override:
*
* 1) Originally, we checked the table signature for "SSDT" or "PSDT".
* 2) We added support for OEMx tables, signature "OEM".
* 3) Valid tables were encountered with a null signature, so we just
* gave up on validating the signature, (05/2008).
* 4) We encountered non-AML tables such as the MADT, which caused
* interpreter errors and kernel faults. So now, we once again allow
* only "SSDT", "OEMx", and now, also a null signature. (05/2011).
* 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.
*/
if
((
table_desc
->
pointer
->
signature
[
0
]
!=
0x00
)
&&
(
!
ACPI_COMPARE_NAME
(
table_desc
->
pointer
->
signature
,
ACPI_SIG_SSDT
))
&&
(
ACPI_STRNCMP
(
table_desc
->
pointer
->
signature
,
"OEM"
,
3
)))
{
ACPI_BIOS_ERROR
((
AE_INFO
,
"Table has invalid signature [%4.4s] (0x%8.8X), "
"must be SSDT or OEMx"
,
acpi_ut_valid_acpi_name
(
table_desc
->
pointer
->
signature
)
?
table_desc
->
pointer
->
signature
:
"????"
,
*
(
u32
*
)
table_desc
->
pointer
->
signature
));
return_ACPI_STATUS
(
AE_BAD_SIGNATURE
);
if
(
override
)
{
acpi_tb_override_table
(
new_table_desc
);
}
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
acpi_tb_init_table_descriptor
(
&
acpi_gbl_root_table_list
.
tables
[
table_index
],
new_table_desc
->
address
,
new_table_desc
->
flags
,
new_table_desc
->
pointer
);
/* Check if table is already registered */
acpi_tb_print_table_header
(
new_table_desc
->
address
,
new_table_desc
->
pointer
);
for
(
i
=
0
;
i
<
acpi_gbl_root_table_list
.
current_table_count
;
++
i
)
{
if
(
!
acpi_gbl_root_table_list
.
tables
[
i
].
pointer
)
{
status
=
acpi_tb_verify_table
(
&
acpi_gbl_root_table_list
.
tables
[
i
]);
if
(
ACPI_FAILURE
(
status
)
||
!
acpi_gbl_root_table_list
.
tables
[
i
].
pointer
)
{
continue
;
}
}
/* Set the global integer width (based upon revision of the DSDT) */
/*
* Check for a table match on the entire table length,
* not just the header.
*/
if
(
table_desc
->
length
!=
acpi_gbl_root_table_list
.
tables
[
i
].
length
)
{
continue
;
}
if
(
ACPI_MEMCMP
(
table_desc
->
pointer
,
acpi_gbl_root_table_list
.
tables
[
i
].
pointer
,
acpi_gbl_root_table_list
.
tables
[
i
].
length
))
{
continue
;
}
/*
* Note: the current mechanism does not unregister a table if it is
* dynamically unloaded. The related namespace entries are deleted,
* but the table remains in the root table list.
*
* The assumption here is that the number of different tables that
* will be loaded is actually small, and there is minimal overhead
* in just keeping the table in case it is needed again.
*
* If this assumption changes in the future (perhaps on large
* machines with many table load/unload operations), tables will
* need to be unregistered when they are unloaded, and slots in the
* root table list should be reused when empty.
*/
/*
* Table is already registered.
* We can delete the table that was passed as a parameter.
*/
acpi_tb_delete_table
(
table_desc
);
*
table_index
=
i
;
if
(
acpi_gbl_root_table_list
.
tables
[
i
].
flags
&
ACPI_TABLE_IS_LOADED
)
{
/* Table is still loaded, this is an error */
status
=
AE_ALREADY_EXISTS
;
goto
release
;
}
else
{
/* Table was unloaded, allow it to be reloaded */
table_desc
->
pointer
=
acpi_gbl_root_table_list
.
tables
[
i
].
pointer
;
table_desc
->
address
=
acpi_gbl_root_table_list
.
tables
[
i
].
address
;
status
=
AE_OK
;
goto
print_header
;
}
if
(
table_index
==
ACPI_TABLE_INDEX_DSDT
)
{
acpi_ut_set_integer_width
(
new_table_desc
->
pointer
->
revision
);
}
/*
* ACPI Table Override:
* Allow the host to override dynamically loaded tables.
* NOTE: the table is fully mapped at this point, and the mapping will
* be deleted by tb_table_override if the table is actually overridden.
*/
(
void
)
acpi_tb_table_override
(
table_desc
->
pointer
,
table_desc
);
/* Add the table to the global root table list */
status
=
acpi_tb_store_table
(
table_desc
->
address
,
table_desc
->
pointer
,
table_desc
->
length
,
table_desc
->
flags
,
table_index
);
if
(
ACPI_FAILURE
(
status
))
{
goto
release
;
}
print_header:
acpi_tb_print_table_header
(
table_desc
->
address
,
table_desc
->
pointer
);
release:
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_
table_overrid
e
* FUNCTION: acpi_tb_
install_fixed_tabl
e
*
* PARAMETERS: table_header - Header for the original table
* table_desc - Table descriptor initialized for the
* original table. May or may not be mapped.
* 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: Pointer to the entire new table. NULL if table not overridden.
* If overridden, installs the new table within the input table
* descriptor.
* RETURN: Status
*
* DESCRIPTION: Attempt table override by calling the OSL override functions.
* Note: If the table is overridden, then the entire new table
* is mapped and returned by this function.
* DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data
* structure.
*
******************************************************************************/
struct
acpi_table_header
*
acpi_tb_table_override
(
struct
acpi_table_header
*
table_header
,
struct
acpi_table_desc
*
table_desc
)
acpi_status
acpi_tb_install_fixed_table
(
acpi_physical_address
address
,
char
*
signature
,
u32
table_index
)
{
struct
acpi_table_desc
new_table_desc
;
acpi_status
status
;
struct
acpi_table_header
*
new_table
=
NULL
;
acpi_physical_address
new_address
=
0
;
u32
new_table_length
=
0
;
u8
new_flags
;
char
*
override_type
;
/* (1) Attempt logical override (returns a logical address) */
ACPI_FUNCTION_TRACE
(
tb_install_fixed_table
);
status
=
acpi_os_table_override
(
table_header
,
&
new_table
);
if
(
ACPI_SUCCESS
(
status
)
&&
new_table
)
{
new_address
=
ACPI_PTR_TO_PHYSADDR
(
new_table
);
new_table_length
=
new_table
->
length
;
new_flags
=
ACPI_TABLE_ORIGIN_OVERRIDE
;
override_type
=
"Logical"
;
goto
finish_override
;
if
(
!
address
)
{
ACPI_ERROR
((
AE_INFO
,
"Null physical address for ACPI table [%s]"
,
signature
));
return
(
AE_NO_MEMORY
);
}
/*
(2) Attempt physical override (returns a physical address)
*/
/*
Fill a table descriptor for validation
*/
status
=
acpi_os_physical_table_override
(
table_header
,
&
new_address
,
&
new_table_length
);
if
(
ACPI_SUCCESS
(
status
)
&&
new_address
&&
new_table_length
)
{
/* Map the entire new table */
new_table
=
acpi_os_map_memory
(
new_address
,
new_table_length
);
if
(
!
new_table
)
{
ACPI_EXCEPTION
((
AE_INFO
,
AE_NO_MEMORY
,
"%4.4s "
ACPI_PRINTF_UINT
" Attempted physical table override failed"
,
table_header
->
signature
,
ACPI_FORMAT_TO_UINT
(
table_desc
->
address
)));
return
(
NULL
);
}
override_type
=
"Physical"
;
new_flags
=
ACPI_TABLE_ORIGIN_MAPPED
;
goto
finish_override
;
status
=
acpi_tb_acquire_temp_table
(
&
new_table_desc
,
address
,
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_ERROR
((
AE_INFO
,
"Could not acquire table length at %p"
,
ACPI_CAST_PTR
(
void
,
address
)));
return_ACPI_STATUS
(
status
);
}
return
(
NULL
);
/* There was no override */
finish_override:
ACPI_INFO
((
AE_INFO
,
"%4.4s "
ACPI_PRINTF_UINT
" %s table override, new table: "
ACPI_PRINTF_UINT
,
table_header
->
signature
,
ACPI_FORMAT_TO_UINT
(
table_desc
->
address
),
override_type
,
ACPI_FORMAT_TO_UINT
(
new_table
)));
/* Validate and verify a table before installation */
/* We can now unmap/delete the original table (if fully mapped) */
status
=
acpi_tb_verify_table
(
&
new_table_desc
,
signature
);
if
(
ACPI_FAILURE
(
status
))
{
goto
release_and_exit
;
}
acpi_tb_
delete_table
(
table_desc
);
acpi_tb_
install_table_with_override
(
table_index
,
&
new_table_desc
,
TRUE
);
/* Setup descriptor for the new table */
release_and_exit:
table_desc
->
address
=
new_address
;
table_desc
->
pointer
=
new_table
;
table_desc
->
length
=
new_table_length
;
table_desc
->
flags
=
new_flags
;
/* Release the temporary table descriptor */
return
(
new_table
);
acpi_tb_release_temp_table
(
&
new_table_desc
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_
resize_root_table_list
* FUNCTION: acpi_tb_
install_standard_table
*
* PARAMETERS: None
* PARAMETERS: address - Address of the table (might be a virtual
* address depending on the table_flags)
* flags - Flags for the table
* reload - Whether reload should be performed
* override - Whether override should be performed
* table_index - Where the table index is returned
*
* RETURN: Status
*
* DESCRIPTION: Expand the size of global table array
* DESCRIPTION: This function is called to install an ACPI table that is
* neither DSDT nor FACS (a "standard" table.)
* When this function is called by "Load" or "LoadTable" opcodes,
* or by acpi_load_table() API, the "Reload" parameter is set.
* After sucessfully returning from this function, table is
* "INSTALLED" but not "VALIDATED".
*
******************************************************************************/
acpi_status
acpi_tb_resize_root_table_list
(
void
)
acpi_status
acpi_tb_install_standard_table
(
acpi_physical_address
address
,
u8
flags
,
u8
reload
,
u8
override
,
u32
*
table_index
)
{
struct
acpi_table_desc
*
tables
;
u32
table_count
;
ACPI_FUNCTION_TRACE
(
tb_resize_root_table_list
);
/* allow_resize flag is a parameter to acpi_initialize_tables */
u32
i
;
acpi_status
status
=
AE_OK
;
struct
acpi_table_desc
new_table_desc
;
if
(
!
(
acpi_gbl_root_table_list
.
flags
&
ACPI_ROOT_ALLOW_RESIZE
))
{
ACPI_ERROR
((
AE_INFO
,
"Resize of Root Table Array is not allowed"
));
return_ACPI_STATUS
(
AE_SUPPORT
);
}
ACPI_FUNCTION_TRACE
(
tb_install_standard_table
);
/*
Increase the Table Array size
*/
/*
Acquire a temporary table descriptor for validation
*/
if
(
acpi_gbl_root_table_list
.
flags
&
ACPI_ROOT_ORIGIN_ALLOCATED
)
{
table_count
=
acpi_gbl_root_table_list
.
max_table_count
;
}
else
{
table_count
=
acpi_gbl_root_table_list
.
current_table_count
;
status
=
acpi_tb_acquire_temp_table
(
&
new_table_desc
,
address
,
flags
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_ERROR
((
AE_INFO
,
"Could not acquire table length at %p"
,
ACPI_CAST_PTR
(
void
,
address
)));
return_ACPI_STATUS
(
status
);
}
tables
=
ACPI_ALLOCATE_ZEROED
(((
acpi_size
)
table_count
+
ACPI_ROOT_TABLE_SIZE_INCREMENT
)
*
sizeof
(
struct
acpi_table_desc
));
if
(
!
tables
)
{
ACPI_ERROR
((
AE_INFO
,
"Could not allocate new root table array"
));
return_ACPI_STATUS
(
AE_NO_MEMORY
);
/*
* Optionally do not load any SSDTs from the RSDT/XSDT. This can
* be useful for debugging ACPI problems on some machines.
*/
if
(
!
reload
&&
acpi_gbl_disable_ssdt_table_install
&&
ACPI_COMPARE_NAME
(
&
new_table_desc
.
signature
,
ACPI_SIG_SSDT
))
{
ACPI_INFO
((
AE_INFO
,
"Ignoring installation of %4.4s at %p"
,
new_table_desc
.
signature
.
ascii
,
ACPI_CAST_PTR
(
void
,
address
)));
goto
release_and_exit
;
}
/* Copy and free the previous table array */
if
(
acpi_gbl_root_table_list
.
tables
)
{
ACPI_MEMCPY
(
tables
,
acpi_gbl_root_table_list
.
tables
,
(
acpi_size
)
table_count
*
sizeof
(
struct
acpi_table_desc
));
/* Validate and verify a table before installation */
if
(
acpi_gbl_root_table_list
.
flags
&
ACPI_ROOT_ORIGIN_ALLOCATED
)
{
ACPI_FREE
(
acpi_gbl_root_table_list
.
tables
);
}
status
=
acpi_tb_verify_table
(
&
new_table_desc
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
goto
release_and_exit
;
}
acpi_gbl_root_table_list
.
tables
=
tables
;
acpi_gbl_root_table_list
.
max_table_count
=
table_count
+
ACPI_ROOT_TABLE_SIZE_INCREMENT
;
acpi_gbl_root_table_list
.
flags
|=
ACPI_ROOT_ORIGIN_ALLOCATED
;
return_ACPI_STATUS
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_store_table
*
* PARAMETERS: address - Table address
* table - Table header
* length - Table length
* flags - flags
*
* RETURN: Status and table index.
*
* DESCRIPTION: Add an ACPI table to the global table list
*
******************************************************************************/
if
(
reload
)
{
/*
* Validate the incoming table signature.
*
* 1) Originally, we checked the table signature for "SSDT" or "PSDT".
* 2) We added support for OEMx tables, signature "OEM".
* 3) Valid tables were encountered with a null signature, so we just
* gave up on validating the signature, (05/2008).
* 4) We encountered non-AML tables such as the MADT, which caused
* interpreter errors and kernel faults. So now, we once again allow
* only "SSDT", "OEMx", and now, also a null signature. (05/2011).
*/
if
((
new_table_desc
.
signature
.
ascii
[
0
]
!=
0x00
)
&&
(
!
ACPI_COMPARE_NAME
(
&
new_table_desc
.
signature
,
ACPI_SIG_SSDT
))
&&
(
ACPI_STRNCMP
(
new_table_desc
.
signature
.
ascii
,
"OEM"
,
3
)))
{
ACPI_BIOS_ERROR
((
AE_INFO
,
"Table has invalid signature [%4.4s] (0x%8.8X), "
"must be SSDT or OEMx"
,
acpi_ut_valid_acpi_name
(
new_table_desc
.
signature
.
ascii
)
?
new_table_desc
.
signature
.
ascii
:
"????"
,
new_table_desc
.
signature
.
integer
));
status
=
AE_BAD_SIGNATURE
;
goto
release_and_exit
;
}
acpi_status
acpi_tb_store_table
(
acpi_physical_address
address
,
struct
acpi_table_header
*
table
,
u32
length
,
u8
flags
,
u32
*
table_index
)
{
acpi_status
status
;
struct
acpi_table_desc
*
new_table
;
/* Check if table is already registered */
/* Ensure that there is room for the table in the Root Table List */
for
(
i
=
0
;
i
<
acpi_gbl_root_table_list
.
current_table_count
;
++
i
)
{
/*
* Check for a table match on the entire table length,
* not just the header.
*/
if
(
!
acpi_tb_compare_tables
(
&
new_table_desc
,
i
))
{
continue
;
}
if
(
acpi_gbl_root_table_list
.
current_table_count
>=
acpi_gbl_root_table_list
.
max_table_count
)
{
status
=
acpi_tb_resize_root_table_list
();
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
/*
* Note: the current mechanism does not unregister a table if it is
* dynamically unloaded. The related namespace entries are deleted,
* but the table remains in the root table list.
*
* The assumption here is that the number of different tables that
* will be loaded is actually small, and there is minimal overhead
* in just keeping the table in case it is needed again.
*
* If this assumption changes in the future (perhaps on large
* machines with many table load/unload operations), tables will
* need to be unregistered when they are unloaded, and slots in the
* root table list should be reused when empty.
*/
if
(
acpi_gbl_root_table_list
.
tables
[
i
].
flags
&
ACPI_TABLE_IS_LOADED
)
{
/* Table is still loaded, this is an error */
status
=
AE_ALREADY_EXISTS
;
goto
release_and_exit
;
}
else
{
/*
* Table was unloaded, allow it to be reloaded.
* As we are going to return AE_OK to the caller, we should
* take the responsibility of freeing the input descriptor.
* Refill the input descriptor to ensure
* acpi_tb_install_table_with_override() can be called again to
* indicate the re-installation.
*/
acpi_tb_uninstall_table
(
&
new_table_desc
);
*
table_index
=
i
;
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
AE_OK
);
}
}
}
new_table
=
&
acpi_gbl_root_table_list
.
tables
[
acpi_gbl_root_table_list
.
current_table_count
];
/* Initialize added table */
new_table
->
address
=
address
;
new_table
->
pointer
=
table
;
new_table
->
length
=
length
;
new_table
->
owner_id
=
0
;
new_table
->
flags
=
flags
;
ACPI_MOVE_32_TO_32
(
&
new_table
->
signature
,
table
->
signature
);
*
table_index
=
acpi_gbl_root_table_list
.
current_table_count
;
acpi_gbl_root_table_list
.
current_table_count
++
;
return
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_delete_table
*
* PARAMETERS: table_index - Table index
*
* RETURN: None
*
* DESCRIPTION: Delete one internal ACPI table
*
******************************************************************************/
/* Add the table to the global root table list */
void
acpi_tb_delete_table
(
struct
acpi_table_desc
*
table_desc
)
{
/* Table must be mapped or allocated */
if
(
!
table_desc
->
pointer
)
{
return
;
status
=
acpi_tb_get_next_root_index
(
&
i
);
if
(
ACPI_FAILURE
(
status
))
{
goto
release_and_exit
;
}
switch
(
table_desc
->
flags
&
ACPI_TABLE_ORIGIN_MASK
)
{
case
ACPI_TABLE_ORIGIN_MAPPED
:
acpi_os_unmap_memory
(
table_desc
->
pointer
,
table_desc
->
length
);
break
;
case
ACPI_TABLE_ORIGIN_ALLOCATED
:
ACPI_FREE
(
table_desc
->
pointer
)
;
break
;
*
table_index
=
i
;
acpi_tb_install_table_with_override
(
i
,
&
new_table_desc
,
override
)
;
/* Not mapped or allocated, there is nothing we can do */
release_and_exit:
default:
/* Release the temporary table descriptor */
return
;
}
table_desc
->
pointer
=
NULL
;
acpi_tb_release_temp_table
(
&
new_table_desc
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_
terminat
e
* FUNCTION: acpi_tb_
override_tabl
e
*
* PARAMETERS: None
* PARAMETERS: old_table_desc - Validated table descriptor to be
* overridden
*
* RETURN: None
*
* DESCRIPTION: Delete all internal ACPI tables
* DESCRIPTION: Attempt table override by calling the OSL override functions.
* Note: If the table is overridden, then the entire new table
* is acquired and returned by this function.
* Before/after invocation, the table descriptor is in a state
* that is "VALIDATED".
*
******************************************************************************/
void
acpi_tb_
terminate
(
void
)
void
acpi_tb_
override_table
(
struct
acpi_table_desc
*
old_table_desc
)
{
u32
i
;
ACPI_FUNCTION_TRACE
(
tb_terminate
);
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
/* Delete the individual tables */
acpi_status
status
;
char
*
override_type
;
struct
acpi_table_desc
new_table_desc
;
struct
acpi_table_header
*
table
;
acpi_physical_address
address
;
u32
length
;
for
(
i
=
0
;
i
<
acpi_gbl_root_table_list
.
current_table_count
;
i
++
)
{
acpi_tb_delete_table
(
&
acpi_gbl_root_table_list
.
tables
[
i
]);
}
/* (1) Attempt logical override (returns a logical address) */
/*
* Delete the root table array if allocated locally. Array cannot be
* mapped, so we don't need to check for that flag.
*/
if
(
acpi_gbl_root_table_list
.
flags
&
ACPI_ROOT_ORIGIN_ALLOCATED
)
{
ACPI_FREE
(
acpi_gbl_root_table_list
.
tables
);
status
=
acpi_os_table_override
(
old_table_desc
->
pointer
,
&
table
);
if
(
ACPI_SUCCESS
(
status
)
&&
table
)
{
acpi_tb_acquire_temp_table
(
&
new_table_desc
,
ACPI_PTR_TO_PHYSADDR
(
table
),
ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL
);
override_type
=
"Logical"
;
goto
finish_override
;
}
acpi_gbl_root_table_list
.
tables
=
NULL
;
acpi_gbl_root_table_list
.
flags
=
0
;
acpi_gbl_root_table_list
.
current_table_count
=
0
;
/* (2) Attempt physical override (returns a physical address) */
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"ACPI Tables freed
\n
"
));
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
status
=
acpi_os_physical_table_override
(
old_table_desc
->
pointer
,
&
address
,
&
length
);
if
(
ACPI_SUCCESS
(
status
)
&&
address
&&
length
)
{
acpi_tb_acquire_temp_table
(
&
new_table_desc
,
address
,
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL
);
override_type
=
"Physical"
;
goto
finish_override
;
}
return_VOID
;
}
return
;
/* There was no override */
/*******************************************************************************
*
* FUNCTION: acpi_tb_delete_namespace_by_owner
*
* PARAMETERS: table_index - Table index
*
* RETURN: Status
*
* DESCRIPTION: Delete all namespace objects created when this table was loaded.
*
******************************************************************************/
acpi_status
acpi_tb_delete_namespace_by_owner
(
u32
table_index
)
{
acpi_owner_id
owner_id
;
acpi_status
status
;
finish_override:
ACPI_FUNCTION_TRACE
(
tb_delete_namespace_by_owner
);
/* Validate and verify a table before overriding */
status
=
acpi_
ut_acquire_mutex
(
ACPI_MTX_TABLES
);
status
=
acpi_
tb_verify_table
(
&
new_table_desc
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
return
_ACPI_STATUS
(
status
)
;
return
;
}
if
(
table_index
>=
acpi_gbl_root_table_list
.
current_table_count
)
{
/* The table index does not exist */
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
AE_NOT_EXIST
);
}
ACPI_INFO
((
AE_INFO
,
"%4.4s "
ACPI_PRINTF_UINT
" %s table override, new table: "
ACPI_PRINTF_UINT
,
old_table_desc
->
signature
.
ascii
,
ACPI_FORMAT_TO_UINT
(
old_table_desc
->
address
),
override_type
,
ACPI_FORMAT_TO_UINT
(
new_table_desc
.
address
)));
/*
Get the owner ID for this table, used to delete namespace nodes
*/
/*
We can now uninstall the original table
*/
owner_id
=
acpi_gbl_root_table_list
.
tables
[
table_index
].
owner_id
;
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
acpi_tb_uninstall_table
(
old_table_desc
);
/*
* Need to acquire the namespace writer lock to prevent interference
* with any concurrent namespace walks. The interpreter must be
* released during the deletion since the acquisition of the deletion
* lock may block, and also since the execution of a namespace walk
* must be allowed to use the interpreter.
* Replace the original table descriptor and keep its state as
* "VALIDATED".
*/
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_INTERPRETER
);
status
=
acpi_ut_acquire_write_lock
(
&
acpi_gbl_namespace_rw_lock
);
acpi_tb_init_table_descriptor
(
old_table_desc
,
new_table_desc
.
address
,
new_table_desc
.
flags
,
new_table_desc
.
pointer
);
acpi_tb_validate_table
(
old_table_desc
);
acpi_ns_delete_namespace_by_owner
(
owner_id
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
/* Release the temporary table descriptor */
acpi_ut_release_write_lock
(
&
acpi_gbl_namespace_rw_lock
);
status
=
acpi_ut_acquire_mutex
(
ACPI_MTX_INTERPRETER
);
return_ACPI_STATUS
(
status
);
acpi_tb_release_temp_table
(
&
new_table_desc
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_
allocate_owner_id
* FUNCTION: acpi_tb_
store_table
*
* PARAMETERS: table_index - Table index
* PARAMETERS: address - Table address
* table - Table header
* length - Table length
* flags - Install flags
* table_index - Where the table index is returned
*
* RETURN: Status
* RETURN: Status
and table index.
*
* DESCRIPTION: A
llocates owner_id in table_desc
* DESCRIPTION: A
dd an ACPI table to the global table list
*
******************************************************************************/
acpi_status
acpi_tb_allocate_owner_id
(
u32
table_index
)
acpi_status
acpi_tb_store_table
(
acpi_physical_address
address
,
struct
acpi_table_header
*
table
,
u32
length
,
u8
flags
,
u32
*
table_index
)
{
acpi_status
status
=
AE_BAD_PARAMETER
;
ACPI_FUNCTION_TRACE
(
tb_allocate_owner_id
);
acpi_status
status
;
struct
acpi_table_desc
*
table_desc
;
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
status
=
acpi_ut_allocate_owner_id
(
&
(
acpi_gbl_root_table_list
.
tables
[
table_index
].
owner_id
));
status
=
acpi_tb_get_next_root_index
(
table_index
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_release_owner_id
*
* PARAMETERS: table_index - Table index
*
* RETURN: Status
*
* DESCRIPTION: Releases owner_id in table_desc
*
******************************************************************************/
acpi_status
acpi_tb_release_owner_id
(
u32
table_index
)
{
acpi_status
status
=
AE_BAD_PARAMETER
;
ACPI_FUNCTION_TRACE
(
tb_release_owner_id
);
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
acpi_ut_release_owner_id
(
&
(
acpi_gbl_root_table_list
.
tables
[
table_index
].
owner_id
));
status
=
AE_OK
;
}
/* Initialize added table */
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
status
);
table_desc
=
&
acpi_gbl_root_table_list
.
tables
[
*
table_index
];
acpi_tb_init_table_descriptor
(
table_desc
,
address
,
flags
,
table
);
table_desc
->
pointer
=
table
;
return
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_
get_owner_id
* FUNCTION: acpi_tb_
uninstall_table
*
* PARAMETERS: table_index - Table index
* owner_id - Where the table owner_id is returned
* PARAMETERS: table_desc - Table descriptor
*
* RETURN:
Status
* RETURN:
None
*
* DESCRIPTION:
returns owner_id for the
ACPI table
* DESCRIPTION:
Delete one internal
ACPI table
*
******************************************************************************/
acpi_status
acpi_tb_get_owner_id
(
u32
table_index
,
acpi_owner_id
*
owner_id
)
void
acpi_tb_uninstall_table
(
struct
acpi_table_desc
*
table_desc
)
{
acpi_status
status
=
AE_BAD_PARAMETER
;
ACPI_FUNCTION_TRACE
(
tb_get_owner_id
);
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
*
owner_id
=
acpi_gbl_root_table_list
.
tables
[
table_index
].
owner_id
;
status
=
AE_OK
;
}
ACPI_FUNCTION_TRACE
(
tb_uninstall_table
);
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_is_table_loaded
*
* PARAMETERS: table_index - Table index
*
* RETURN: Table Loaded Flag
*
******************************************************************************/
/* Table must be installed */
u8
acpi_tb_is_table_loaded
(
u32
table_index
)
{
u8
is_loaded
=
FALSE
;
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
is_loaded
=
(
u8
)
(
acpi_gbl_root_table_list
.
tables
[
table_index
].
flags
&
ACPI_TABLE_IS_LOADED
);
if
(
!
table_desc
->
address
)
{
return_VOID
;
}
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return
(
is_loaded
);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_set_table_loaded_flag
*
* PARAMETERS: table_index - Table index
* is_loaded - TRUE if table is loaded, FALSE otherwise
*
* RETURN: None
*
* DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
*
******************************************************************************/
void
acpi_tb_set_table_loaded_flag
(
u32
table_index
,
u8
is_loaded
)
{
acpi_tb_invalidate_table
(
table_desc
);
(
void
)
acpi_ut_acquire_mutex
(
ACPI_MTX_TABLES
);
if
(
table_index
<
acpi_gbl_root_table_list
.
current_table_count
)
{
if
(
is_loaded
)
{
acpi_gbl_root_table_list
.
tables
[
table_index
].
flags
|=
ACPI_TABLE_IS_LOADED
;
}
else
{
acpi_gbl_root_table_list
.
tables
[
table_index
].
flags
&=
~
ACPI_TABLE_IS_LOADED
;
}
if
((
table_desc
->
flags
&
ACPI_TABLE_ORIGIN_MASK
)
==
ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL
)
{
ACPI_FREE
(
ACPI_CAST_PTR
(
void
,
table_desc
->
address
));
}
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
table_desc
->
address
=
ACPI_PTR_TO_PHYSADDR
(
NULL
);
return_VOID
;
}
drivers/acpi/acpica/tbutils.c
View file @
23a75c52
...
...
@@ -178,9 +178,13 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
}
ACPI_MEMCPY
(
new_table
,
table_desc
->
pointer
,
table_desc
->
length
);
acpi_tb_delete_table
(
table_desc
);
table_desc
->
pointer
=
new_table
;
table_desc
->
flags
=
ACPI_TABLE_ORIGIN_ALLOCATED
;
acpi_tb_uninstall_table
(
table_desc
);
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
,
"Forced DSDT copy: length 0x%05X copied locally, original unmapped"
,
...
...
@@ -189,116 +193,6 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
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
...
...
@@ -465,6 +359,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
u32
length
;
u8
*
table_entry
;
acpi_status
status
;
u32
table_index
;
ACPI_FUNCTION_TRACE
(
tb_parse_root_table
);
...
...
@@ -576,31 +471,24 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
/* Initialize the root table array from the RSDT/XSDT */
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) */
acpi_gbl_root_table_list
.
tables
[
acpi_gbl_root_table_list
.
current_table_count
].
address
=
acpi_tb_get_root_table_entry
(
table_entry
,
table_entry_size
);
status
=
acpi_tb_install_standard_table
(
acpi_tb_get_root_table_entry
(
table_entry
,
table_entry_size
),
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
);
}
table_entry
+=
table_entry_size
;
acpi_gbl_root_table_list
.
current_table_count
++
;
}
/*
...
...
@@ -609,22 +497,5 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
*/
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
);
}
drivers/acpi/acpica/tbxface.c
View file @
23a75c52
...
...
@@ -206,8 +206,8 @@ acpi_status
acpi_get_table_header
(
char
*
signature
,
u32
instance
,
struct
acpi_table_header
*
out_table_header
)
{
u32
i
;
u32
j
;
u32
i
;
u32
j
;
struct
acpi_table_header
*
header
;
/* Parameter validation */
...
...
@@ -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
].
flags
&
ACPI_TABLE_ORIGIN_MASK
)
==
ACPI_TABLE_ORIGIN_
MAPPED
)
{
ACPI_TABLE_ORIGIN_
INTERNAL_PHYSICAL
)
{
header
=
acpi_os_map_memory
(
acpi_gbl_root_table_list
.
tables
[
i
].
address
,
...
...
@@ -321,8 +321,8 @@ acpi_get_table_with_size(char *signature,
u32
instance
,
struct
acpi_table_header
**
out_table
,
acpi_size
*
tbl_size
)
{
u32
i
;
u32
j
;
u32
i
;
u32
j
;
acpi_status
status
;
/* Parameter validation */
...
...
@@ -346,7 +346,7 @@ acpi_get_table_with_size(char *signature,
}
status
=
acpi_tb_v
erify
_table
(
&
acpi_gbl_root_table_list
.
tables
[
i
]);
acpi_tb_v
alidate
_table
(
&
acpi_gbl_root_table_list
.
tables
[
i
]);
if
(
ACPI_SUCCESS
(
status
))
{
*
out_table
=
acpi_gbl_root_table_list
.
tables
[
i
].
pointer
;
*
tbl_size
=
acpi_gbl_root_table_list
.
tables
[
i
].
length
;
...
...
@@ -390,7 +390,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table)
*
******************************************************************************/
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
;
...
...
@@ -416,8 +416,8 @@ acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table)
/* Table is not mapped, map it */
status
=
acpi_tb_v
erify
_table
(
&
acpi_gbl_root_table_list
.
tables
[
table_index
]);
acpi_tb_v
alidate
_table
(
&
acpi_gbl_root_table_list
.
tables
[
table_index
]);
if
(
ACPI_FAILURE
(
status
))
{
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
return_ACPI_STATUS
(
status
);
...
...
drivers/acpi/acpica/tbxfload.c
View file @
23a75c52
...
...
@@ -117,7 +117,7 @@ static acpi_status acpi_tb_load_namespace(void)
tables
[
ACPI_TABLE_INDEX_DSDT
].
signature
),
ACPI_SIG_DSDT
)
||
ACPI_FAILURE
(
acpi_tb_v
erify
_table
ACPI_FAILURE
(
acpi_tb_v
alidate
_table
(
&
acpi_gbl_root_table_list
.
tables
[
ACPI_TABLE_INDEX_DSDT
])))
{
status
=
AE_NO_ACPI_TABLES
;
...
...
@@ -128,7 +128,7 @@ static acpi_status acpi_tb_load_namespace(void)
* Save the DSDT pointer for simple access. This is the mapped memory
* address. We must take care here because the address of the .Tables
* array can change dynamically as tables are loaded at run-time. Note:
* .Pointer field is not validated until after call to acpi_tb_v
erify
_table.
* .Pointer field is not validated until after call to acpi_tb_v
alidate
_table.
*/
acpi_gbl_DSDT
=
acpi_gbl_root_table_list
.
tables
[
ACPI_TABLE_INDEX_DSDT
].
pointer
;
...
...
@@ -174,24 +174,11 @@ static acpi_status acpi_tb_load_namespace(void)
(
acpi_gbl_root_table_list
.
tables
[
i
].
signature
),
ACPI_SIG_PSDT
))
||
ACPI_FAILURE
(
acpi_tb_v
erify
_table
ACPI_FAILURE
(
acpi_tb_v
alidate
_table
(
&
acpi_gbl_root_table_list
.
tables
[
i
])))
{
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 */
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_TABLES
);
...
...
@@ -206,6 +193,45 @@ static acpi_status acpi_tb_load_namespace(void)
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
...
...
@@ -222,11 +248,9 @@ static acpi_status acpi_tb_load_namespace(void)
* to ensure that the table is not deleted or unmapped.
*
******************************************************************************/
acpi_status
acpi_load_table
(
struct
acpi_table_header
*
table
)
{
acpi_status
status
;
struct
acpi_table_desc
table_desc
;
u32
table_index
;
ACPI_FUNCTION_TRACE
(
acpi_load_table
);
...
...
@@ -237,14 +261,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table)
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 */
status
=
acpi_ut_acquire_mutex
(
ACPI_MTX_INTERPRETER
);
...
...
@@ -255,7 +271,24 @@ acpi_status acpi_load_table(struct acpi_table_header *table)
/* Install the table and load it into the namespace */
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
))
{
goto
unlock_and_exit
;
}
...
...
drivers/acpi/acpica/utdecode.c
View file @
23a75c52
...
...
@@ -462,7 +462,7 @@ char *acpi_ut_get_mutex_name(u32 mutex_id)
/* 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"
,
/* 01 */
"Device Check"
,
/* 02 */
"Device Wake"
,
...
...
@@ -473,23 +473,75 @@ static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = {
/* 07 */
"Power Fault"
,
/* 08 */
"Capabilities Check"
,
/* 09 */
"Device PLD Check"
,
/*
10
*/
"Reserved"
,
/*
11
*/
"System Locality Update"
,
/*
12
*/
"Shutdown Request"
/*
0A
*/
"Reserved"
,
/*
0B
*/
"System Locality Update"
,
/*
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
)
{
return
(
acpi_gbl_notify_value_names
[
notify_value
]);
}
else
if
(
notify_value
<=
ACPI_MAX_SYS_NOTIFY
)
{
return
(
acpi_gbl_generic_notify
[
notify_value
]);
}
/* 0D - 7F are reserved */
if
(
notify_value
<=
ACPI_MAX_SYS_NOTIFY
)
{
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
...
...
drivers/acpi/acpica/utstring.c
View file @
23a75c52
...
...
@@ -353,7 +353,7 @@ void acpi_ut_print_string(char *string, u16 max_length)
}
acpi_os_printf
(
"
\"
"
);
for
(
i
=
0
;
string
[
i
]
&&
(
i
<
max_length
)
;
i
++
)
{
for
(
i
=
0
;
(
i
<
max_length
)
&&
string
[
i
]
;
i
++
)
{
/* Escape sequences */
...
...
drivers/acpi/osl.c
View file @
23a75c52
...
...
@@ -1770,16 +1770,15 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
}
#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
1
;
return
0
;
}
__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
)
{
...
...
include/acpi/acpixf.h
View file @
23a75c52
...
...
@@ -46,7 +46,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20140
214
#define ACPI_CA_VERSION 0x20140
325
#include <acpi/acconfig.h>
#include <acpi/actypes.h>
...
...
@@ -75,7 +75,7 @@ extern u8 acpi_gbl_auto_serialize_methods;
extern
u8
acpi_gbl_copy_dsdt_locally
;
extern
u8
acpi_gbl_create_osi_method
;
extern
u8
acpi_gbl_disable_auto_repair
;
extern
u8
acpi_gbl_disable_ssdt_table_
load
;
extern
u8
acpi_gbl_disable_ssdt_table_
install
;
extern
u8
acpi_gbl_do_not_use_xsdt
;
extern
u8
acpi_gbl_enable_aml_debug_object
;
extern
u8
acpi_gbl_enable_interpreter_slack
;
...
...
@@ -164,6 +164,9 @@ acpi_decode_pld_buffer(u8 *in_buffer,
/*
* ACPI table load/unload interfaces
*/
acpi_status
__init
acpi_install_table
(
acpi_physical_address
address
,
u8
physical
);
acpi_status
acpi_load_table
(
struct
acpi_table_header
*
table
);
acpi_status
acpi_unload_parent_table
(
acpi_handle
object
);
...
...
include/acpi/actbl.h
View file @
23a75c52
...
...
@@ -367,12 +367,11 @@ struct acpi_table_desc {
/* Masks for Flags field above */
#define ACPI_TABLE_ORIGIN_UNKNOWN (0)
#define ACPI_TABLE_ORIGIN_MAPPED (1)
#define ACPI_TABLE_ORIGIN_ALLOCATED (2)
#define ACPI_TABLE_ORIGIN_OVERRIDE (4)
#define ACPI_TABLE_ORIGIN_MASK (7)
#define ACPI_TABLE_IS_LOADED (8)
#define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0)
/* Virtual address, external maintained */
#define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL (1)
/* Physical address, internally mapped */
#define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL (2)
/* Virtual address, internallly allocated */
#define ACPI_TABLE_ORIGIN_MASK (3)
#define ACPI_TABLE_IS_LOADED (8)
/*
* Get the remaining ACPI tables
...
...
include/acpi/platform/acgcc.h
View file @
23a75c52
...
...
@@ -64,4 +64,15 @@
*/
#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__ */
include/acpi/platform/aclinux.h
View file @
23a75c52
...
...
@@ -91,7 +91,7 @@
#include <ctype.h>
#include <unistd.h>
/* D
isable kernel
specific declarators */
/* D
efine/disable kernel-
specific declarators */
#ifndef __init
#define __init
...
...
@@ -106,7 +106,8 @@
#define ACPI_FLUSH_CPU_CACHE()
#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 COMPILER_DEPENDENT_INT64 long
#define COMPILER_DEPENDENT_UINT64 unsigned long
...
...
tools/power/acpi/Makefile
View file @
23a75c52
...
...
@@ -68,7 +68,8 @@ WARNINGS += $(call cc-supports,-Wstrict-prototypes)
WARNINGS
+=
$(
call
cc-supports,-Wdeclaration-after-statement
)
KERNEL_INCLUDE
:=
../../../include
CFLAGS
+=
-D_LINUX
-DDEFINE_ALTERNATE_TYPES
-I
$(KERNEL_INCLUDE)
ACPICA_INCLUDE
:=
../../../drivers/acpi/acpica
CFLAGS
+=
-D_LINUX
-I
$(KERNEL_INCLUDE)
-I
$(ACPICA_INCLUDE)
CFLAGS
+=
$(WARNINGS)
ifeq
($(strip $(V)),false)
...
...
@@ -92,10 +93,29 @@ endif
# --- ACPIDUMP BEGIN ---
vpath
%.c
\
tools/acpidump
../../../drivers/acpi/acpica\
tools/acpidump\
common\
os_specific/service_layers
CFLAGS
+=
-DACPI_DUMP_APP
-Itools
/acpidump
DUMP_OBJS
=
\
acpidump.o
apdump.o
\
apfiles.o
\
apmain.o
\
osunixdir.o
\
osunixmap.o
\
tbprint.o
\
tbxfroot.o
\
utbuffer.o
\
utexcep.o
\
utmath.o
\
utstring.o
\
utxferror.o
\
oslinuxtbl.o
\
cmfsize.o
\
getopt.o
DUMP_OBJS
:=
$(
addprefix
$(OUTPUT)
tools/acpidump/,
$(DUMP_OBJS)
)
...
...
tools/power/acpi/common/cmfsize.c
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: cfsize - Common get file size function
*
*****************************************************************************/
/*
* 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.
*/
#include <acpi/acpi.h>
#include "accommon.h"
#include "acapps.h"
#include <stdio.h>
#define _COMPONENT ACPI_TOOLS
ACPI_MODULE_NAME
(
"cmfsize"
)
/*******************************************************************************
*
* FUNCTION: cm_get_file_size
*
* PARAMETERS: file - Open file descriptor
*
* RETURN: File Size. On error, -1 (ACPI_UINT32_MAX)
*
* DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open.
* Does not disturb the current file pointer. Uses perror for
* error messages.
*
******************************************************************************/
u32
cm_get_file_size
(
FILE
*
file
)
{
long
file_size
;
long
current_offset
;
/* Save the current file pointer, seek to EOF to obtain file size */
current_offset
=
ftell
(
file
);
if
(
current_offset
<
0
)
{
goto
offset_error
;
}
if
(
fseek
(
file
,
0
,
SEEK_END
))
{
goto
seek_error
;
}
file_size
=
ftell
(
file
);
if
(
file_size
<
0
)
{
goto
offset_error
;
}
/* Restore original file pointer */
if
(
fseek
(
file
,
current_offset
,
SEEK_SET
))
{
goto
seek_error
;
}
return
((
u32
)
file_size
);
offset_error:
perror
(
"Could not get file offset"
);
return
(
ACPI_UINT32_MAX
);
seek_error:
perror
(
"Could not seek file"
);
return
(
ACPI_UINT32_MAX
);
}
tools/power/acpi/common/getopt.c
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: getopt
*
*****************************************************************************/
/*
* 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.
*/
/*
* ACPICA getopt() implementation
*
* Option strings:
* "f" - Option has no arguments
* "f:" - Option requires an argument
* "f^" - Option has optional single-char sub-options
* "f|" - Option has required single-char sub-options
*/
#include <stdio.h>
#include <string.h>
#include <acpi/acpi.h>
#include "accommon.h"
#include "acapps.h"
#define ACPI_OPTION_ERROR(msg, badchar) \
if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
int
acpi_gbl_opterr
=
1
;
int
acpi_gbl_optind
=
1
;
int
acpi_gbl_sub_opt_char
=
0
;
char
*
acpi_gbl_optarg
;
static
int
current_char_ptr
=
1
;
/*******************************************************************************
*
* FUNCTION: acpi_getopt_argument
*
* PARAMETERS: argc, argv - from main
*
* RETURN: 0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg
* to point to the next argument.
*
* DESCRIPTION: Get the next argument. Used to obtain arguments for the
* two-character options after the original call to acpi_getopt.
* Note: Either the argument starts at the next character after
* the option, or it is pointed to by the next argv entry.
* (After call to acpi_getopt, we need to backup to the previous
* argv entry).
*
******************************************************************************/
int
acpi_getopt_argument
(
int
argc
,
char
**
argv
)
{
acpi_gbl_optind
--
;
current_char_ptr
++
;
if
(
argv
[
acpi_gbl_optind
][(
int
)(
current_char_ptr
+
1
)]
!=
'\0'
)
{
acpi_gbl_optarg
=
&
argv
[
acpi_gbl_optind
++
][(
int
)(
current_char_ptr
+
1
)];
}
else
if
(
++
acpi_gbl_optind
>=
argc
)
{
ACPI_OPTION_ERROR
(
"Option requires an argument: -"
,
'v'
);
current_char_ptr
=
1
;
return
(
-
1
);
}
else
{
acpi_gbl_optarg
=
argv
[
acpi_gbl_optind
++
];
}
current_char_ptr
=
1
;
return
(
0
);
}
/*******************************************************************************
*
* FUNCTION: acpi_getopt
*
* PARAMETERS: argc, argv - from main
* opts - options info list
*
* RETURN: Option character or EOF
*
* DESCRIPTION: Get the next option
*
******************************************************************************/
int
acpi_getopt
(
int
argc
,
char
**
argv
,
char
*
opts
)
{
int
current_char
;
char
*
opts_ptr
;
if
(
current_char_ptr
==
1
)
{
if
(
acpi_gbl_optind
>=
argc
||
argv
[
acpi_gbl_optind
][
0
]
!=
'-'
||
argv
[
acpi_gbl_optind
][
1
]
==
'\0'
)
{
return
(
EOF
);
}
else
if
(
strcmp
(
argv
[
acpi_gbl_optind
],
"--"
)
==
0
)
{
acpi_gbl_optind
++
;
return
(
EOF
);
}
}
/* Get the option */
current_char
=
argv
[
acpi_gbl_optind
][
current_char_ptr
];
/* Make sure that the option is legal */
if
(
current_char
==
':'
||
(
opts_ptr
=
strchr
(
opts
,
current_char
))
==
NULL
)
{
ACPI_OPTION_ERROR
(
"Illegal option: -"
,
current_char
);
if
(
argv
[
acpi_gbl_optind
][
++
current_char_ptr
]
==
'\0'
)
{
acpi_gbl_optind
++
;
current_char_ptr
=
1
;
}
return
(
'?'
);
}
/* Option requires an argument? */
if
(
*++
opts_ptr
==
':'
)
{
if
(
argv
[
acpi_gbl_optind
][(
int
)(
current_char_ptr
+
1
)]
!=
'\0'
)
{
acpi_gbl_optarg
=
&
argv
[
acpi_gbl_optind
++
][(
int
)
(
current_char_ptr
+
1
)];
}
else
if
(
++
acpi_gbl_optind
>=
argc
)
{
ACPI_OPTION_ERROR
(
"Option requires an argument: -"
,
current_char
);
current_char_ptr
=
1
;
return
(
'?'
);
}
else
{
acpi_gbl_optarg
=
argv
[
acpi_gbl_optind
++
];
}
current_char_ptr
=
1
;
}
/* Option has an optional argument? */
else
if
(
*
opts_ptr
==
'+'
)
{
if
(
argv
[
acpi_gbl_optind
][(
int
)(
current_char_ptr
+
1
)]
!=
'\0'
)
{
acpi_gbl_optarg
=
&
argv
[
acpi_gbl_optind
++
][(
int
)
(
current_char_ptr
+
1
)];
}
else
if
(
++
acpi_gbl_optind
>=
argc
)
{
acpi_gbl_optarg
=
NULL
;
}
else
{
acpi_gbl_optarg
=
argv
[
acpi_gbl_optind
++
];
}
current_char_ptr
=
1
;
}
/* Option has optional single-char arguments? */
else
if
(
*
opts_ptr
==
'^'
)
{
if
(
argv
[
acpi_gbl_optind
][(
int
)(
current_char_ptr
+
1
)]
!=
'\0'
)
{
acpi_gbl_optarg
=
&
argv
[
acpi_gbl_optind
][(
int
)(
current_char_ptr
+
1
)];
}
else
{
acpi_gbl_optarg
=
"^"
;
}
acpi_gbl_sub_opt_char
=
acpi_gbl_optarg
[
0
];
acpi_gbl_optind
++
;
current_char_ptr
=
1
;
}
/* Option has a required single-char argument? */
else
if
(
*
opts_ptr
==
'|'
)
{
if
(
argv
[
acpi_gbl_optind
][(
int
)(
current_char_ptr
+
1
)]
!=
'\0'
)
{
acpi_gbl_optarg
=
&
argv
[
acpi_gbl_optind
][(
int
)(
current_char_ptr
+
1
)];
}
else
{
ACPI_OPTION_ERROR
(
"Option requires a single-character suboption: -"
,
current_char
);
current_char_ptr
=
1
;
return
(
'?'
);
}
acpi_gbl_sub_opt_char
=
acpi_gbl_optarg
[
0
];
acpi_gbl_optind
++
;
current_char_ptr
=
1
;
}
/* Option with no arguments */
else
{
if
(
argv
[
acpi_gbl_optind
][
++
current_char_ptr
]
==
'\0'
)
{
current_char_ptr
=
1
;
acpi_gbl_optind
++
;
}
acpi_gbl_optarg
=
NULL
;
}
return
(
current_char
);
}
tools/power/acpi/man/acpidump.8
View file @
23a75c52
.TH ACPIDUMP 8
.SH NAME
acpidump \- Dump system's ACPI tables to an ASCII file.
acpidump \- dump a system's ACPI tables to an ASCII file
.SH SYNOPSIS
.ft B
.B acpidump > acpidump.out
.B acpidump
.RI [ options ]
.br
.SH DESCRIPTION
\fBacpidump \fP dumps the systems ACPI tables to an ASCII file
appropriate for attaching to a bug report.
.B acpidump
dumps the systems ACPI tables to an ASCII file appropriate for
attaching to a bug report.
Subsequently, they can be processed by utilities in the ACPICA package.
.SS Options
no options worth worrying about.
.PP
.SH EXAMPLE
.SH OPTIONS
acpidump options are as follow:
.TP
.B Options
.TP
.B \-b
Dump tables to binary files
.TP
.B \-c
Dump customized tables
.TP
.B \-h \-?
This help message
.TP
.B \-o <File>
Redirect output to file
.TP
.B \-r <Address>
Dump tables from specified RSDP
.TP
.B \-s
Print table summaries only
.TP
.B \-v
Display version information
.TP
.B \-z
Verbose mode
.TP
.B Table Options
.TP
.B \-a <Address>
Get table via a physical address
.TP
.B \-f <BinaryFile>
Get table via a binary file
.TP
.B \-n <Signature>
Get table via a name/signature
.TP
Invocation without parameters dumps all available tables
.TP
Multiple mixed instances of -a, -f, and -n are supported
.SH EXAMPLES
.nf
# acpidump > acpidump.out
...
...
@@ -50,10 +96,25 @@ ACPICA: https://acpica.org/
.ta
.nf
/dev/mem
/sys/firmware/acpi/tables/*
/sys/firmware/acpi/tables/dynamic/*
/sys/firmware/efi/systab
.fi
.PP
.SH AUTHOR
.nf
Written by Len Brown <len.brown@intel.com>
.TP
Original by:
Len Brown <len.brown@intel.com>
.TP
Written by:
Chao Guan <chao.guan@intel.com>
.TP
Updated by:
Bob Moore <robert.moore@intel.com>
Lv Zheng <lv.zheng@intel.com>
.SH SEE ALSO
\&\fIacpixtract\fR\|(8), \fIiasl\fR\|(8).
.SH COPYRIGHT
COPYRIGHT (c) 2013, Intel Corporation.
tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: oslinuxtbl - Linux OSL for obtaining ACPI tables
*
*****************************************************************************/
/*
* 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.
*/
#include "acpidump.h"
#define _COMPONENT ACPI_OS_SERVICES
ACPI_MODULE_NAME
(
"oslinuxtbl"
)
#ifndef PATH_MAX
#define PATH_MAX 256
#endif
/* List of information about obtained ACPI tables */
typedef
struct
osl_table_info
{
struct
osl_table_info
*
next
;
u32
instance
;
char
signature
[
ACPI_NAME_SIZE
];
}
osl_table_info
;
/* Local prototypes */
static
acpi_status
osl_table_initialize
(
void
);
static
acpi_status
osl_table_name_from_file
(
char
*
filename
,
char
*
signature
,
u32
*
instance
);
static
acpi_status
osl_add_table_to_list
(
char
*
signature
,
u32
instance
);
static
acpi_status
osl_read_table_from_file
(
char
*
filename
,
acpi_size
file_offset
,
char
*
signature
,
struct
acpi_table_header
**
table
);
static
acpi_status
osl_map_table
(
acpi_size
address
,
char
*
signature
,
struct
acpi_table_header
**
table
);
static
void
osl_unmap_table
(
struct
acpi_table_header
*
table
);
static
acpi_physical_address
osl_find_rsdp_via_efi
(
void
);
static
acpi_status
osl_load_rsdp
(
void
);
static
acpi_status
osl_list_customized_tables
(
char
*
directory
);
static
acpi_status
osl_get_customized_table
(
char
*
pathname
,
char
*
signature
,
u32
instance
,
struct
acpi_table_header
**
table
,
acpi_physical_address
*
address
);
static
acpi_status
osl_list_bios_tables
(
void
);
static
acpi_status
osl_get_bios_table
(
char
*
signature
,
u32
instance
,
struct
acpi_table_header
**
table
,
acpi_physical_address
*
address
);
static
acpi_status
osl_get_last_status
(
acpi_status
default_status
);
/* File locations */
#define DYNAMIC_TABLE_DIR "/sys/firmware/acpi/tables/dynamic"
#define STATIC_TABLE_DIR "/sys/firmware/acpi/tables"
#define EFI_SYSTAB "/sys/firmware/efi/systab"
/* Should we get dynamically loaded SSDTs from DYNAMIC_TABLE_DIR? */
u8
gbl_dump_dynamic_tables
=
TRUE
;
/* Initialization flags */
u8
gbl_table_list_initialized
=
FALSE
;
/* Local copies of main ACPI tables */
struct
acpi_table_rsdp
gbl_rsdp
;
struct
acpi_table_fadt
*
gbl_fadt
=
NULL
;
struct
acpi_table_rsdt
*
gbl_rsdt
=
NULL
;
struct
acpi_table_xsdt
*
gbl_xsdt
=
NULL
;
/* Table addresses */
acpi_physical_address
gbl_fadt_address
=
0
;
acpi_physical_address
gbl_rsdp_address
=
0
;
/* Revision of RSD PTR */
u8
gbl_revision
=
0
;
struct
osl_table_info
*
gbl_table_list_head
=
NULL
;
u32
gbl_table_count
=
0
;
/******************************************************************************
*
* FUNCTION: osl_get_last_status
*
* PARAMETERS: default_status - Default error status to return
*
* RETURN: Status; Converted from errno.
*
* DESCRIPTION: Get last errno and conver it to acpi_status.
*
*****************************************************************************/
static
acpi_status
osl_get_last_status
(
acpi_status
default_status
)
{
switch
(
errno
)
{
case
EACCES
:
case
EPERM
:
return
(
AE_ACCESS
);
case
ENOENT
:
return
(
AE_NOT_FOUND
);
case
ENOMEM
:
return
(
AE_NO_MEMORY
);
default:
return
(
default_status
);
}
}
/******************************************************************************
*
* FUNCTION: acpi_os_get_table_by_address
*
* PARAMETERS: address - Physical address of the ACPI table
* table - Where a pointer to the table is returned
*
* RETURN: Status; Table buffer is returned if AE_OK.
* AE_NOT_FOUND: A valid table was not found at the address
*
* DESCRIPTION: Get an ACPI table via a physical memory address.
*
*****************************************************************************/
acpi_status
acpi_os_get_table_by_address
(
acpi_physical_address
address
,
struct
acpi_table_header
**
table
)
{
u32
table_length
;
struct
acpi_table_header
*
mapped_table
;
struct
acpi_table_header
*
local_table
=
NULL
;
acpi_status
status
=
AE_OK
;
/* Get main ACPI tables from memory on first invocation of this function */
status
=
osl_table_initialize
();
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
/* Map the table and validate it */
status
=
osl_map_table
(
address
,
NULL
,
&
mapped_table
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
/* Copy table to local buffer and return it */
table_length
=
ap_get_table_length
(
mapped_table
);
if
(
table_length
==
0
)
{
status
=
AE_BAD_HEADER
;
goto
exit
;
}
local_table
=
calloc
(
1
,
table_length
);
if
(
!
local_table
)
{
status
=
AE_NO_MEMORY
;
goto
exit
;
}
ACPI_MEMCPY
(
local_table
,
mapped_table
,
table_length
);
exit:
osl_unmap_table
(
mapped_table
);
*
table
=
local_table
;
return
(
status
);
}
/******************************************************************************
*
* FUNCTION: acpi_os_get_table_by_name
*
* PARAMETERS: signature - ACPI Signature for desired table. Must be
* a null terminated 4-character string.
* instance - Multiple table support for SSDT/UEFI (0...n)
* Must be 0 for other tables.
* table - Where a pointer to the table is returned
* address - Where the table physical address is returned
*
* RETURN: Status; Table buffer and physical address returned if AE_OK.
* AE_LIMIT: Instance is beyond valid limit
* AE_NOT_FOUND: A table with the signature was not found
*
* NOTE: Assumes the input signature is uppercase.
*
*****************************************************************************/
acpi_status
acpi_os_get_table_by_name
(
char
*
signature
,
u32
instance
,
struct
acpi_table_header
**
table
,
acpi_physical_address
*
address
)
{
acpi_status
status
;
/* Get main ACPI tables from memory on first invocation of this function */
status
=
osl_table_initialize
();
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
/* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */
if
(
!
gbl_dump_customized_tables
)
{
/* Attempt to get the table from the memory */
status
=
osl_get_bios_table
(
signature
,
instance
,
table
,
address
);
}
else
{
/* Attempt to get the table from the static directory */
status
=
osl_get_customized_table
(
STATIC_TABLE_DIR
,
signature
,
instance
,
table
,
address
);
}
if
(
ACPI_FAILURE
(
status
)
&&
status
==
AE_LIMIT
)
{
if
(
gbl_dump_dynamic_tables
)
{
/* Attempt to get a dynamic table */
status
=
osl_get_customized_table
(
DYNAMIC_TABLE_DIR
,
signature
,
instance
,
table
,
address
);
}
}
return
(
status
);
}
/******************************************************************************
*
* FUNCTION: osl_add_table_to_list
*
* PARAMETERS: signature - Table signature
* instance - Table instance
*
* RETURN: Status; Successfully added if AE_OK.
* AE_NO_MEMORY: Memory allocation error
*
* DESCRIPTION: Insert a table structure into OSL table list.
*
*****************************************************************************/
static
acpi_status
osl_add_table_to_list
(
char
*
signature
,
u32
instance
)
{
struct
osl_table_info
*
new_info
;
struct
osl_table_info
*
next
;
u32
next_instance
=
0
;
u8
found
=
FALSE
;
new_info
=
calloc
(
1
,
sizeof
(
struct
osl_table_info
));
if
(
!
new_info
)
{
return
(
AE_NO_MEMORY
);
}
ACPI_MOVE_NAME
(
new_info
->
signature
,
signature
);
if
(
!
gbl_table_list_head
)
{
gbl_table_list_head
=
new_info
;
}
else
{
next
=
gbl_table_list_head
;
while
(
1
)
{
if
(
ACPI_COMPARE_NAME
(
next
->
signature
,
signature
))
{
if
(
next
->
instance
==
instance
)
{
found
=
TRUE
;
}
if
(
next
->
instance
>=
next_instance
)
{
next_instance
=
next
->
instance
+
1
;
}
}
if
(
!
next
->
next
)
{
break
;
}
next
=
next
->
next
;
}
next
->
next
=
new_info
;
}
if
(
found
)
{
if
(
instance
)
{
fprintf
(
stderr
,
"%4.4s: Warning unmatched table instance %d, expected %d
\n
"
,
signature
,
instance
,
next_instance
);
}
instance
=
next_instance
;
}
new_info
->
instance
=
instance
;
gbl_table_count
++
;
return
(
AE_OK
);
}
/******************************************************************************
*
* FUNCTION: acpi_os_get_table_by_index
*
* PARAMETERS: index - Which table to get
* table - Where a pointer to the table is returned
* instance - Where a pointer to the table instance no. is
* returned
* address - Where the table physical address is returned
*
* RETURN: Status; Table buffer and physical address returned if AE_OK.
* AE_LIMIT: Index is beyond valid limit
*
* DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
* AE_LIMIT when an invalid index is reached. Index is not
* necessarily an index into the RSDT/XSDT.
*
*****************************************************************************/
acpi_status
acpi_os_get_table_by_index
(
u32
index
,
struct
acpi_table_header
**
table
,
u32
*
instance
,
acpi_physical_address
*
address
)
{
struct
osl_table_info
*
info
;
acpi_status
status
;
u32
i
;
/* Get main ACPI tables from memory on first invocation of this function */
status
=
osl_table_initialize
();
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
/* Validate Index */
if
(
index
>=
gbl_table_count
)
{
return
(
AE_LIMIT
);
}
/* Point to the table list entry specified by the Index argument */
info
=
gbl_table_list_head
;
for
(
i
=
0
;
i
<
index
;
i
++
)
{
info
=
info
->
next
;
}
/* Now we can just get the table via the signature */
status
=
acpi_os_get_table_by_name
(
info
->
signature
,
info
->
instance
,
table
,
address
);
if
(
ACPI_SUCCESS
(
status
))
{
*
instance
=
info
->
instance
;
}
return
(
status
);
}
/******************************************************************************
*
* FUNCTION: osl_find_rsdp_via_efi
*
* PARAMETERS: None
*
* RETURN: RSDP address if found
*
* DESCRIPTION: Find RSDP address via EFI.
*
*****************************************************************************/
static
acpi_physical_address
osl_find_rsdp_via_efi
(
void
)
{
FILE
*
file
;
char
buffer
[
80
];
unsigned
long
address
=
0
;
file
=
fopen
(
EFI_SYSTAB
,
"r"
);
if
(
file
)
{
while
(
fgets
(
buffer
,
80
,
file
))
{
if
(
sscanf
(
buffer
,
"ACPI20=0x%lx"
,
&
address
)
==
1
)
{
break
;
}
}
fclose
(
file
);
}
return
((
acpi_physical_address
)
(
address
));
}
/******************************************************************************
*
* FUNCTION: osl_load_rsdp
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Scan and load RSDP.
*
*****************************************************************************/
static
acpi_status
osl_load_rsdp
(
void
)
{
struct
acpi_table_header
*
mapped_table
;
u8
*
rsdp_address
;
acpi_physical_address
rsdp_base
;
acpi_size
rsdp_size
;
/* Get RSDP from memory */
rsdp_size
=
sizeof
(
struct
acpi_table_rsdp
);
if
(
gbl_rsdp_base
)
{
rsdp_base
=
gbl_rsdp_base
;
}
else
{
rsdp_base
=
osl_find_rsdp_via_efi
();
}
if
(
!
rsdp_base
)
{
rsdp_base
=
ACPI_HI_RSDP_WINDOW_BASE
;
rsdp_size
=
ACPI_HI_RSDP_WINDOW_SIZE
;
}
rsdp_address
=
acpi_os_map_memory
(
rsdp_base
,
rsdp_size
);
if
(
!
rsdp_address
)
{
return
(
osl_get_last_status
(
AE_BAD_ADDRESS
));
}
/* Search low memory for the RSDP */
mapped_table
=
ACPI_CAST_PTR
(
struct
acpi_table_header
,
acpi_tb_scan_memory_for_rsdp
(
rsdp_address
,
rsdp_size
));
if
(
!
mapped_table
)
{
acpi_os_unmap_memory
(
rsdp_address
,
rsdp_size
);
return
(
AE_NOT_FOUND
);
}
gbl_rsdp_address
=
rsdp_base
+
(
ACPI_CAST8
(
mapped_table
)
-
rsdp_address
);
ACPI_MEMCPY
(
&
gbl_rsdp
,
mapped_table
,
sizeof
(
struct
acpi_table_rsdp
));
acpi_os_unmap_memory
(
rsdp_address
,
rsdp_size
);
return
(
AE_OK
);
}
/******************************************************************************
*
* FUNCTION: osl_table_initialize
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
* local variables. Main ACPI tables include RSDT, FADT, RSDT,
* and/or XSDT.
*
*****************************************************************************/
static
acpi_status
osl_table_initialize
(
void
)
{
acpi_status
status
;
acpi_physical_address
address
;
if
(
gbl_table_list_initialized
)
{
return
(
AE_OK
);
}
/* Get RSDP from memory */
status
=
osl_load_rsdp
();
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
/* Get XSDT from memory */
if
(
gbl_rsdp
.
revision
)
{
if
(
gbl_xsdt
)
{
free
(
gbl_xsdt
);
gbl_xsdt
=
NULL
;
}
gbl_revision
=
2
;
status
=
osl_get_bios_table
(
ACPI_SIG_XSDT
,
0
,
ACPI_CAST_PTR
(
struct
acpi_table_header
*
,
&
gbl_xsdt
),
&
address
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
}
/* Get RSDT from memory */
if
(
gbl_rsdp
.
rsdt_physical_address
)
{
if
(
gbl_rsdt
)
{
free
(
gbl_rsdt
);
gbl_rsdt
=
NULL
;
}
status
=
osl_get_bios_table
(
ACPI_SIG_RSDT
,
0
,
ACPI_CAST_PTR
(
struct
acpi_table_header
*
,
&
gbl_rsdt
),
&
address
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
}
/* Get FADT from memory */
if
(
gbl_fadt
)
{
free
(
gbl_fadt
);
gbl_fadt
=
NULL
;
}
status
=
osl_get_bios_table
(
ACPI_SIG_FADT
,
0
,
ACPI_CAST_PTR
(
struct
acpi_table_header
*
,
&
gbl_fadt
),
&
gbl_fadt_address
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
if
(
!
gbl_dump_customized_tables
)
{
/* Add mandatory tables to global table list first */
status
=
osl_add_table_to_list
(
ACPI_RSDP_NAME
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
status
=
osl_add_table_to_list
(
ACPI_SIG_RSDT
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
if
(
gbl_revision
==
2
)
{
status
=
osl_add_table_to_list
(
ACPI_SIG_XSDT
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
}
status
=
osl_add_table_to_list
(
ACPI_SIG_DSDT
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
status
=
osl_add_table_to_list
(
ACPI_SIG_FACS
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
/* Add all tables found in the memory */
status
=
osl_list_bios_tables
();
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
}
else
{
/* Add all tables found in the static directory */
status
=
osl_list_customized_tables
(
STATIC_TABLE_DIR
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
}
if
(
gbl_dump_dynamic_tables
)
{
/* Add all dynamically loaded tables in the dynamic directory */
status
=
osl_list_customized_tables
(
DYNAMIC_TABLE_DIR
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
}
gbl_table_list_initialized
=
TRUE
;
return
(
AE_OK
);
}
/******************************************************************************
*
* FUNCTION: osl_list_bios_tables
*
* PARAMETERS: None
*
* RETURN: Status; Table list is initialized if AE_OK.
*
* DESCRIPTION: Add ACPI tables to the table list from memory.
*
* NOTE: This works on Linux as table customization does not modify the
* addresses stored in RSDP/RSDT/XSDT/FADT.
*
*****************************************************************************/
static
acpi_status
osl_list_bios_tables
(
void
)
{
struct
acpi_table_header
*
mapped_table
=
NULL
;
u8
*
table_data
;
u8
number_of_tables
;
u8
item_size
;
acpi_physical_address
table_address
=
0
;
acpi_status
status
=
AE_OK
;
u32
i
;
if
(
gbl_revision
)
{
item_size
=
sizeof
(
u64
);
table_data
=
ACPI_CAST8
(
gbl_xsdt
)
+
sizeof
(
struct
acpi_table_header
);
number_of_tables
=
(
u8
)((
gbl_xsdt
->
header
.
length
-
sizeof
(
struct
acpi_table_header
))
/
item_size
);
}
else
{
/* Use RSDT if XSDT is not available */
item_size
=
sizeof
(
u32
);
table_data
=
ACPI_CAST8
(
gbl_rsdt
)
+
sizeof
(
struct
acpi_table_header
);
number_of_tables
=
(
u8
)((
gbl_rsdt
->
header
.
length
-
sizeof
(
struct
acpi_table_header
))
/
item_size
);
}
/* Search RSDT/XSDT for the requested table */
for
(
i
=
0
;
i
<
number_of_tables
;
++
i
,
table_data
+=
item_size
)
{
if
(
gbl_revision
)
{
table_address
=
(
acpi_physical_address
)
(
*
ACPI_CAST64
(
table_data
));
}
else
{
table_address
=
(
acpi_physical_address
)
(
*
ACPI_CAST32
(
table_data
));
}
status
=
osl_map_table
(
table_address
,
NULL
,
&
mapped_table
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
osl_add_table_to_list
(
mapped_table
->
signature
,
0
);
osl_unmap_table
(
mapped_table
);
}
return
(
AE_OK
);
}
/******************************************************************************
*
* FUNCTION: osl_get_bios_table
*
* PARAMETERS: signature - ACPI Signature for common table. Must be
* a null terminated 4-character string.
* instance - Multiple table support for SSDT/UEFI (0...n)
* Must be 0 for other tables.
* table - Where a pointer to the table is returned
* address - Where the table physical address is returned
*
* RETURN: Status; Table buffer and physical address returned if AE_OK.
* AE_LIMIT: Instance is beyond valid limit
* AE_NOT_FOUND: A table with the signature was not found
*
* DESCRIPTION: Get a BIOS provided ACPI table
*
* NOTE: Assumes the input signature is uppercase.
*
*****************************************************************************/
static
acpi_status
osl_get_bios_table
(
char
*
signature
,
u32
instance
,
struct
acpi_table_header
**
table
,
acpi_physical_address
*
address
)
{
struct
acpi_table_header
*
local_table
=
NULL
;
struct
acpi_table_header
*
mapped_table
=
NULL
;
u8
*
table_data
;
u8
number_of_tables
;
u8
item_size
;
u32
current_instance
=
0
;
acpi_physical_address
table_address
=
0
;
u32
table_length
=
0
;
acpi_status
status
=
AE_OK
;
u32
i
;
/* Handle special tables whose addresses are not in RSDT/XSDT */
if
(
ACPI_COMPARE_NAME
(
signature
,
ACPI_RSDP_NAME
)
||
ACPI_COMPARE_NAME
(
signature
,
ACPI_SIG_RSDT
)
||
ACPI_COMPARE_NAME
(
signature
,
ACPI_SIG_XSDT
)
||
ACPI_COMPARE_NAME
(
signature
,
ACPI_SIG_DSDT
)
||
ACPI_COMPARE_NAME
(
signature
,
ACPI_SIG_FACS
))
{
/*
* Get the appropriate address, either 32-bit or 64-bit. Be very
* careful about the FADT length and validate table addresses.
* Note: The 64-bit addresses have priority.
*/
if
(
ACPI_COMPARE_NAME
(
signature
,
ACPI_SIG_DSDT
))
{
if
((
gbl_fadt
->
header
.
length
>=
MIN_FADT_FOR_XDSDT
)
&&
gbl_fadt
->
Xdsdt
)
{
table_address
=
(
acpi_physical_address
)
gbl_fadt
->
Xdsdt
;
}
else
if
((
gbl_fadt
->
header
.
length
>=
MIN_FADT_FOR_DSDT
)
&&
gbl_fadt
->
dsdt
)
{
table_address
=
(
acpi_physical_address
)
gbl_fadt
->
dsdt
;
}
}
else
if
(
ACPI_COMPARE_NAME
(
signature
,
ACPI_SIG_FACS
))
{
if
((
gbl_fadt
->
header
.
length
>=
MIN_FADT_FOR_XFACS
)
&&
gbl_fadt
->
Xfacs
)
{
table_address
=
(
acpi_physical_address
)
gbl_fadt
->
Xfacs
;
}
else
if
((
gbl_fadt
->
header
.
length
>=
MIN_FADT_FOR_FACS
)
&&
gbl_fadt
->
facs
)
{
table_address
=
(
acpi_physical_address
)
gbl_fadt
->
facs
;
}
}
else
if
(
ACPI_COMPARE_NAME
(
signature
,
ACPI_SIG_XSDT
))
{
if
(
!
gbl_revision
)
{
return
(
AE_BAD_SIGNATURE
);
}
table_address
=
(
acpi_physical_address
)
gbl_rsdp
.
xsdt_physical_address
;
}
else
if
(
ACPI_COMPARE_NAME
(
signature
,
ACPI_SIG_RSDT
))
{
table_address
=
(
acpi_physical_address
)
gbl_rsdp
.
rsdt_physical_address
;
}
else
{
table_address
=
(
acpi_physical_address
)
gbl_rsdp_address
;
signature
=
ACPI_SIG_RSDP
;
}
/* Now we can get the requested special table */
status
=
osl_map_table
(
table_address
,
signature
,
&
mapped_table
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
table_length
=
ap_get_table_length
(
mapped_table
);
}
else
{
/* Case for a normal ACPI table */
if
(
gbl_revision
)
{
item_size
=
sizeof
(
u64
);
table_data
=
ACPI_CAST8
(
gbl_xsdt
)
+
sizeof
(
struct
acpi_table_header
);
number_of_tables
=
(
u8
)((
gbl_xsdt
->
header
.
length
-
sizeof
(
struct
acpi_table_header
))
/
item_size
);
}
else
{
/* Use RSDT if XSDT is not available */
item_size
=
sizeof
(
u32
);
table_data
=
ACPI_CAST8
(
gbl_rsdt
)
+
sizeof
(
struct
acpi_table_header
);
number_of_tables
=
(
u8
)((
gbl_rsdt
->
header
.
length
-
sizeof
(
struct
acpi_table_header
))
/
item_size
);
}
/* Search RSDT/XSDT for the requested table */
for
(
i
=
0
;
i
<
number_of_tables
;
++
i
,
table_data
+=
item_size
)
{
if
(
gbl_revision
)
{
table_address
=
(
acpi_physical_address
)
(
*
ACPI_CAST64
(
table_data
));
}
else
{
table_address
=
(
acpi_physical_address
)
(
*
ACPI_CAST32
(
table_data
));
}
status
=
osl_map_table
(
table_address
,
NULL
,
&
mapped_table
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
table_length
=
mapped_table
->
length
;
/* Does this table match the requested signature? */
if
(
!
ACPI_COMPARE_NAME
(
mapped_table
->
signature
,
signature
))
{
osl_unmap_table
(
mapped_table
);
mapped_table
=
NULL
;
continue
;
}
/* Match table instance (for SSDT/UEFI tables) */
if
(
current_instance
!=
instance
)
{
osl_unmap_table
(
mapped_table
);
mapped_table
=
NULL
;
current_instance
++
;
continue
;
}
break
;
}
}
if
(
!
mapped_table
)
{
return
(
AE_LIMIT
);
}
if
(
table_length
==
0
)
{
status
=
AE_BAD_HEADER
;
goto
exit
;
}
/* Copy table to local buffer and return it */
local_table
=
calloc
(
1
,
table_length
);
if
(
!
local_table
)
{
status
=
AE_NO_MEMORY
;
goto
exit
;
}
ACPI_MEMCPY
(
local_table
,
mapped_table
,
table_length
);
*
address
=
table_address
;
*
table
=
local_table
;
exit:
osl_unmap_table
(
mapped_table
);
return
(
status
);
}
/******************************************************************************
*
* FUNCTION: osl_list_customized_tables
*
* PARAMETERS: directory - Directory that contains the tables
*
* RETURN: Status; Table list is initialized if AE_OK.
*
* DESCRIPTION: Add ACPI tables to the table list from a directory.
*
*****************************************************************************/
static
acpi_status
osl_list_customized_tables
(
char
*
directory
)
{
void
*
table_dir
;
u32
instance
;
char
temp_name
[
ACPI_NAME_SIZE
];
char
*
filename
;
acpi_status
status
=
AE_OK
;
/* Open the requested directory */
table_dir
=
acpi_os_open_directory
(
directory
,
"*"
,
REQUEST_FILE_ONLY
);
if
(
!
table_dir
)
{
return
(
osl_get_last_status
(
AE_NOT_FOUND
));
}
/* Examine all entries in this directory */
while
((
filename
=
acpi_os_get_next_filename
(
table_dir
)))
{
/* Extract table name and instance number */
status
=
osl_table_name_from_file
(
filename
,
temp_name
,
&
instance
);
/* Ignore meaningless files */
if
(
ACPI_FAILURE
(
status
))
{
continue
;
}
/* Add new info node to global table list */
status
=
osl_add_table_to_list
(
temp_name
,
instance
);
if
(
ACPI_FAILURE
(
status
))
{
break
;
}
}
acpi_os_close_directory
(
table_dir
);
return
(
status
);
}
/******************************************************************************
*
* FUNCTION: osl_map_table
*
* PARAMETERS: address - Address of the table in memory
* signature - Optional ACPI Signature for desired table.
* Null terminated 4-character string.
* table - Where a pointer to the mapped table is
* returned
*
* RETURN: Status; Mapped table is returned if AE_OK.
* AE_NOT_FOUND: A valid table was not found at the address
*
* DESCRIPTION: Map entire ACPI table into caller's address space.
*
*****************************************************************************/
static
acpi_status
osl_map_table
(
acpi_size
address
,
char
*
signature
,
struct
acpi_table_header
**
table
)
{
struct
acpi_table_header
*
mapped_table
;
u32
length
;
if
(
!
address
)
{
return
(
AE_BAD_ADDRESS
);
}
/*
* Map the header so we can get the table length.
* Use sizeof (struct acpi_table_header) as:
* 1. it is bigger than 24 to include RSDP->Length
* 2. it is smaller than sizeof (struct acpi_table_rsdp)
*/
mapped_table
=
acpi_os_map_memory
(
address
,
sizeof
(
struct
acpi_table_header
));
if
(
!
mapped_table
)
{
fprintf
(
stderr
,
"Could not map table header at 0x%8.8X%8.8X
\n
"
,
ACPI_FORMAT_UINT64
(
address
));
return
(
osl_get_last_status
(
AE_BAD_ADDRESS
));
}
/* If specified, signature must match */
if
(
signature
&&
!
ACPI_COMPARE_NAME
(
signature
,
mapped_table
->
signature
))
{
acpi_os_unmap_memory
(
mapped_table
,
sizeof
(
struct
acpi_table_header
));
return
(
AE_BAD_SIGNATURE
);
}
/* Map the entire table */
length
=
ap_get_table_length
(
mapped_table
);
acpi_os_unmap_memory
(
mapped_table
,
sizeof
(
struct
acpi_table_header
));
if
(
length
==
0
)
{
return
(
AE_BAD_HEADER
);
}
mapped_table
=
acpi_os_map_memory
(
address
,
length
);
if
(
!
mapped_table
)
{
fprintf
(
stderr
,
"Could not map table at 0x%8.8X%8.8X length %8.8X
\n
"
,
ACPI_FORMAT_UINT64
(
address
),
length
);
return
(
osl_get_last_status
(
AE_INVALID_TABLE_LENGTH
));
}
(
void
)
ap_is_valid_checksum
(
mapped_table
);
*
table
=
mapped_table
;
return
(
AE_OK
);
}
/******************************************************************************
*
* FUNCTION: osl_unmap_table
*
* PARAMETERS: table - A pointer to the mapped table
*
* RETURN: None
*
* DESCRIPTION: Unmap entire ACPI table.
*
*****************************************************************************/
static
void
osl_unmap_table
(
struct
acpi_table_header
*
table
)
{
if
(
table
)
{
acpi_os_unmap_memory
(
table
,
ap_get_table_length
(
table
));
}
}
/******************************************************************************
*
* FUNCTION: osl_table_name_from_file
*
* PARAMETERS: filename - File that contains the desired table
* signature - Pointer to 4-character buffer to store
* extracted table signature.
* instance - Pointer to integer to store extracted
* table instance number.
*
* RETURN: Status; Table name is extracted if AE_OK.
*
* DESCRIPTION: Extract table signature and instance number from a table file
* name.
*
*****************************************************************************/
static
acpi_status
osl_table_name_from_file
(
char
*
filename
,
char
*
signature
,
u32
*
instance
)
{
/* Ignore meaningless files */
if
(
strlen
(
filename
)
<
ACPI_NAME_SIZE
)
{
return
(
AE_BAD_SIGNATURE
);
}
/* Extract instance number */
if
(
isdigit
((
int
)
filename
[
ACPI_NAME_SIZE
]))
{
sscanf
(
&
filename
[
ACPI_NAME_SIZE
],
"%d"
,
instance
);
}
else
if
(
strlen
(
filename
)
!=
ACPI_NAME_SIZE
)
{
return
(
AE_BAD_SIGNATURE
);
}
else
{
*
instance
=
0
;
}
/* Extract signature */
ACPI_MOVE_NAME
(
signature
,
filename
);
return
(
AE_OK
);
}
/******************************************************************************
*
* FUNCTION: osl_read_table_from_file
*
* PARAMETERS: filename - File that contains the desired table
* file_offset - Offset of the table in file
* signature - Optional ACPI Signature for desired table.
* A null terminated 4-character string.
* table - Where a pointer to the table is returned
*
* RETURN: Status; Table buffer is returned if AE_OK.
*
* DESCRIPTION: Read a ACPI table from a file.
*
*****************************************************************************/
static
acpi_status
osl_read_table_from_file
(
char
*
filename
,
acpi_size
file_offset
,
char
*
signature
,
struct
acpi_table_header
**
table
)
{
FILE
*
table_file
;
struct
acpi_table_header
header
;
struct
acpi_table_header
*
local_table
=
NULL
;
u32
table_length
;
s32
count
;
u32
total
=
0
;
acpi_status
status
=
AE_OK
;
/* Open the file */
table_file
=
fopen
(
filename
,
"rb"
);
if
(
table_file
==
NULL
)
{
fprintf
(
stderr
,
"Could not open table file: %s
\n
"
,
filename
);
return
(
osl_get_last_status
(
AE_NOT_FOUND
));
}
fseek
(
table_file
,
file_offset
,
SEEK_SET
);
/* Read the Table header to get the table length */
count
=
fread
(
&
header
,
1
,
sizeof
(
struct
acpi_table_header
),
table_file
);
if
(
count
!=
sizeof
(
struct
acpi_table_header
))
{
fprintf
(
stderr
,
"Could not read table header: %s
\n
"
,
filename
);
status
=
AE_BAD_HEADER
;
goto
exit
;
}
/* If signature is specified, it must match the table */
if
(
signature
&&
!
ACPI_COMPARE_NAME
(
signature
,
header
.
signature
))
{
fprintf
(
stderr
,
"Incorrect signature: Expecting %4.4s, found %4.4s
\n
"
,
signature
,
header
.
signature
);
status
=
AE_BAD_SIGNATURE
;
goto
exit
;
}
table_length
=
ap_get_table_length
(
&
header
);
if
(
table_length
==
0
)
{
status
=
AE_BAD_HEADER
;
goto
exit
;
}
/* Read the entire table into a local buffer */
local_table
=
calloc
(
1
,
table_length
);
if
(
!
local_table
)
{
fprintf
(
stderr
,
"%4.4s: Could not allocate buffer for table of length %X
\n
"
,
header
.
signature
,
table_length
);
status
=
AE_NO_MEMORY
;
goto
exit
;
}
fseek
(
table_file
,
file_offset
,
SEEK_SET
);
while
(
!
feof
(
table_file
)
&&
total
<
table_length
)
{
count
=
fread
(
local_table
+
total
,
1
,
table_length
-
total
,
table_file
);
if
(
count
<
0
)
{
fprintf
(
stderr
,
"%4.4s: Could not read table content
\n
"
,
header
.
signature
);
status
=
AE_INVALID_TABLE_LENGTH
;
goto
exit
;
}
total
+=
count
;
}
/* Validate checksum */
(
void
)
ap_is_valid_checksum
(
local_table
);
exit:
fclose
(
table_file
);
*
table
=
local_table
;
return
(
status
);
}
/******************************************************************************
*
* FUNCTION: osl_get_customized_table
*
* PARAMETERS: pathname - Directory to find Linux customized table
* signature - ACPI Signature for desired table. Must be
* a null terminated 4-character string.
* instance - Multiple table support for SSDT/UEFI (0...n)
* Must be 0 for other tables.
* table - Where a pointer to the table is returned
* address - Where the table physical address is returned
*
* RETURN: Status; Table buffer is returned if AE_OK.
* AE_LIMIT: Instance is beyond valid limit
* AE_NOT_FOUND: A table with the signature was not found
*
* DESCRIPTION: Get an OS customized table.
*
*****************************************************************************/
static
acpi_status
osl_get_customized_table
(
char
*
pathname
,
char
*
signature
,
u32
instance
,
struct
acpi_table_header
**
table
,
acpi_physical_address
*
address
)
{
void
*
table_dir
;
u32
current_instance
=
0
;
char
temp_name
[
ACPI_NAME_SIZE
];
char
table_filename
[
PATH_MAX
];
char
*
filename
;
acpi_status
status
;
/* Open the directory for customized tables */
table_dir
=
acpi_os_open_directory
(
pathname
,
"*"
,
REQUEST_FILE_ONLY
);
if
(
!
table_dir
)
{
return
(
osl_get_last_status
(
AE_NOT_FOUND
));
}
/* Attempt to find the table in the directory */
while
((
filename
=
acpi_os_get_next_filename
(
table_dir
)))
{
/* Ignore meaningless files */
if
(
!
ACPI_COMPARE_NAME
(
filename
,
signature
))
{
continue
;
}
/* Extract table name and instance number */
status
=
osl_table_name_from_file
(
filename
,
temp_name
,
&
current_instance
);
/* Ignore meaningless files */
if
(
ACPI_FAILURE
(
status
)
||
current_instance
!=
instance
)
{
continue
;
}
/* Create the table pathname */
if
(
instance
!=
0
)
{
sprintf
(
table_filename
,
"%s/%4.4s%d"
,
pathname
,
temp_name
,
instance
);
}
else
{
sprintf
(
table_filename
,
"%s/%4.4s"
,
pathname
,
temp_name
);
}
break
;
}
acpi_os_close_directory
(
table_dir
);
if
(
!
filename
)
{
return
(
AE_LIMIT
);
}
/* There is no physical address saved for customized tables, use zero */
*
address
=
0
;
status
=
osl_read_table_from_file
(
table_filename
,
0
,
NULL
,
table
);
return
(
status
);
}
tools/power/acpi/os_specific/service_layers/osunixdir.c
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: osunixdir - Unix directory access interfaces
*
*****************************************************************************/
/*
* 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.
*/
#include <acpi/acpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <fnmatch.h>
#include <ctype.h>
#include <sys/stat.h>
/*
* Allocated structure returned from os_open_directory
*/
typedef
struct
external_find_info
{
char
*
dir_pathname
;
DIR
*
dir_ptr
;
char
temp_buffer
[
256
];
char
*
wildcard_spec
;
char
requested_file_type
;
}
external_find_info
;
/*******************************************************************************
*
* FUNCTION: acpi_os_open_directory
*
* PARAMETERS: dir_pathname - Full pathname to the directory
* wildcard_spec - string of the form "*.c", etc.
*
* RETURN: A directory "handle" to be used in subsequent search operations.
* NULL returned on failure.
*
* DESCRIPTION: Open a directory in preparation for a wildcard search
*
******************************************************************************/
void
*
acpi_os_open_directory
(
char
*
dir_pathname
,
char
*
wildcard_spec
,
char
requested_file_type
)
{
struct
external_find_info
*
external_info
;
DIR
*
dir
;
/* Allocate the info struct that will be returned to the caller */
external_info
=
calloc
(
1
,
sizeof
(
struct
external_find_info
));
if
(
!
external_info
)
{
return
(
NULL
);
}
/* Get the directory stream */
dir
=
opendir
(
dir_pathname
);
if
(
!
dir
)
{
fprintf
(
stderr
,
"Cannot open directory - %s
\n
"
,
dir_pathname
);
free
(
external_info
);
return
(
NULL
);
}
/* Save the info in the return structure */
external_info
->
wildcard_spec
=
wildcard_spec
;
external_info
->
requested_file_type
=
requested_file_type
;
external_info
->
dir_pathname
=
dir_pathname
;
external_info
->
dir_ptr
=
dir
;
return
(
external_info
);
}
/*******************************************************************************
*
* FUNCTION: acpi_os_get_next_filename
*
* PARAMETERS: dir_handle - Created via acpi_os_open_directory
*
* RETURN: Next filename matched. NULL if no more matches.
*
* DESCRIPTION: Get the next file in the directory that matches the wildcard
* specification.
*
******************************************************************************/
char
*
acpi_os_get_next_filename
(
void
*
dir_handle
)
{
struct
external_find_info
*
external_info
=
dir_handle
;
struct
dirent
*
dir_entry
;
char
*
temp_str
;
int
str_len
;
struct
stat
temp_stat
;
int
err
;
while
((
dir_entry
=
readdir
(
external_info
->
dir_ptr
)))
{
if
(
!
fnmatch
(
external_info
->
wildcard_spec
,
dir_entry
->
d_name
,
0
))
{
if
(
dir_entry
->
d_name
[
0
]
==
'.'
)
{
continue
;
}
str_len
=
strlen
(
dir_entry
->
d_name
)
+
strlen
(
external_info
->
dir_pathname
)
+
2
;
temp_str
=
calloc
(
str_len
,
1
);
if
(
!
temp_str
)
{
fprintf
(
stderr
,
"Could not allocate buffer for temporary string
\n
"
);
return
(
NULL
);
}
strcpy
(
temp_str
,
external_info
->
dir_pathname
);
strcat
(
temp_str
,
"/"
);
strcat
(
temp_str
,
dir_entry
->
d_name
);
err
=
stat
(
temp_str
,
&
temp_stat
);
if
(
err
==
-
1
)
{
fprintf
(
stderr
,
"Cannot stat file (should not happen) - %s
\n
"
,
temp_str
);
free
(
temp_str
);
return
(
NULL
);
}
free
(
temp_str
);
if
((
S_ISDIR
(
temp_stat
.
st_mode
)
&&
(
external_info
->
requested_file_type
==
REQUEST_DIR_ONLY
))
||
((
!
S_ISDIR
(
temp_stat
.
st_mode
)
&&
external_info
->
requested_file_type
==
REQUEST_FILE_ONLY
)))
{
/* copy to a temp buffer because dir_entry struct is on the stack */
strcpy
(
external_info
->
temp_buffer
,
dir_entry
->
d_name
);
return
(
external_info
->
temp_buffer
);
}
}
}
return
(
NULL
);
}
/*******************************************************************************
*
* FUNCTION: acpi_os_close_directory
*
* PARAMETERS: dir_handle - Created via acpi_os_open_directory
*
* RETURN: None.
*
* DESCRIPTION: Close the open directory and cleanup.
*
******************************************************************************/
void
acpi_os_close_directory
(
void
*
dir_handle
)
{
struct
external_find_info
*
external_info
=
dir_handle
;
/* Close the directory and free allocations */
closedir
(
external_info
->
dir_ptr
);
free
(
dir_handle
);
}
tools/power/acpi/os_specific/service_layers/osunixmap.c
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: osunixmap - Unix OSL for file mappings
*
*****************************************************************************/
/*
* 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.
*/
#include "acpidump.h"
#include <unistd.h>
#include <sys/mman.h>
#ifdef _free_BSD
#include <sys/param.h>
#endif
#define _COMPONENT ACPI_OS_SERVICES
ACPI_MODULE_NAME
(
"osunixmap"
)
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifdef _free_BSD
#define MMAP_FLAGS MAP_SHARED
#else
#define MMAP_FLAGS MAP_PRIVATE
#endif
#define SYSTEM_MEMORY "/dev/mem"
/*******************************************************************************
*
* FUNCTION: acpi_os_get_page_size
*
* PARAMETERS: None
*
* RETURN: Page size of the platform.
*
* DESCRIPTION: Obtain page size of the platform.
*
******************************************************************************/
static
acpi_size
acpi_os_get_page_size
(
void
)
{
#ifdef PAGE_SIZE
return
PAGE_SIZE
;
#else
return
sysconf
(
_SC_PAGESIZE
);
#endif
}
/******************************************************************************
*
* FUNCTION: acpi_os_map_memory
*
* PARAMETERS: where - Physical address of memory to be mapped
* length - How much memory to map
*
* RETURN: Pointer to mapped memory. Null on error.
*
* DESCRIPTION: Map physical memory into local address space.
*
*****************************************************************************/
void
*
acpi_os_map_memory
(
acpi_physical_address
where
,
acpi_size
length
)
{
u8
*
mapped_memory
;
acpi_physical_address
offset
;
acpi_size
page_size
;
int
fd
;
fd
=
open
(
SYSTEM_MEMORY
,
O_RDONLY
|
O_BINARY
);
if
(
fd
<
0
)
{
fprintf
(
stderr
,
"Cannot open %s
\n
"
,
SYSTEM_MEMORY
);
return
(
NULL
);
}
/* Align the offset to use mmap */
page_size
=
acpi_os_get_page_size
();
offset
=
where
%
page_size
;
/* Map the table header to get the length of the full table */
mapped_memory
=
mmap
(
NULL
,
(
length
+
offset
),
PROT_READ
,
MMAP_FLAGS
,
fd
,
(
where
-
offset
));
if
(
mapped_memory
==
MAP_FAILED
)
{
fprintf
(
stderr
,
"Cannot map %s
\n
"
,
SYSTEM_MEMORY
);
close
(
fd
);
return
(
NULL
);
}
close
(
fd
);
return
(
ACPI_CAST8
(
mapped_memory
+
offset
));
}
/******************************************************************************
*
* FUNCTION: acpi_os_unmap_memory
*
* PARAMETERS: where - Logical address of memory to be unmapped
* length - How much memory to unmap
*
* RETURN: None.
*
* DESCRIPTION: Delete a previously created mapping. Where and Length must
* correspond to a previous mapping exactly.
*
*****************************************************************************/
void
acpi_os_unmap_memory
(
void
*
where
,
acpi_size
length
)
{
acpi_physical_address
offset
;
acpi_size
page_size
;
page_size
=
acpi_os_get_page_size
();
offset
=
(
acpi_physical_address
)
where
%
page_size
;
munmap
((
u8
*
)
where
-
offset
,
(
length
+
offset
));
}
tools/power/acpi/tools/acpidump/acpidump.c
deleted
100644 → 0
View file @
d48dc067
/*
* (c) Alexey Starikovskiy, Intel, 2005-2006.
* 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.
*/
#ifdef DEFINE_ALTERNATE_TYPES
/* hack to enable building old application with new headers -lenb */
#define acpi_fadt_descriptor acpi_table_fadt
#define acpi_rsdp_descriptor acpi_table_rsdp
#define DSDT_SIG ACPI_SIG_DSDT
#define FACS_SIG ACPI_SIG_FACS
#define FADT_SIG ACPI_SIG_FADT
#define xfirmware_ctrl Xfacs
#define firmware_ctrl facs
typedef
int
s32
;
typedef
unsigned
char
u8
;
typedef
unsigned
short
u16
;
typedef
unsigned
int
u32
;
typedef
unsigned
long
long
u64
;
typedef
long
long
s64
;
#endif
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <dirent.h>
#include <acpi/acconfig.h>
#include <acpi/platform/acenv.h>
#include <acpi/actypes.h>
#include <acpi/actbl.h>
static
inline
u8
checksum
(
u8
*
buffer
,
u32
length
)
{
u8
sum
=
0
,
*
i
=
buffer
;
buffer
+=
length
;
for
(;
i
<
buffer
;
sum
+=
*
(
i
++
));
return
sum
;
}
static
unsigned
long
psz
,
addr
,
length
;
static
int
print
,
connect
,
skip
;
static
u8
select_sig
[
4
];
static
unsigned
long
read_efi_systab
(
void
)
{
char
buffer
[
80
];
unsigned
long
addr
;
FILE
*
f
=
fopen
(
"/sys/firmware/efi/systab"
,
"r"
);
if
(
f
)
{
while
(
fgets
(
buffer
,
80
,
f
))
{
if
(
sscanf
(
buffer
,
"ACPI20=0x%lx"
,
&
addr
)
==
1
)
return
addr
;
}
fclose
(
f
);
}
return
0
;
}
static
u8
*
acpi_map_memory
(
unsigned
long
where
,
unsigned
length
)
{
unsigned
long
offset
;
u8
*
there
;
int
fd
=
open
(
"/dev/mem"
,
O_RDONLY
);
if
(
fd
<
0
)
{
fprintf
(
stderr
,
"acpi_os_map_memory: cannot open /dev/mem
\n
"
);
exit
(
1
);
}
offset
=
where
%
psz
;
there
=
mmap
(
NULL
,
length
+
offset
,
PROT_READ
,
MAP_PRIVATE
,
fd
,
where
-
offset
);
close
(
fd
);
if
(
there
==
MAP_FAILED
)
return
0
;
return
(
there
+
offset
);
}
static
void
acpi_unmap_memory
(
u8
*
there
,
unsigned
length
)
{
unsigned
long
offset
=
(
unsigned
long
)
there
%
psz
;
munmap
(
there
-
offset
,
length
+
offset
);
}
static
struct
acpi_table_header
*
acpi_map_table
(
unsigned
long
where
,
char
*
sig
)
{
unsigned
size
;
struct
acpi_table_header
*
tbl
=
(
struct
acpi_table_header
*
)
acpi_map_memory
(
where
,
sizeof
(
struct
acpi_table_header
));
if
(
!
tbl
||
(
sig
&&
memcmp
(
sig
,
tbl
->
signature
,
4
)))
return
0
;
size
=
tbl
->
length
;
acpi_unmap_memory
((
u8
*
)
tbl
,
sizeof
(
struct
acpi_table_header
));
return
(
struct
acpi_table_header
*
)
acpi_map_memory
(
where
,
size
);
}
static
void
acpi_unmap_table
(
struct
acpi_table_header
*
tbl
)
{
acpi_unmap_memory
((
u8
*
)
tbl
,
tbl
->
length
);
}
static
struct
acpi_rsdp_descriptor
*
acpi_scan_for_rsdp
(
u8
*
begin
,
u32
length
)
{
struct
acpi_rsdp_descriptor
*
rsdp
;
u8
*
i
,
*
end
=
begin
+
length
;
/* Search from given start address for the requested length */
for
(
i
=
begin
;
i
<
end
;
i
+=
ACPI_RSDP_SCAN_STEP
)
{
/* The signature and checksum must both be correct */
if
(
memcmp
((
char
*
)
i
,
"RSD PTR "
,
8
))
continue
;
rsdp
=
(
struct
acpi_rsdp_descriptor
*
)
i
;
/* Signature matches, check the appropriate checksum */
if
(
!
checksum
((
u8
*
)
rsdp
,
(
rsdp
->
revision
<
2
)
?
ACPI_RSDP_CHECKSUM_LENGTH
:
ACPI_RSDP_XCHECKSUM_LENGTH
))
/* Checksum valid, we have found a valid RSDP */
return
rsdp
;
}
/* Searched entire block, no RSDP was found */
return
0
;
}
/*
* Output data
*/
static
void
acpi_show_data
(
int
fd
,
u8
*
data
,
int
size
)
{
char
buffer
[
256
];
int
len
;
int
i
,
remain
=
size
;
while
(
remain
>
0
)
{
len
=
snprintf
(
buffer
,
256
,
" %04x:"
,
size
-
remain
);
for
(
i
=
0
;
i
<
16
&&
i
<
remain
;
i
++
)
{
len
+=
snprintf
(
&
buffer
[
len
],
256
-
len
,
" %02x"
,
data
[
i
]);
}
for
(;
i
<
16
;
i
++
)
{
len
+=
snprintf
(
&
buffer
[
len
],
256
-
len
,
" "
);
}
len
+=
snprintf
(
&
buffer
[
len
],
256
-
len
,
" "
);
for
(
i
=
0
;
i
<
16
&&
i
<
remain
;
i
++
)
{
buffer
[
len
++
]
=
(
isprint
(
data
[
i
]))
?
data
[
i
]
:
'.'
;
}
buffer
[
len
++
]
=
'\n'
;
write
(
fd
,
buffer
,
len
);
data
+=
16
;
remain
-=
16
;
}
}
/*
* Output ACPI table
*/
static
void
acpi_show_table
(
int
fd
,
struct
acpi_table_header
*
table
,
unsigned
long
addr
)
{
char
buff
[
80
];
int
len
=
snprintf
(
buff
,
80
,
"%.4s @ %p
\n
"
,
table
->
signature
,
(
void
*
)
addr
);
write
(
fd
,
buff
,
len
);
acpi_show_data
(
fd
,
(
u8
*
)
table
,
table
->
length
);
buff
[
0
]
=
'\n'
;
write
(
fd
,
buff
,
1
);
}
static
void
write_table
(
int
fd
,
struct
acpi_table_header
*
tbl
,
unsigned
long
addr
)
{
static
int
select_done
=
0
;
if
(
!
select_sig
[
0
])
{
if
(
print
)
{
acpi_show_table
(
fd
,
tbl
,
addr
);
}
else
{
write
(
fd
,
tbl
,
tbl
->
length
);
}
}
else
if
(
!
select_done
&&
!
memcmp
(
select_sig
,
tbl
->
signature
,
4
))
{
if
(
skip
>
0
)
{
--
skip
;
return
;
}
if
(
print
)
{
acpi_show_table
(
fd
,
tbl
,
addr
);
}
else
{
write
(
fd
,
tbl
,
tbl
->
length
);
}
select_done
=
1
;
}
}
static
void
acpi_dump_FADT
(
int
fd
,
struct
acpi_table_header
*
tbl
,
unsigned
long
xaddr
)
{
struct
acpi_fadt_descriptor
x
;
unsigned
long
addr
;
size_t
len
=
sizeof
(
struct
acpi_fadt_descriptor
);
if
(
len
>
tbl
->
length
)
len
=
tbl
->
length
;
memcpy
(
&
x
,
tbl
,
len
);
x
.
header
.
length
=
len
;
if
(
checksum
((
u8
*
)
tbl
,
len
))
{
fprintf
(
stderr
,
"Wrong checksum for FADT!
\n
"
);
}
if
(
x
.
header
.
length
>=
148
&&
x
.
Xdsdt
)
{
addr
=
(
unsigned
long
)
x
.
Xdsdt
;
if
(
connect
)
{
x
.
Xdsdt
=
lseek
(
fd
,
0
,
SEEK_CUR
);
}
}
else
if
(
x
.
header
.
length
>=
44
&&
x
.
dsdt
)
{
addr
=
(
unsigned
long
)
x
.
dsdt
;
if
(
connect
)
{
x
.
dsdt
=
lseek
(
fd
,
0
,
SEEK_CUR
);
}
}
else
{
fprintf
(
stderr
,
"No DSDT in FADT!
\n
"
);
goto
no_dsdt
;
}
tbl
=
acpi_map_table
(
addr
,
DSDT_SIG
);
if
(
!
tbl
)
goto
no_dsdt
;
if
(
checksum
((
u8
*
)
tbl
,
tbl
->
length
))
fprintf
(
stderr
,
"Wrong checksum for DSDT!
\n
"
);
write_table
(
fd
,
tbl
,
addr
);
acpi_unmap_table
(
tbl
);
no_dsdt:
if
(
x
.
header
.
length
>=
140
&&
x
.
xfirmware_ctrl
)
{
addr
=
(
unsigned
long
)
x
.
xfirmware_ctrl
;
if
(
connect
)
{
x
.
xfirmware_ctrl
=
lseek
(
fd
,
0
,
SEEK_CUR
);
}
}
else
if
(
x
.
header
.
length
>=
40
&&
x
.
firmware_ctrl
)
{
addr
=
(
unsigned
long
)
x
.
firmware_ctrl
;
if
(
connect
)
{
x
.
firmware_ctrl
=
lseek
(
fd
,
0
,
SEEK_CUR
);
}
}
else
{
fprintf
(
stderr
,
"No FACS in FADT!
\n
"
);
goto
no_facs
;
}
tbl
=
acpi_map_table
(
addr
,
FACS_SIG
);
if
(
!
tbl
)
goto
no_facs
;
/* do not checksum FACS */
write_table
(
fd
,
tbl
,
addr
);
acpi_unmap_table
(
tbl
);
no_facs:
write_table
(
fd
,
(
struct
acpi_table_header
*
)
&
x
,
xaddr
);
}
static
int
acpi_dump_SDT
(
int
fd
,
struct
acpi_rsdp_descriptor
*
rsdp
)
{
struct
acpi_table_header
*
sdt
,
*
tbl
=
0
;
int
xsdt
=
1
,
i
,
num
;
char
*
offset
;
unsigned
long
addr
;
if
(
rsdp
->
revision
>
1
&&
rsdp
->
xsdt_physical_address
)
{
tbl
=
acpi_map_table
(
rsdp
->
xsdt_physical_address
,
"XSDT"
);
}
if
(
!
tbl
&&
rsdp
->
rsdt_physical_address
)
{
xsdt
=
0
;
tbl
=
acpi_map_table
(
rsdp
->
rsdt_physical_address
,
"RSDT"
);
}
if
(
!
tbl
)
return
0
;
sdt
=
malloc
(
tbl
->
length
);
memcpy
(
sdt
,
tbl
,
tbl
->
length
);
acpi_unmap_table
(
tbl
);
if
(
checksum
((
u8
*
)
sdt
,
sdt
->
length
))
fprintf
(
stderr
,
"Wrong checksum for %s!
\n
"
,
(
xsdt
)
?
"XSDT"
:
"RSDT"
);
num
=
(
sdt
->
length
-
sizeof
(
struct
acpi_table_header
))
/
((
xsdt
)
?
sizeof
(
u64
)
:
sizeof
(
u32
));
offset
=
(
char
*
)
sdt
+
sizeof
(
struct
acpi_table_header
);
for
(
i
=
0
;
i
<
num
;
++
i
,
offset
+=
((
xsdt
)
?
sizeof
(
u64
)
:
sizeof
(
u32
)))
{
addr
=
(
xsdt
)
?
(
unsigned
long
)(
*
(
u64
*
)
offset
)
:
(
unsigned
long
)(
*
(
u32
*
)
offset
);
if
(
!
addr
)
continue
;
tbl
=
acpi_map_table
(
addr
,
0
);
if
(
!
tbl
)
continue
;
if
(
!
memcmp
(
tbl
->
signature
,
FADT_SIG
,
4
))
{
acpi_dump_FADT
(
fd
,
tbl
,
addr
);
}
else
{
if
(
checksum
((
u8
*
)
tbl
,
tbl
->
length
))
fprintf
(
stderr
,
"Wrong checksum for generic table!
\n
"
);
write_table
(
fd
,
tbl
,
addr
);
}
acpi_unmap_table
(
tbl
);
if
(
connect
)
{
if
(
xsdt
)
(
*
(
u64
*
)
offset
)
=
lseek
(
fd
,
0
,
SEEK_CUR
);
else
(
*
(
u32
*
)
offset
)
=
lseek
(
fd
,
0
,
SEEK_CUR
);
}
}
if
(
xsdt
)
{
addr
=
(
unsigned
long
)
rsdp
->
xsdt_physical_address
;
if
(
connect
)
{
rsdp
->
xsdt_physical_address
=
lseek
(
fd
,
0
,
SEEK_CUR
);
}
}
else
{
addr
=
(
unsigned
long
)
rsdp
->
rsdt_physical_address
;
if
(
connect
)
{
rsdp
->
rsdt_physical_address
=
lseek
(
fd
,
0
,
SEEK_CUR
);
}
}
write_table
(
fd
,
sdt
,
addr
);
free
(
sdt
);
return
1
;
}
#define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic"
static
void
acpi_dump_dynamic_SSDT
(
int
fd
)
{
struct
stat
file_stat
;
char
filename
[
256
],
*
ptr
;
DIR
*
tabledir
;
struct
dirent
*
entry
;
FILE
*
fp
;
int
count
,
readcount
,
length
;
struct
acpi_table_header
table_header
,
*
ptable
;
if
(
stat
(
DYNAMIC_SSDT
,
&
file_stat
)
==
-
1
)
{
/* The directory doesn't exist */
return
;
}
tabledir
=
opendir
(
DYNAMIC_SSDT
);
if
(
!
tabledir
){
/*can't open the directory */
return
;
}
while
((
entry
=
readdir
(
tabledir
))
!=
0
){
/* skip the file of . /.. */
if
(
entry
->
d_name
[
0
]
==
'.'
)
continue
;
sprintf
(
filename
,
"%s/%s"
,
DYNAMIC_SSDT
,
entry
->
d_name
);
fp
=
fopen
(
filename
,
"r"
);
if
(
fp
==
NULL
)
{
fprintf
(
stderr
,
"Can't open the file of %s
\n
"
,
filename
);
continue
;
}
/* Read the Table header to parse the table length */
count
=
fread
(
&
table_header
,
1
,
sizeof
(
struct
acpi_table_header
),
fp
);
if
(
count
<
sizeof
(
table_header
))
{
/* the length is lessn than ACPI table header. skip it */
fclose
(
fp
);
continue
;
}
length
=
table_header
.
length
;
ptr
=
malloc
(
table_header
.
length
);
fseek
(
fp
,
0
,
SEEK_SET
);
readcount
=
0
;
while
(
!
feof
(
fp
)
&&
readcount
<
length
)
{
count
=
fread
(
ptr
+
readcount
,
1
,
256
,
fp
);
readcount
+=
count
;
}
fclose
(
fp
);
ptable
=
(
struct
acpi_table_header
*
)
ptr
;
if
(
checksum
((
u8
*
)
ptable
,
ptable
->
length
))
fprintf
(
stderr
,
"Wrong checksum "
"for dynamic SSDT table!
\n
"
);
write_table
(
fd
,
ptable
,
0
);
free
(
ptr
);
}
closedir
(
tabledir
);
return
;
}
static
void
usage
(
const
char
*
progname
)
{
puts
(
"Usage:"
);
printf
(
"%s [--addr 0x1234][--table DSDT][--output filename]"
"[--binary][--length 0x456][--help]
\n
"
,
progname
);
puts
(
"
\t
--addr 0x1234 or -a 0x1234 -- look for tables at this physical address"
);
puts
(
"
\t
--table DSDT or -t DSDT -- only dump table with DSDT signature"
);
puts
(
"
\t
--output filename or -o filename -- redirect output from stdin to filename"
);
puts
(
"
\t
--binary or -b -- dump data in binary form rather than in hex-dump format"
);
puts
(
"
\t
--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
"
\n\t\t
region without trying to understand it's contents"
);
puts
(
"
\t
--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one"
);
puts
(
"
\t
--help or -h -- this help message"
);
exit
(
0
);
}
static
struct
option
long_options
[]
=
{
{
"addr"
,
1
,
0
,
0
},
{
"table"
,
1
,
0
,
0
},
{
"output"
,
1
,
0
,
0
},
{
"binary"
,
0
,
0
,
0
},
{
"length"
,
1
,
0
,
0
},
{
"skip"
,
1
,
0
,
0
},
{
"help"
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
}
};
int
main
(
int
argc
,
char
**
argv
)
{
int
option_index
,
c
,
fd
;
u8
*
raw
;
struct
acpi_rsdp_descriptor
rsdpx
,
*
x
=
0
;
char
*
filename
=
0
;
char
buff
[
80
];
memset
(
select_sig
,
0
,
4
);
print
=
1
;
connect
=
0
;
addr
=
length
=
0
;
skip
=
0
;
while
(
1
)
{
option_index
=
0
;
c
=
getopt_long
(
argc
,
argv
,
"a:t:o:bl:s:h"
,
long_options
,
&
option_index
);
if
(
c
==
-
1
)
break
;
switch
(
c
)
{
case
0
:
switch
(
option_index
)
{
case
0
:
addr
=
strtoul
(
optarg
,
(
char
**
)
NULL
,
16
);
break
;
case
1
:
memcpy
(
select_sig
,
optarg
,
4
);
break
;
case
2
:
filename
=
optarg
;
break
;
case
3
:
print
=
0
;
break
;
case
4
:
length
=
strtoul
(
optarg
,
(
char
**
)
NULL
,
16
);
break
;
case
5
:
skip
=
strtoul
(
optarg
,
(
char
**
)
NULL
,
10
);
break
;
case
6
:
usage
(
argv
[
0
]);
exit
(
0
);
}
break
;
case
'a'
:
addr
=
strtoul
(
optarg
,
(
char
**
)
NULL
,
16
);
break
;
case
't'
:
memcpy
(
select_sig
,
optarg
,
4
);
break
;
case
'o'
:
filename
=
optarg
;
break
;
case
'b'
:
print
=
0
;
break
;
case
'l'
:
length
=
strtoul
(
optarg
,
(
char
**
)
NULL
,
16
);
break
;
case
's'
:
skip
=
strtoul
(
optarg
,
(
char
**
)
NULL
,
10
);
break
;
case
'h'
:
usage
(
argv
[
0
]);
exit
(
0
);
default:
printf
(
"Unknown option!
\n
"
);
usage
(
argv
[
0
]);
exit
(
0
);
}
}
fd
=
STDOUT_FILENO
;
if
(
filename
)
{
fd
=
creat
(
filename
,
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_IROTH
);
if
(
fd
<
0
)
return
fd
;
}
if
(
!
select_sig
[
0
]
&&
!
print
)
{
connect
=
1
;
}
psz
=
sysconf
(
_SC_PAGESIZE
);
if
(
length
&&
addr
)
{
/* We know length and address, it means we just want a memory dump */
if
(
!
(
raw
=
acpi_map_memory
(
addr
,
length
)))
goto
not_found
;
write
(
fd
,
raw
,
length
);
acpi_unmap_memory
(
raw
,
length
);
close
(
fd
);
return
0
;
}
length
=
sizeof
(
struct
acpi_rsdp_descriptor
);
if
(
!
addr
)
{
addr
=
read_efi_systab
();
if
(
!
addr
)
{
addr
=
ACPI_HI_RSDP_WINDOW_BASE
;
length
=
ACPI_HI_RSDP_WINDOW_SIZE
;
}
}
if
(
!
(
raw
=
acpi_map_memory
(
addr
,
length
))
||
!
(
x
=
acpi_scan_for_rsdp
(
raw
,
length
)))
goto
not_found
;
/* Find RSDP and print all found tables */
memcpy
(
&
rsdpx
,
x
,
sizeof
(
struct
acpi_rsdp_descriptor
));
acpi_unmap_memory
(
raw
,
length
);
if
(
connect
)
{
lseek
(
fd
,
sizeof
(
struct
acpi_rsdp_descriptor
),
SEEK_SET
);
}
if
(
!
acpi_dump_SDT
(
fd
,
&
rsdpx
))
goto
not_found
;
if
(
connect
)
{
lseek
(
fd
,
0
,
SEEK_SET
);
write
(
fd
,
x
,
(
rsdpx
.
revision
<
2
)
?
ACPI_RSDP_CHECKSUM_LENGTH
:
ACPI_RSDP_XCHECKSUM_LENGTH
);
}
else
if
(
!
select_sig
[
0
]
||
!
memcmp
(
"RSD PTR "
,
select_sig
,
4
))
{
addr
+=
(
long
)
x
-
(
long
)
raw
;
length
=
snprintf
(
buff
,
80
,
"RSD PTR @ %p
\n
"
,
(
void
*
)
addr
);
write
(
fd
,
buff
,
length
);
acpi_show_data
(
fd
,
(
u8
*
)
&
rsdpx
,
(
rsdpx
.
revision
<
2
)
?
ACPI_RSDP_CHECKSUM_LENGTH
:
ACPI_RSDP_XCHECKSUM_LENGTH
);
buff
[
0
]
=
'\n'
;
write
(
fd
,
buff
,
1
);
}
acpi_dump_dynamic_SSDT
(
fd
);
close
(
fd
);
return
0
;
not_found:
close
(
fd
);
fprintf
(
stderr
,
"ACPI tables were not found. If you know location "
"of RSD PTR table (from dmesg, etc), "
"supply it with either --addr or -a option
\n
"
);
return
1
;
}
tools/power/acpi/tools/acpidump/acpidump.h
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: acpidump.h - Include file for acpi_dump utility
*
*****************************************************************************/
/*
* 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.
*/
#include <acpi/acpi.h>
#include "accommon.h"
#include "actables.h"
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
/*
* Global variables. Defined in main.c only, externed in all other files
*/
#ifdef _DECLARE_GLOBALS
#define EXTERN
#define INIT_GLOBAL(a,b) a=b
#else
#define EXTERN extern
#define INIT_GLOBAL(a,b) a
#endif
/* Globals */
EXTERN
u8
INIT_GLOBAL
(
gbl_summary_mode
,
FALSE
);
EXTERN
u8
INIT_GLOBAL
(
gbl_verbose_mode
,
FALSE
);
EXTERN
u8
INIT_GLOBAL
(
gbl_binary_mode
,
FALSE
);
EXTERN
u8
INIT_GLOBAL
(
gbl_dump_customized_tables
,
FALSE
);
EXTERN
FILE
INIT_GLOBAL
(
*
gbl_output_file
,
NULL
);
EXTERN
char
INIT_GLOBAL
(
*
gbl_output_filename
,
NULL
);
EXTERN
u64
INIT_GLOBAL
(
gbl_rsdp_base
,
0
);
/* Globals required for use with ACPICA modules */
#ifdef _DECLARE_GLOBALS
u8
acpi_gbl_enable_interpreter_slack
=
FALSE
;
u8
acpi_gbl_integer_byte_width
=
8
;
u32
acpi_dbg_level
=
0
;
u32
acpi_dbg_layer
=
0
;
#endif
/* Action table used to defer requested options */
struct
ap_dump_action
{
char
*
argument
;
u32
to_be_done
;
};
#define AP_MAX_ACTIONS 32
#define AP_DUMP_ALL_TABLES 0
#define AP_DUMP_TABLE_BY_ADDRESS 1
#define AP_DUMP_TABLE_BY_NAME 2
#define AP_DUMP_TABLE_BY_FILE 3
#define AP_MAX_ACPI_FILES 256
/* Prevent infinite loops */
/* Minimum FADT sizes for various table addresses */
#define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (dsdt) + sizeof (u32))
#define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (facs) + sizeof (u32))
#define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (Xdsdt) + sizeof (u64))
#define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (Xfacs) + sizeof (u64))
/*
* apdump - Table get/dump routines
*/
int
ap_dump_table_from_file
(
char
*
pathname
);
int
ap_dump_table_by_name
(
char
*
signature
);
int
ap_dump_table_by_address
(
char
*
ascii_address
);
int
ap_dump_all_tables
(
void
);
u8
ap_is_valid_header
(
struct
acpi_table_header
*
table
);
u8
ap_is_valid_checksum
(
struct
acpi_table_header
*
table
);
u32
ap_get_table_length
(
struct
acpi_table_header
*
table
);
/*
* apfiles - File I/O utilities
*/
int
ap_open_output_file
(
char
*
pathname
);
int
ap_write_to_binary_file
(
struct
acpi_table_header
*
table
,
u32
instance
);
struct
acpi_table_header
*
ap_get_table_from_file
(
char
*
pathname
,
u32
*
file_size
);
tools/power/acpi/tools/acpidump/apdump.c
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: apdump - Dump routines for ACPI tables (acpidump)
*
*****************************************************************************/
/*
* 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.
*/
#include "acpidump.h"
/* Local prototypes */
static
int
ap_dump_table_buffer
(
struct
acpi_table_header
*
table
,
u32
instance
,
acpi_physical_address
address
);
/******************************************************************************
*
* FUNCTION: ap_is_valid_header
*
* PARAMETERS: table - Pointer to table to be validated
*
* RETURN: TRUE if the header appears to be valid. FALSE otherwise
*
* DESCRIPTION: Check for a valid ACPI table header
*
******************************************************************************/
u8
ap_is_valid_header
(
struct
acpi_table_header
*
table
)
{
if
(
!
ACPI_VALIDATE_RSDP_SIG
(
table
->
signature
))
{
/* Make sure signature is all ASCII and a valid ACPI name */
if
(
!
acpi_ut_valid_acpi_name
(
table
->
signature
))
{
fprintf
(
stderr
,
"Table signature (0x%8.8X) is invalid
\n
"
,
*
(
u32
*
)
table
->
signature
);
return
(
FALSE
);
}
/* Check for minimum table length */
if
(
table
->
length
<
sizeof
(
struct
acpi_table_header
))
{
fprintf
(
stderr
,
"Table length (0x%8.8X) is invalid
\n
"
,
table
->
length
);
return
(
FALSE
);
}
}
return
(
TRUE
);
}
/******************************************************************************
*
* FUNCTION: ap_is_valid_checksum
*
* PARAMETERS: table - Pointer to table to be validated
*
* RETURN: TRUE if the checksum appears to be valid. FALSE otherwise.
*
* DESCRIPTION: Check for a valid ACPI table checksum.
*
******************************************************************************/
u8
ap_is_valid_checksum
(
struct
acpi_table_header
*
table
)
{
acpi_status
status
;
struct
acpi_table_rsdp
*
rsdp
;
if
(
ACPI_VALIDATE_RSDP_SIG
(
table
->
signature
))
{
/*
* Checksum for RSDP.
* Note: Other checksums are computed during the table dump.
*/
rsdp
=
ACPI_CAST_PTR
(
struct
acpi_table_rsdp
,
table
);
status
=
acpi_tb_validate_rsdp
(
rsdp
);
}
else
{
status
=
acpi_tb_verify_checksum
(
table
,
table
->
length
);
}
if
(
ACPI_FAILURE
(
status
))
{
fprintf
(
stderr
,
"%4.4s: Warning: wrong checksum in table
\n
"
,
table
->
signature
);
}
return
(
AE_OK
);
}
/******************************************************************************
*
* FUNCTION: ap_get_table_length
*
* PARAMETERS: table - Pointer to the table
*
* RETURN: Table length
*
* DESCRIPTION: Obtain table length according to table signature.
*
******************************************************************************/
u32
ap_get_table_length
(
struct
acpi_table_header
*
table
)
{
struct
acpi_table_rsdp
*
rsdp
;
/* Check if table is valid */
if
(
!
ap_is_valid_header
(
table
))
{
return
(
0
);
}
if
(
ACPI_VALIDATE_RSDP_SIG
(
table
->
signature
))
{
rsdp
=
ACPI_CAST_PTR
(
struct
acpi_table_rsdp
,
table
);
return
(
rsdp
->
length
);
}
/* Normal ACPI table */
return
(
table
->
length
);
}
/******************************************************************************
*
* FUNCTION: ap_dump_table_buffer
*
* PARAMETERS: table - ACPI table to be dumped
* instance - ACPI table instance no. to be dumped
* address - Physical address of the table
*
* RETURN: None
*
* DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a
* header that is compatible with the acpi_xtract utility.
*
******************************************************************************/
static
int
ap_dump_table_buffer
(
struct
acpi_table_header
*
table
,
u32
instance
,
acpi_physical_address
address
)
{
u32
table_length
;
table_length
=
ap_get_table_length
(
table
);
/* Print only the header if requested */
if
(
gbl_summary_mode
)
{
acpi_tb_print_table_header
(
address
,
table
);
return
(
0
);
}
/* Dump to binary file if requested */
if
(
gbl_binary_mode
)
{
return
(
ap_write_to_binary_file
(
table
,
instance
));
}
/*
* Dump the table with header for use with acpixtract utility.
* Note: simplest to just always emit a 64-bit address. acpi_xtract
* utility can handle this.
*/
printf
(
"%4.4s @ 0x%8.8X%8.8X
\n
"
,
table
->
signature
,
ACPI_FORMAT_UINT64
(
address
));
acpi_ut_dump_buffer
(
ACPI_CAST_PTR
(
u8
,
table
),
table_length
,
DB_BYTE_DISPLAY
,
0
);
printf
(
"
\n
"
);
return
(
0
);
}
/******************************************************************************
*
* FUNCTION: ap_dump_all_tables
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the
* tables that we can possibly get).
*
******************************************************************************/
int
ap_dump_all_tables
(
void
)
{
struct
acpi_table_header
*
table
;
u32
instance
=
0
;
acpi_physical_address
address
;
acpi_status
status
;
int
table_status
;
u32
i
;
/* Get and dump all available ACPI tables */
for
(
i
=
0
;
i
<
AP_MAX_ACPI_FILES
;
i
++
)
{
status
=
acpi_os_get_table_by_index
(
i
,
&
table
,
&
instance
,
&
address
);
if
(
ACPI_FAILURE
(
status
))
{
/* AE_LIMIT means that no more tables are available */
if
(
status
==
AE_LIMIT
)
{
return
(
0
);
}
else
if
(
i
==
0
)
{
fprintf
(
stderr
,
"Could not get ACPI tables, %s
\n
"
,
acpi_format_exception
(
status
));
return
(
-
1
);
}
else
{
fprintf
(
stderr
,
"Could not get ACPI table at index %u, %s
\n
"
,
i
,
acpi_format_exception
(
status
));
continue
;
}
}
table_status
=
ap_dump_table_buffer
(
table
,
instance
,
address
);
free
(
table
);
if
(
table_status
)
{
break
;
}
}
/* Something seriously bad happened if the loop terminates here */
return
(
-
1
);
}
/******************************************************************************
*
* FUNCTION: ap_dump_table_by_address
*
* PARAMETERS: ascii_address - Address for requested ACPI table
*
* RETURN: Status
*
* DESCRIPTION: Get an ACPI table via a physical address and dump it.
*
******************************************************************************/
int
ap_dump_table_by_address
(
char
*
ascii_address
)
{
acpi_physical_address
address
;
struct
acpi_table_header
*
table
;
acpi_status
status
;
int
table_status
;
u64
long_address
;
/* Convert argument to an integer physical address */
status
=
acpi_ut_strtoul64
(
ascii_address
,
0
,
&
long_address
);
if
(
ACPI_FAILURE
(
status
))
{
fprintf
(
stderr
,
"%s: Could not convert to a physical address
\n
"
,
ascii_address
);
return
(
-
1
);
}
address
=
(
acpi_physical_address
)
long_address
;
status
=
acpi_os_get_table_by_address
(
address
,
&
table
);
if
(
ACPI_FAILURE
(
status
))
{
fprintf
(
stderr
,
"Could not get table at 0x%8.8X%8.8X, %s
\n
"
,
ACPI_FORMAT_UINT64
(
address
),
acpi_format_exception
(
status
));
return
(
-
1
);
}
table_status
=
ap_dump_table_buffer
(
table
,
0
,
address
);
free
(
table
);
return
(
table_status
);
}
/******************************************************************************
*
* FUNCTION: ap_dump_table_by_name
*
* PARAMETERS: signature - Requested ACPI table signature
*
* RETURN: Status
*
* DESCRIPTION: Get an ACPI table via a signature and dump it. Handles
* multiple tables with the same signature (SSDTs).
*
******************************************************************************/
int
ap_dump_table_by_name
(
char
*
signature
)
{
char
local_signature
[
ACPI_NAME_SIZE
+
1
];
u32
instance
;
struct
acpi_table_header
*
table
;
acpi_physical_address
address
;
acpi_status
status
;
int
table_status
;
if
(
strlen
(
signature
)
!=
ACPI_NAME_SIZE
)
{
fprintf
(
stderr
,
"Invalid table signature [%s]: must be exactly 4 characters
\n
"
,
signature
);
return
(
-
1
);
}
/* Table signatures are expected to be uppercase */
strcpy
(
local_signature
,
signature
);
acpi_ut_strupr
(
local_signature
);
/* To be friendly, handle tables whose signatures do not match the name */
if
(
ACPI_COMPARE_NAME
(
local_signature
,
"FADT"
))
{
strcpy
(
local_signature
,
ACPI_SIG_FADT
);
}
else
if
(
ACPI_COMPARE_NAME
(
local_signature
,
"MADT"
))
{
strcpy
(
local_signature
,
ACPI_SIG_MADT
);
}
/* Dump all instances of this signature (to handle multiple SSDTs) */
for
(
instance
=
0
;
instance
<
AP_MAX_ACPI_FILES
;
instance
++
)
{
status
=
acpi_os_get_table_by_name
(
local_signature
,
instance
,
&
table
,
&
address
);
if
(
ACPI_FAILURE
(
status
))
{
/* AE_LIMIT means that no more tables are available */
if
(
status
==
AE_LIMIT
)
{
return
(
0
);
}
fprintf
(
stderr
,
"Could not get ACPI table with signature [%s], %s
\n
"
,
local_signature
,
acpi_format_exception
(
status
));
return
(
-
1
);
}
table_status
=
ap_dump_table_buffer
(
table
,
instance
,
address
);
free
(
table
);
if
(
table_status
)
{
break
;
}
}
/* Something seriously bad happened if the loop terminates here */
return
(
-
1
);
}
/******************************************************************************
*
* FUNCTION: ap_dump_table_from_file
*
* PARAMETERS: pathname - File containing the binary ACPI table
*
* RETURN: Status
*
* DESCRIPTION: Dump an ACPI table from a binary file
*
******************************************************************************/
int
ap_dump_table_from_file
(
char
*
pathname
)
{
struct
acpi_table_header
*
table
;
u32
file_size
=
0
;
int
table_status
=
-
1
;
/* Get the entire ACPI table from the file */
table
=
ap_get_table_from_file
(
pathname
,
&
file_size
);
if
(
!
table
)
{
return
(
-
1
);
}
/* File must be at least as long as the table length */
if
(
table
->
length
>
file_size
)
{
fprintf
(
stderr
,
"Table length (0x%X) is too large for input file (0x%X) %s
\n
"
,
table
->
length
,
file_size
,
pathname
);
goto
exit
;
}
if
(
gbl_verbose_mode
)
{
fprintf
(
stderr
,
"Input file: %s contains table [%4.4s], 0x%X (%u) bytes
\n
"
,
pathname
,
table
->
signature
,
file_size
,
file_size
);
}
table_status
=
ap_dump_table_buffer
(
table
,
0
,
0
);
exit:
free
(
table
);
return
(
table_status
);
}
/******************************************************************************
*
* FUNCTION: acpi_os* print functions
*
* DESCRIPTION: Used for linkage with ACPICA modules
*
******************************************************************************/
void
ACPI_INTERNAL_VAR_XFACE
acpi_os_printf
(
const
char
*
fmt
,
...)
{
va_list
args
;
va_start
(
args
,
fmt
);
vfprintf
(
stdout
,
fmt
,
args
);
va_end
(
args
);
}
void
acpi_os_vprintf
(
const
char
*
fmt
,
va_list
args
)
{
vfprintf
(
stdout
,
fmt
,
args
);
}
tools/power/acpi/tools/acpidump/apfiles.c
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: apfiles - File-related functions for acpidump utility
*
*****************************************************************************/
/*
* 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.
*/
#include "acpidump.h"
#include "acapps.h"
/******************************************************************************
*
* FUNCTION: ap_open_output_file
*
* PARAMETERS: pathname - Output filename
*
* RETURN: Open file handle
*
* DESCRIPTION: Open a text output file for acpidump. Checks if file already
* exists.
*
******************************************************************************/
int
ap_open_output_file
(
char
*
pathname
)
{
struct
stat
stat_info
;
FILE
*
file
;
/* If file exists, prompt for overwrite */
if
(
!
stat
(
pathname
,
&
stat_info
))
{
fprintf
(
stderr
,
"Target path already exists, overwrite? [y|n] "
);
if
(
getchar
()
!=
'y'
)
{
return
(
-
1
);
}
}
/* Point stdout to the file */
file
=
freopen
(
pathname
,
"w"
,
stdout
);
if
(
!
file
)
{
perror
(
"Could not open output file"
);
return
(
-
1
);
}
/* Save the file and path */
gbl_output_file
=
file
;
gbl_output_filename
=
pathname
;
return
(
0
);
}
/******************************************************************************
*
* FUNCTION: ap_write_to_binary_file
*
* PARAMETERS: table - ACPI table to be written
* instance - ACPI table instance no. to be written
*
* RETURN: Status
*
* DESCRIPTION: Write an ACPI table to a binary file. Builds the output
* filename from the table signature.
*
******************************************************************************/
int
ap_write_to_binary_file
(
struct
acpi_table_header
*
table
,
u32
instance
)
{
char
filename
[
ACPI_NAME_SIZE
+
16
];
char
instance_str
[
16
];
FILE
*
file
;
size_t
actual
;
u32
table_length
;
/* Obtain table length */
table_length
=
ap_get_table_length
(
table
);
/* Construct lower-case filename from the table local signature */
if
(
ACPI_VALIDATE_RSDP_SIG
(
table
->
signature
))
{
ACPI_MOVE_NAME
(
filename
,
ACPI_RSDP_NAME
);
}
else
{
ACPI_MOVE_NAME
(
filename
,
table
->
signature
);
}
filename
[
0
]
=
(
char
)
ACPI_TOLOWER
(
filename
[
0
]);
filename
[
1
]
=
(
char
)
ACPI_TOLOWER
(
filename
[
1
]);
filename
[
2
]
=
(
char
)
ACPI_TOLOWER
(
filename
[
2
]);
filename
[
3
]
=
(
char
)
ACPI_TOLOWER
(
filename
[
3
]);
filename
[
ACPI_NAME_SIZE
]
=
0
;
/* Handle multiple SSDts - create different filenames for each */
if
(
instance
>
0
)
{
sprintf
(
instance_str
,
"%u"
,
instance
);
strcat
(
filename
,
instance_str
);
}
strcat
(
filename
,
ACPI_TABLE_FILE_SUFFIX
);
if
(
gbl_verbose_mode
)
{
fprintf
(
stderr
,
"Writing [%4.4s] to binary file: %s 0x%X (%u) bytes
\n
"
,
table
->
signature
,
filename
,
table
->
length
,
table
->
length
);
}
/* Open the file and dump the entire table in binary mode */
file
=
fopen
(
filename
,
"wb"
);
if
(
!
file
)
{
perror
(
"Could not open output file"
);
return
(
-
1
);
}
actual
=
fwrite
(
table
,
1
,
table_length
,
file
);
if
(
actual
!=
table_length
)
{
perror
(
"Error writing binary output file"
);
fclose
(
file
);
return
(
-
1
);
}
fclose
(
file
);
return
(
0
);
}
/******************************************************************************
*
* FUNCTION: ap_get_table_from_file
*
* PARAMETERS: pathname - File containing the binary ACPI table
* out_file_size - Where the file size is returned
*
* RETURN: Buffer containing the ACPI table. NULL on error.
*
* DESCRIPTION: Open a file and read it entirely into a new buffer
*
******************************************************************************/
struct
acpi_table_header
*
ap_get_table_from_file
(
char
*
pathname
,
u32
*
out_file_size
)
{
struct
acpi_table_header
*
buffer
=
NULL
;
FILE
*
file
;
u32
file_size
;
size_t
actual
;
/* Must use binary mode */
file
=
fopen
(
pathname
,
"rb"
);
if
(
!
file
)
{
perror
(
"Could not open input file"
);
return
(
NULL
);
}
/* Need file size to allocate a buffer */
file_size
=
cm_get_file_size
(
file
);
if
(
file_size
==
ACPI_UINT32_MAX
)
{
fprintf
(
stderr
,
"Could not get input file size: %s
\n
"
,
pathname
);
goto
cleanup
;
}
/* Allocate a buffer for the entire file */
buffer
=
calloc
(
1
,
file_size
);
if
(
!
buffer
)
{
fprintf
(
stderr
,
"Could not allocate file buffer of size: %u
\n
"
,
file_size
);
goto
cleanup
;
}
/* Read the entire file */
actual
=
fread
(
buffer
,
1
,
file_size
,
file
);
if
(
actual
!=
file_size
)
{
fprintf
(
stderr
,
"Could not read input file: %s
\n
"
,
pathname
);
free
(
buffer
);
buffer
=
NULL
;
goto
cleanup
;
}
*
out_file_size
=
file_size
;
cleanup:
fclose
(
file
);
return
(
buffer
);
}
tools/power/acpi/tools/acpidump/apmain.c
0 → 100644
View file @
23a75c52
/******************************************************************************
*
* Module Name: apmain - Main module for the acpidump utility
*
*****************************************************************************/
/*
* 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.
*/
#define _DECLARE_GLOBALS
#include "acpidump.h"
#include "acapps.h"
/*
* acpidump - A portable utility for obtaining system ACPI tables and dumping
* them in an ASCII hex format suitable for binary extraction via acpixtract.
*
* Obtaining the system ACPI tables is an OS-specific operation.
*
* This utility can be ported to any host operating system by providing a
* module containing system-specific versions of these interfaces:
*
* acpi_os_get_table_by_address
* acpi_os_get_table_by_index
* acpi_os_get_table_by_name
*
* See the ACPICA Reference Guide for the exact definitions of these
* interfaces. Also, see these ACPICA source code modules for example
* implementations:
*
* source/os_specific/service_layers/oswintbl.c
* source/os_specific/service_layers/oslinuxtbl.c
*/
/* Local prototypes */
static
void
ap_display_usage
(
void
);
static
int
ap_do_options
(
int
argc
,
char
**
argv
);
static
void
ap_insert_action
(
char
*
argument
,
u32
to_be_done
);
/* Table for deferred actions from command line options */
struct
ap_dump_action
action_table
[
AP_MAX_ACTIONS
];
u32
current_action
=
0
;
#define AP_UTILITY_NAME "ACPI Binary Table Dump Utility"
#define AP_SUPPORTED_OPTIONS "?a:bcf:hn:o:r:svz"
/******************************************************************************
*
* FUNCTION: ap_display_usage
*
* DESCRIPTION: Usage message for the acpi_dump utility
*
******************************************************************************/
static
void
ap_display_usage
(
void
)
{
ACPI_USAGE_HEADER
(
"acpidump [options]"
);
ACPI_OPTION
(
"-b"
,
"Dump tables to binary files"
);
ACPI_OPTION
(
"-c"
,
"Dump customized tables"
);
ACPI_OPTION
(
"-h -?"
,
"This help message"
);
ACPI_OPTION
(
"-o <File>"
,
"Redirect output to file"
);
ACPI_OPTION
(
"-r <Address>"
,
"Dump tables from specified RSDP"
);
ACPI_OPTION
(
"-s"
,
"Print table summaries only"
);
ACPI_OPTION
(
"-v"
,
"Display version information"
);
ACPI_OPTION
(
"-z"
,
"Verbose mode"
);
printf
(
"
\n
Table Options:
\n
"
);
ACPI_OPTION
(
"-a <Address>"
,
"Get table via a physical address"
);
ACPI_OPTION
(
"-f <BinaryFile>"
,
"Get table via a binary file"
);
ACPI_OPTION
(
"-n <Signature>"
,
"Get table via a name/signature"
);
printf
(
"
\n
"
"Invocation without parameters dumps all available tables
\n
"
"Multiple mixed instances of -a, -f, and -n are supported
\n\n
"
);
}
/******************************************************************************
*
* FUNCTION: ap_insert_action
*
* PARAMETERS: argument - Pointer to the argument for this action
* to_be_done - What to do to process this action
*
* RETURN: None. Exits program if action table becomes full.
*
* DESCRIPTION: Add an action item to the action table
*
******************************************************************************/
static
void
ap_insert_action
(
char
*
argument
,
u32
to_be_done
)
{
/* Insert action and check for table overflow */
action_table
[
current_action
].
argument
=
argument
;
action_table
[
current_action
].
to_be_done
=
to_be_done
;
current_action
++
;
if
(
current_action
>
AP_MAX_ACTIONS
)
{
fprintf
(
stderr
,
"Too many table options (max %u)
\n
"
,
AP_MAX_ACTIONS
);
exit
(
-
1
);
}
}
/******************************************************************************
*
* FUNCTION: ap_do_options
*
* PARAMETERS: argc/argv - Standard argc/argv
*
* RETURN: Status
*
* DESCRIPTION: Command line option processing. The main actions for getting
* and dumping tables are deferred via the action table.
*
*****************************************************************************/
static
int
ap_do_options
(
int
argc
,
char
**
argv
)
{
int
j
;
acpi_status
status
;
/* Command line options */
while
((
j
=
acpi_getopt
(
argc
,
argv
,
AP_SUPPORTED_OPTIONS
))
!=
EOF
)
switch
(
j
)
{
/*
* Global options
*/
case
'b'
:
/* Dump all input tables to binary files */
gbl_binary_mode
=
TRUE
;
continue
;
case
'c'
:
/* Dump customized tables */
gbl_dump_customized_tables
=
TRUE
;
continue
;
case
'h'
:
case
'?'
:
ap_display_usage
();
exit
(
0
);
case
'o'
:
/* Redirect output to a single file */
if
(
ap_open_output_file
(
acpi_gbl_optarg
))
{
exit
(
-
1
);
}
continue
;
case
'r'
:
/* Dump tables from specified RSDP */
status
=
acpi_ut_strtoul64
(
acpi_gbl_optarg
,
0
,
&
gbl_rsdp_base
);
if
(
ACPI_FAILURE
(
status
))
{
fprintf
(
stderr
,
"%s: Could not convert to a physical address
\n
"
,
acpi_gbl_optarg
);
exit
(
-
1
);
}
continue
;
case
's'
:
/* Print table summaries only */
gbl_summary_mode
=
TRUE
;
continue
;
case
'v'
:
/* Revision/version */
printf
(
ACPI_COMMON_SIGNON
(
AP_UTILITY_NAME
));
exit
(
0
);
case
'z'
:
/* Verbose mode */
gbl_verbose_mode
=
TRUE
;
fprintf
(
stderr
,
ACPI_COMMON_SIGNON
(
AP_UTILITY_NAME
));
continue
;
/*
* Table options
*/
case
'a'
:
/* Get table by physical address */
ap_insert_action
(
acpi_gbl_optarg
,
AP_DUMP_TABLE_BY_ADDRESS
);
break
;
case
'f'
:
/* Get table from a file */
ap_insert_action
(
acpi_gbl_optarg
,
AP_DUMP_TABLE_BY_FILE
);
break
;
case
'n'
:
/* Get table by input name (signature) */
ap_insert_action
(
acpi_gbl_optarg
,
AP_DUMP_TABLE_BY_NAME
);
break
;
default:
ap_display_usage
();
exit
(
-
1
);
}
/* If there are no actions, this means "get/dump all tables" */
if
(
current_action
==
0
)
{
ap_insert_action
(
NULL
,
AP_DUMP_ALL_TABLES
);
}
return
(
0
);
}
/******************************************************************************
*
* FUNCTION: main
*
* PARAMETERS: argc/argv - Standard argc/argv
*
* RETURN: Status
*
* DESCRIPTION: C main function for acpidump utility
*
******************************************************************************/
int
ACPI_SYSTEM_XFACE
main
(
int
argc
,
char
*
argv
[])
{
int
status
=
0
;
struct
ap_dump_action
*
action
;
u32
file_size
;
u32
i
;
ACPI_DEBUG_INITIALIZE
();
/* For debug version only */
/* Process command line options */
if
(
ap_do_options
(
argc
,
argv
))
{
return
(
-
1
);
}
/* Get/dump ACPI table(s) as requested */
for
(
i
=
0
;
i
<
current_action
;
i
++
)
{
action
=
&
action_table
[
i
];
switch
(
action
->
to_be_done
)
{
case
AP_DUMP_ALL_TABLES
:
status
=
ap_dump_all_tables
();
break
;
case
AP_DUMP_TABLE_BY_ADDRESS
:
status
=
ap_dump_table_by_address
(
action
->
argument
);
break
;
case
AP_DUMP_TABLE_BY_NAME
:
status
=
ap_dump_table_by_name
(
action
->
argument
);
break
;
case
AP_DUMP_TABLE_BY_FILE
:
status
=
ap_dump_table_from_file
(
action
->
argument
);
break
;
default:
fprintf
(
stderr
,
"Internal error, invalid action: 0x%X
\n
"
,
action
->
to_be_done
);
return
(
-
1
);
}
if
(
status
)
{
return
(
status
);
}
}
if
(
gbl_output_file
)
{
if
(
gbl_verbose_mode
)
{
/* Summary for the output file */
file_size
=
cm_get_file_size
(
gbl_output_file
);
fprintf
(
stderr
,
"Output file %s contains 0x%X (%u) bytes
\n\n
"
,
gbl_output_filename
,
file_size
,
file_size
);
}
fclose
(
gbl_output_file
);
}
return
(
status
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment