2018-03-15 02:13:07 +03:00
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2015-10-19 05:25:20 +03:00
/*******************************************************************************
*
* Module Name : dbcmds - Miscellaneous debug commands and output routines
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <acpi/acpi.h>
# include "accommon.h"
# include "acevents.h"
# include "acdebug.h"
# include "acnamesp.h"
# include "acresrc.h"
# include "actables.h"
# define _COMPONENT ACPI_CA_DEBUGGER
ACPI_MODULE_NAME ( " dbcmds " )
/* Local prototypes */
static void
acpi_dm_compare_aml_resources ( u8 * aml1_buffer ,
acpi_rsdesc_size aml1_buffer_length ,
u8 * aml2_buffer ,
acpi_rsdesc_size aml2_buffer_length ) ;
static acpi_status
acpi_dm_test_resource_conversion ( struct acpi_namespace_node * node , char * name ) ;
static acpi_status
acpi_db_resource_callback ( struct acpi_resource * resource , void * context ) ;
static acpi_status
acpi_db_device_resources ( acpi_handle obj_handle ,
u32 nesting_level , void * context , void * * return_value ) ;
static void acpi_db_do_one_sleep_state ( u8 sleep_state ) ;
static char * acpi_db_trace_method_name = NULL ;
/*******************************************************************************
*
* FUNCTION : acpi_db_convert_to_node
*
* PARAMETERS : in_string - String to convert
*
* RETURN : Pointer to a NS node
*
* DESCRIPTION : Convert a string to a valid NS pointer . Handles numeric or
* alphanumeric strings .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct acpi_namespace_node * acpi_db_convert_to_node ( char * in_string )
{
struct acpi_namespace_node * node ;
acpi_size address ;
if ( ( * in_string > = 0x30 ) & & ( * in_string < = 0x39 ) ) {
/* Numeric argument, convert */
address = strtoul ( in_string , NULL , 16 ) ;
node = ACPI_TO_POINTER ( address ) ;
if ( ! acpi_os_readable ( node , sizeof ( struct acpi_namespace_node ) ) ) {
acpi_os_printf ( " Address %p is invalid " , node ) ;
return ( NULL ) ;
}
/* Make sure pointer is valid NS node */
if ( ACPI_GET_DESCRIPTOR_TYPE ( node ) ! = ACPI_DESC_TYPE_NAMED ) {
acpi_os_printf
( " Address %p is not a valid namespace node [%s] \n " ,
node , acpi_ut_get_descriptor_name ( node ) ) ;
return ( NULL ) ;
}
} else {
/*
* Alpha argument : The parameter is a name string that must be
* resolved to a Namespace object .
*/
node = acpi_db_local_ns_lookup ( in_string ) ;
if ( ! node ) {
acpi_os_printf
( " Could not find [%s] in namespace, defaulting to root node \n " ,
in_string ) ;
node = acpi_gbl_root_node ;
}
}
return ( node ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_sleep
*
* PARAMETERS : object_arg - Desired sleep state ( 0 - 5 ) . NULL means
* invoke all possible sleep states .
*
* RETURN : Status
*
* DESCRIPTION : Simulate sleep / wake sequences
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status acpi_db_sleep ( char * object_arg )
{
u8 sleep_state ;
u32 i ;
ACPI_FUNCTION_TRACE ( acpi_db_sleep ) ;
/* Null input (no arguments) means to invoke all sleep states */
if ( ! object_arg ) {
acpi_os_printf ( " Invoking all possible sleep states, 0-%d \n " ,
ACPI_S_STATES_MAX ) ;
for ( i = 0 ; i < = ACPI_S_STATES_MAX ; i + + ) {
acpi_db_do_one_sleep_state ( ( u8 ) i ) ;
}
return_ACPI_STATUS ( AE_OK ) ;
}
/* Convert argument to binary and invoke the sleep state */
sleep_state = ( u8 ) strtoul ( object_arg , NULL , 0 ) ;
acpi_db_do_one_sleep_state ( sleep_state ) ;
return_ACPI_STATUS ( AE_OK ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_do_one_sleep_state
*
* PARAMETERS : sleep_state - Desired sleep state ( 0 - 5 )
*
* RETURN : None
*
* DESCRIPTION : Simulate a sleep / wake sequence
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void acpi_db_do_one_sleep_state ( u8 sleep_state )
{
acpi_status status ;
u8 sleep_type_a ;
u8 sleep_type_b ;
/* Validate parameter */
if ( sleep_state > ACPI_S_STATES_MAX ) {
acpi_os_printf ( " Sleep state %d out of range (%d max) \n " ,
sleep_state , ACPI_S_STATES_MAX ) ;
return ;
}
acpi_os_printf ( " \n ---- Invoking sleep state S%d (%s): \n " ,
sleep_state , acpi_gbl_sleep_state_names [ sleep_state ] ) ;
/* Get the values for the sleep type registers (for display only) */
status =
acpi_get_sleep_type_data ( sleep_state , & sleep_type_a , & sleep_type_b ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " Could not evaluate [%s] method, %s \n " ,
acpi_gbl_sleep_state_names [ sleep_state ] ,
acpi_format_exception ( status ) ) ;
return ;
}
acpi_os_printf
( " Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X \n " ,
sleep_state , sleep_type_a , sleep_type_b ) ;
/* Invoke the various sleep/wake interfaces */
acpi_os_printf ( " **** Sleep: Prepare to sleep (S%d) **** \n " ,
sleep_state ) ;
status = acpi_enter_sleep_state_prep ( sleep_state ) ;
if ( ACPI_FAILURE ( status ) ) {
goto error_exit ;
}
acpi_os_printf ( " **** Sleep: Going to sleep (S%d) **** \n " , sleep_state ) ;
status = acpi_enter_sleep_state ( sleep_state ) ;
if ( ACPI_FAILURE ( status ) ) {
goto error_exit ;
}
acpi_os_printf ( " **** Wake: Prepare to return from sleep (S%d) **** \n " ,
sleep_state ) ;
status = acpi_leave_sleep_state_prep ( sleep_state ) ;
if ( ACPI_FAILURE ( status ) ) {
goto error_exit ;
}
acpi_os_printf ( " **** Wake: Return from sleep (S%d) **** \n " ,
sleep_state ) ;
status = acpi_leave_sleep_state ( sleep_state ) ;
if ( ACPI_FAILURE ( status ) ) {
goto error_exit ;
}
return ;
error_exit :
ACPI_EXCEPTION ( ( AE_INFO , status , " During invocation of sleep state S%d " ,
sleep_state ) ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_display_locks
*
* PARAMETERS : None
*
* RETURN : None
*
* DESCRIPTION : Display information about internal mutexes .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_display_locks ( void )
{
u32 i ;
for ( i = 0 ; i < ACPI_MAX_MUTEX ; i + + ) {
acpi_os_printf ( " %26s : %s \n " , acpi_ut_get_mutex_name ( i ) ,
acpi_gbl_mutex_info [ i ] . thread_id = =
ACPI_MUTEX_NOT_ACQUIRED ? " Locked " : " Unlocked " ) ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_display_table_info
*
* PARAMETERS : table_arg - Name of table to be displayed
*
* RETURN : None
*
* DESCRIPTION : Display information about loaded tables . Current
* implementation displays all loaded tables .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_display_table_info ( char * table_arg )
{
u32 i ;
struct acpi_table_desc * table_desc ;
acpi_status status ;
/* Header */
acpi_os_printf ( " Idx ID Status Type "
" TableHeader (Sig, Address, Length, Misc) \n " ) ;
/* Walk the entire root table list */
for ( i = 0 ; i < acpi_gbl_root_table_list . current_table_count ; i + + ) {
table_desc = & acpi_gbl_root_table_list . tables [ i ] ;
/* Index and Table ID */
acpi_os_printf ( " %3u %.2u " , i , table_desc - > owner_id ) ;
/* Decode the table flags */
if ( ! ( table_desc - > flags & ACPI_TABLE_IS_LOADED ) ) {
acpi_os_printf ( " NotLoaded " ) ;
} else {
acpi_os_printf ( " Loaded " ) ;
}
switch ( table_desc - > flags & ACPI_TABLE_ORIGIN_MASK ) {
case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL :
acpi_os_printf ( " External/virtual " ) ;
break ;
case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL :
acpi_os_printf ( " Internal/physical " ) ;
break ;
case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL :
acpi_os_printf ( " Internal/virtual " ) ;
break ;
default :
acpi_os_printf ( " INVALID TYPE " ) ;
break ;
}
/* Make sure that the table is mapped */
status = acpi_tb_validate_table ( table_desc ) ;
if ( ACPI_FAILURE ( status ) ) {
return ;
}
/* Dump the table header */
if ( table_desc - > pointer ) {
acpi_tb_print_table_header ( table_desc - > address ,
table_desc - > pointer ) ;
} else {
/* If the pointer is null, the table has been unloaded */
2016-02-19 09:16:42 +03:00
ACPI_INFO ( ( " %4.4s - Table has been unloaded " ,
2015-10-19 05:25:20 +03:00
table_desc - > signature . ascii ) ) ;
}
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_unload_acpi_table
*
* PARAMETERS : object_name - Namespace pathname for an object that
* is owned by the table to be unloaded
*
* RETURN : None
*
* DESCRIPTION : Unload an ACPI table , via any namespace node that is owned
* by the table .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_unload_acpi_table ( char * object_name )
{
struct acpi_namespace_node * node ;
acpi_status status ;
/* Translate name to an Named object */
node = acpi_db_convert_to_node ( object_name ) ;
if ( ! node ) {
return ;
}
status = acpi_unload_parent_table ( ACPI_CAST_PTR ( acpi_handle , node ) ) ;
if ( ACPI_SUCCESS ( status ) ) {
acpi_os_printf ( " Parent of [%s] (%p) unloaded and uninstalled \n " ,
object_name , node ) ;
} else {
acpi_os_printf ( " %s, while unloading parent table of [%s] \n " ,
acpi_format_exception ( status ) , object_name ) ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_send_notify
*
* PARAMETERS : name - Name of ACPI object where to send notify
* value - Value of the notify to send .
*
* RETURN : None
*
* DESCRIPTION : Send an ACPI notification . The value specified is sent to the
* named object as an ACPI notify .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_send_notify ( char * name , u32 value )
{
struct acpi_namespace_node * node ;
acpi_status status ;
/* Translate name to an Named object */
node = acpi_db_convert_to_node ( name ) ;
if ( ! node ) {
return ;
}
/* Dispatch the notify if legal */
if ( acpi_ev_is_notify_object ( node ) ) {
status = acpi_ev_queue_notify_request ( node , value ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " Could not queue notify \n " ) ;
}
} else {
acpi_os_printf ( " Named object [%4.4s] Type %s, "
" must be Device/Thermal/Processor type \n " ,
acpi_ut_get_node_name ( node ) ,
acpi_ut_get_type_name ( node - > type ) ) ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_display_interfaces
*
* PARAMETERS : action_arg - Null , " install " , or " remove "
* interface_name_arg - Name for install / remove options
*
* RETURN : None
*
* DESCRIPTION : Display or modify the global _OSI interface list
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_display_interfaces ( char * action_arg , char * interface_name_arg )
{
struct acpi_interface_info * next_interface ;
char * sub_string ;
acpi_status status ;
/* If no arguments, just display current interface list */
if ( ! action_arg ) {
( void ) acpi_os_acquire_mutex ( acpi_gbl_osi_mutex ,
ACPI_WAIT_FOREVER ) ;
next_interface = acpi_gbl_supported_interfaces ;
while ( next_interface ) {
if ( ! ( next_interface - > flags & ACPI_OSI_INVALID ) ) {
acpi_os_printf ( " %s \n " , next_interface - > name ) ;
}
next_interface = next_interface - > next ;
}
acpi_os_release_mutex ( acpi_gbl_osi_mutex ) ;
return ;
}
/* If action_arg exists, so must interface_name_arg */
if ( ! interface_name_arg ) {
acpi_os_printf ( " Missing Interface Name argument \n " ) ;
return ;
}
/* Uppercase the action for match below */
acpi_ut_strupr ( action_arg ) ;
/* install - install an interface */
sub_string = strstr ( " INSTALL " , action_arg ) ;
if ( sub_string ) {
status = acpi_install_interface ( interface_name_arg ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " %s, while installing \" %s \" \n " ,
acpi_format_exception ( status ) ,
interface_name_arg ) ;
}
return ;
}
/* remove - remove an interface */
sub_string = strstr ( " REMOVE " , action_arg ) ;
if ( sub_string ) {
status = acpi_remove_interface ( interface_name_arg ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " %s, while removing \" %s \" \n " ,
acpi_format_exception ( status ) ,
interface_name_arg ) ;
}
return ;
}
/* Invalid action_arg */
acpi_os_printf ( " Invalid action argument: %s \n " , action_arg ) ;
return ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_display_template
*
* PARAMETERS : buffer_arg - Buffer name or address
*
* RETURN : None
*
* DESCRIPTION : Dump a buffer that contains a resource template
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_display_template ( char * buffer_arg )
{
struct acpi_namespace_node * node ;
acpi_status status ;
struct acpi_buffer return_buffer ;
/* Translate buffer_arg to an Named object */
node = acpi_db_convert_to_node ( buffer_arg ) ;
if ( ! node | | ( node = = acpi_gbl_root_node ) ) {
acpi_os_printf ( " Invalid argument: %s \n " , buffer_arg ) ;
return ;
}
/* We must have a buffer object */
if ( node - > type ! = ACPI_TYPE_BUFFER ) {
acpi_os_printf
( " Not a Buffer object, cannot be a template: %s \n " ,
buffer_arg ) ;
return ;
}
return_buffer . length = ACPI_DEBUG_BUFFER_SIZE ;
return_buffer . pointer = acpi_gbl_db_buffer ;
/* Attempt to convert the raw buffer to a resource list */
status = acpi_rs_create_resource_list ( node - > object , & return_buffer ) ;
acpi_db_set_output_destination ( ACPI_DB_REDIRECTABLE_OUTPUT ) ;
acpi_dbg_level | = ACPI_LV_RESOURCES ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf
( " Could not convert Buffer to a resource list: %s, %s \n " ,
buffer_arg , acpi_format_exception ( status ) ) ;
goto dump_buffer ;
}
/* Now we can dump the resource list */
acpi_rs_dump_resource_list ( ACPI_CAST_PTR ( struct acpi_resource ,
return_buffer . pointer ) ) ;
dump_buffer :
acpi_os_printf ( " \n Raw data buffer: \n " ) ;
acpi_ut_debug_dump_buffer ( ( u8 * ) node - > object - > buffer . pointer ,
node - > object - > buffer . length ,
DB_BYTE_DISPLAY , ACPI_UINT32_MAX ) ;
acpi_db_set_output_destination ( ACPI_DB_CONSOLE_OUTPUT ) ;
return ;
}
/*******************************************************************************
*
* FUNCTION : acpi_dm_compare_aml_resources
*
* PARAMETERS : aml1_buffer - Contains first resource list
* aml1_buffer_length - Length of first resource list
* aml2_buffer - Contains second resource list
* aml2_buffer_length - Length of second resource list
*
* RETURN : None
*
* DESCRIPTION : Compare two AML resource lists , descriptor by descriptor ( in
* order to isolate a miscompare to an individual resource )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void
acpi_dm_compare_aml_resources ( u8 * aml1_buffer ,
acpi_rsdesc_size aml1_buffer_length ,
u8 * aml2_buffer ,
acpi_rsdesc_size aml2_buffer_length )
{
u8 * aml1 ;
u8 * aml2 ;
u8 * aml1_end ;
u8 * aml2_end ;
acpi_rsdesc_size aml1_length ;
acpi_rsdesc_size aml2_length ;
acpi_rsdesc_size offset = 0 ;
u8 resource_type ;
u32 count = 0 ;
u32 i ;
/* Compare overall buffer sizes (may be different due to size rounding) */
if ( aml1_buffer_length ! = aml2_buffer_length ) {
acpi_os_printf ( " **** Buffer length mismatch in converted "
" AML: Original %X, New %X **** \n " ,
aml1_buffer_length , aml2_buffer_length ) ;
}
aml1 = aml1_buffer ;
aml2 = aml2_buffer ;
aml1_end = aml1_buffer + aml1_buffer_length ;
aml2_end = aml2_buffer + aml2_buffer_length ;
/* Walk the descriptor lists, comparing each descriptor */
while ( ( aml1 < aml1_end ) & & ( aml2 < aml2_end ) ) {
/* Get the lengths of each descriptor */
aml1_length = acpi_ut_get_descriptor_length ( aml1 ) ;
aml2_length = acpi_ut_get_descriptor_length ( aml2 ) ;
resource_type = acpi_ut_get_resource_type ( aml1 ) ;
/* Check for descriptor length match */
if ( aml1_length ! = aml2_length ) {
acpi_os_printf
( " **** Length mismatch in descriptor [%.2X] type %2.2X, "
" Offset %8.8X Len1 %X, Len2 %X **** \n " , count ,
resource_type , offset , aml1_length , aml2_length ) ;
}
/* Check for descriptor byte match */
else if ( memcmp ( aml1 , aml2 , aml1_length ) ) {
acpi_os_printf
( " **** Data mismatch in descriptor [%.2X] type %2.2X, "
" Offset %8.8X **** \n " , count , resource_type ,
offset ) ;
for ( i = 0 ; i < aml1_length ; i + + ) {
if ( aml1 [ i ] ! = aml2 [ i ] ) {
acpi_os_printf
( " Mismatch at byte offset %.2X: is %2.2X, "
" should be %2.2X \n " , i , aml2 [ i ] ,
aml1 [ i ] ) ;
}
}
}
/* Exit on end_tag descriptor */
if ( resource_type = = ACPI_RESOURCE_NAME_END_TAG ) {
return ;
}
/* Point to next descriptor in each buffer */
count + + ;
offset + = aml1_length ;
aml1 + = aml1_length ;
aml2 + = aml2_length ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_dm_test_resource_conversion
*
* PARAMETERS : node - Parent device node
* name - resource method name ( _CRS )
*
* RETURN : Status
*
* DESCRIPTION : Compare the original AML with a conversion of the AML to
* internal resource list , then back to AML .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static acpi_status
acpi_dm_test_resource_conversion ( struct acpi_namespace_node * node , char * name )
{
acpi_status status ;
struct acpi_buffer return_buffer ;
struct acpi_buffer resource_buffer ;
struct acpi_buffer new_aml ;
union acpi_object * original_aml ;
acpi_os_printf ( " Resource Conversion Comparison: \n " ) ;
new_aml . length = ACPI_ALLOCATE_LOCAL_BUFFER ;
return_buffer . length = ACPI_ALLOCATE_LOCAL_BUFFER ;
resource_buffer . length = ACPI_ALLOCATE_LOCAL_BUFFER ;
/* Get the original _CRS AML resource template */
status = acpi_evaluate_object ( node , name , NULL , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " Could not obtain %s: %s \n " ,
name , acpi_format_exception ( status ) ) ;
return ( status ) ;
}
/* Get the AML resource template, converted to internal resource structs */
status = acpi_get_current_resources ( node , & resource_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " AcpiGetCurrentResources failed: %s \n " ,
acpi_format_exception ( status ) ) ;
goto exit1 ;
}
/* Convert internal resource list to external AML resource template */
status = acpi_rs_create_aml_resources ( & resource_buffer , & new_aml ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " AcpiRsCreateAmlResources failed: %s \n " ,
acpi_format_exception ( status ) ) ;
goto exit2 ;
}
/* Compare original AML to the newly created AML resource list */
original_aml = return_buffer . pointer ;
acpi_dm_compare_aml_resources ( original_aml - > buffer . pointer ,
2016-05-05 07:57:53 +03:00
( acpi_rsdesc_size ) original_aml - > buffer .
2015-10-19 05:25:20 +03:00
length , new_aml . pointer ,
2016-05-05 07:57:53 +03:00
( acpi_rsdesc_size ) new_aml . length ) ;
2015-10-19 05:25:20 +03:00
/* Cleanup and exit */
ACPI_FREE ( new_aml . pointer ) ;
exit2 :
ACPI_FREE ( resource_buffer . pointer ) ;
exit1 :
ACPI_FREE ( return_buffer . pointer ) ;
return ( status ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_resource_callback
*
* PARAMETERS : acpi_walk_resource_callback
*
* RETURN : Status
*
* DESCRIPTION : Simple callback to exercise acpi_walk_resources and
* acpi_walk_resource_buffer .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static acpi_status
acpi_db_resource_callback ( struct acpi_resource * resource , void * context )
{
return ( AE_OK ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_device_resources
*
* PARAMETERS : acpi_walk_callback
*
* RETURN : Status
*
* DESCRIPTION : Display the _PRT / _CRS / _PRS resources for a device object .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static acpi_status
acpi_db_device_resources ( acpi_handle obj_handle ,
u32 nesting_level , void * context , void * * return_value )
{
struct acpi_namespace_node * node ;
struct acpi_namespace_node * prt_node = NULL ;
struct acpi_namespace_node * crs_node = NULL ;
struct acpi_namespace_node * prs_node = NULL ;
struct acpi_namespace_node * aei_node = NULL ;
char * parent_path ;
struct acpi_buffer return_buffer ;
acpi_status status ;
node = ACPI_CAST_PTR ( struct acpi_namespace_node , obj_handle ) ;
2015-12-29 08:53:50 +03:00
parent_path = acpi_ns_get_normalized_pathname ( node , TRUE ) ;
2015-10-19 05:25:20 +03:00
if ( ! parent_path ) {
return ( AE_NO_MEMORY ) ;
}
/* Get handles to the resource methods for this device */
( void ) acpi_get_handle ( node , METHOD_NAME__PRT ,
ACPI_CAST_PTR ( acpi_handle , & prt_node ) ) ;
( void ) acpi_get_handle ( node , METHOD_NAME__CRS ,
ACPI_CAST_PTR ( acpi_handle , & crs_node ) ) ;
( void ) acpi_get_handle ( node , METHOD_NAME__PRS ,
ACPI_CAST_PTR ( acpi_handle , & prs_node ) ) ;
( void ) acpi_get_handle ( node , METHOD_NAME__AEI ,
ACPI_CAST_PTR ( acpi_handle , & aei_node ) ) ;
if ( ! prt_node & & ! crs_node & & ! prs_node & & ! aei_node ) {
goto cleanup ; /* Nothing to do */
}
acpi_os_printf ( " \n Device: %s \n " , parent_path ) ;
/* Prepare for a return object of arbitrary size */
return_buffer . pointer = acpi_gbl_db_buffer ;
return_buffer . length = ACPI_DEBUG_BUFFER_SIZE ;
/* _PRT */
if ( prt_node ) {
acpi_os_printf ( " Evaluating _PRT \n " ) ;
status =
acpi_evaluate_object ( prt_node , NULL , NULL , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " Could not evaluate _PRT: %s \n " ,
acpi_format_exception ( status ) ) ;
goto get_crs ;
}
return_buffer . pointer = acpi_gbl_db_buffer ;
return_buffer . length = ACPI_DEBUG_BUFFER_SIZE ;
status = acpi_get_irq_routing_table ( node , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " GetIrqRoutingTable failed: %s \n " ,
acpi_format_exception ( status ) ) ;
goto get_crs ;
}
acpi_rs_dump_irq_list ( ACPI_CAST_PTR ( u8 , acpi_gbl_db_buffer ) ) ;
}
/* _CRS */
get_crs :
if ( crs_node ) {
acpi_os_printf ( " Evaluating _CRS \n " ) ;
return_buffer . pointer = acpi_gbl_db_buffer ;
return_buffer . length = ACPI_DEBUG_BUFFER_SIZE ;
status =
acpi_evaluate_object ( crs_node , NULL , NULL , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " Could not evaluate _CRS: %s \n " ,
acpi_format_exception ( status ) ) ;
goto get_prs ;
}
/* This code exercises the acpi_walk_resources interface */
status = acpi_walk_resources ( node , METHOD_NAME__CRS ,
acpi_db_resource_callback , NULL ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " AcpiWalkResources failed: %s \n " ,
acpi_format_exception ( status ) ) ;
goto get_prs ;
}
/* Get the _CRS resource list (test ALLOCATE buffer) */
return_buffer . pointer = NULL ;
return_buffer . length = ACPI_ALLOCATE_LOCAL_BUFFER ;
status = acpi_get_current_resources ( node , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " AcpiGetCurrentResources failed: %s \n " ,
acpi_format_exception ( status ) ) ;
goto get_prs ;
}
/* This code exercises the acpi_walk_resource_buffer interface */
status = acpi_walk_resource_buffer ( & return_buffer ,
acpi_db_resource_callback ,
NULL ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " AcpiWalkResourceBuffer failed: %s \n " ,
acpi_format_exception ( status ) ) ;
goto end_crs ;
}
/* Dump the _CRS resource list */
acpi_rs_dump_resource_list ( ACPI_CAST_PTR ( struct acpi_resource ,
return_buffer .
pointer ) ) ;
/*
* Perform comparison of original AML to newly created AML . This
* tests both the AML - > Resource conversion and the Resource - > AML
* conversion .
*/
( void ) acpi_dm_test_resource_conversion ( node , METHOD_NAME__CRS ) ;
/* Execute _SRS with the resource list */
acpi_os_printf ( " Evaluating _SRS \n " ) ;
status = acpi_set_current_resources ( node , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " AcpiSetCurrentResources failed: %s \n " ,
acpi_format_exception ( status ) ) ;
goto end_crs ;
}
end_crs :
ACPI_FREE ( return_buffer . pointer ) ;
}
/* _PRS */
get_prs :
if ( prs_node ) {
acpi_os_printf ( " Evaluating _PRS \n " ) ;
return_buffer . pointer = acpi_gbl_db_buffer ;
return_buffer . length = ACPI_DEBUG_BUFFER_SIZE ;
status =
acpi_evaluate_object ( prs_node , NULL , NULL , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " Could not evaluate _PRS: %s \n " ,
acpi_format_exception ( status ) ) ;
goto get_aei ;
}
return_buffer . pointer = acpi_gbl_db_buffer ;
return_buffer . length = ACPI_DEBUG_BUFFER_SIZE ;
status = acpi_get_possible_resources ( node , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " AcpiGetPossibleResources failed: %s \n " ,
acpi_format_exception ( status ) ) ;
goto get_aei ;
}
acpi_rs_dump_resource_list ( ACPI_CAST_PTR
( struct acpi_resource ,
acpi_gbl_db_buffer ) ) ;
}
/* _AEI */
get_aei :
if ( aei_node ) {
acpi_os_printf ( " Evaluating _AEI \n " ) ;
return_buffer . pointer = acpi_gbl_db_buffer ;
return_buffer . length = ACPI_DEBUG_BUFFER_SIZE ;
status =
acpi_evaluate_object ( aei_node , NULL , NULL , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " Could not evaluate _AEI: %s \n " ,
acpi_format_exception ( status ) ) ;
goto cleanup ;
}
return_buffer . pointer = acpi_gbl_db_buffer ;
return_buffer . length = ACPI_DEBUG_BUFFER_SIZE ;
status = acpi_get_event_resources ( node , & return_buffer ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " AcpiGetEventResources failed: %s \n " ,
acpi_format_exception ( status ) ) ;
goto cleanup ;
}
acpi_rs_dump_resource_list ( ACPI_CAST_PTR
( struct acpi_resource ,
acpi_gbl_db_buffer ) ) ;
}
cleanup :
ACPI_FREE ( parent_path ) ;
return ( AE_OK ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_display_resources
*
* PARAMETERS : object_arg - String object name or object pointer .
* NULL or " * " means " display resources for
* all devices "
*
* RETURN : None
*
* DESCRIPTION : Display the resource objects associated with a device .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_display_resources ( char * object_arg )
{
struct acpi_namespace_node * node ;
acpi_db_set_output_destination ( ACPI_DB_REDIRECTABLE_OUTPUT ) ;
acpi_dbg_level | = ACPI_LV_RESOURCES ;
/* Asterisk means "display resources for all devices" */
if ( ! object_arg | | ( ! strcmp ( object_arg , " * " ) ) ) {
( void ) acpi_walk_namespace ( ACPI_TYPE_DEVICE , ACPI_ROOT_OBJECT ,
ACPI_UINT32_MAX ,
acpi_db_device_resources , NULL , NULL ,
NULL ) ;
} else {
/* Convert string to object pointer */
node = acpi_db_convert_to_node ( object_arg ) ;
if ( node ) {
if ( node - > type ! = ACPI_TYPE_DEVICE ) {
acpi_os_printf
( " %4.4s: Name is not a device object (%s) \n " ,
node - > name . ascii ,
acpi_ut_get_type_name ( node - > type ) ) ;
} else {
( void ) acpi_db_device_resources ( node , 0 , NULL ,
NULL ) ;
}
}
}
acpi_db_set_output_destination ( ACPI_DB_CONSOLE_OUTPUT ) ;
}
# if (!ACPI_REDUCED_HARDWARE)
/*******************************************************************************
*
* FUNCTION : acpi_db_generate_gpe
*
* PARAMETERS : gpe_arg - Raw GPE number , ascii string
* block_arg - GPE block number , ascii string
* 0 or 1 for FADT GPE blocks
*
* RETURN : None
*
* DESCRIPTION : Simulate firing of a GPE
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_generate_gpe ( char * gpe_arg , char * block_arg )
{
u32 block_number = 0 ;
u32 gpe_number ;
struct acpi_gpe_event_info * gpe_event_info ;
gpe_number = strtoul ( gpe_arg , NULL , 0 ) ;
/*
* If no block arg , or block arg = = 0 or 1 , use the FADT - defined
* GPE blocks .
*/
if ( block_arg ) {
block_number = strtoul ( block_arg , NULL , 0 ) ;
if ( block_number = = 1 ) {
block_number = 0 ;
}
}
gpe_event_info =
acpi_ev_get_gpe_event_info ( ACPI_TO_POINTER ( block_number ) ,
gpe_number ) ;
if ( ! gpe_event_info ) {
acpi_os_printf ( " Invalid GPE \n " ) ;
return ;
}
( void ) acpi_ev_gpe_dispatch ( NULL , gpe_event_info , gpe_number ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_generate_sci
*
* PARAMETERS : None
*
* RETURN : None
*
* DESCRIPTION : Simulate an SCI - - just call the SCI dispatch .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_generate_sci ( void )
{
acpi_ev_sci_dispatch ( ) ;
}
# endif /* !ACPI_REDUCED_HARDWARE */
/*******************************************************************************
*
* FUNCTION : acpi_db_trace
*
* PARAMETERS : enable_arg - ENABLE / AML to enable tracer
* DISABLE to disable tracer
* method_arg - Method to trace
* once_arg - Whether trace once
*
* RETURN : None
*
* DESCRIPTION : Control method tracing facility
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_trace ( char * enable_arg , char * method_arg , char * once_arg )
{
u32 debug_level = 0 ;
u32 debug_layer = 0 ;
u32 flags = 0 ;
2015-12-29 08:55:27 +03:00
acpi_ut_strupr ( enable_arg ) ;
acpi_ut_strupr ( once_arg ) ;
2015-10-19 05:25:20 +03:00
if ( method_arg ) {
if ( acpi_db_trace_method_name ) {
ACPI_FREE ( acpi_db_trace_method_name ) ;
acpi_db_trace_method_name = NULL ;
}
acpi_db_trace_method_name =
ACPI_ALLOCATE ( strlen ( method_arg ) + 1 ) ;
if ( ! acpi_db_trace_method_name ) {
acpi_os_printf ( " Failed to allocate method name (%s) \n " ,
method_arg ) ;
return ;
}
strcpy ( acpi_db_trace_method_name , method_arg ) ;
}
if ( ! strcmp ( enable_arg , " ENABLE " ) | |
! strcmp ( enable_arg , " METHOD " ) | | ! strcmp ( enable_arg , " OPCODE " ) ) {
if ( ! strcmp ( enable_arg , " ENABLE " ) ) {
/* Inherit current console settings */
debug_level = acpi_gbl_db_console_debug_level ;
debug_layer = acpi_dbg_layer ;
} else {
/* Restrict console output to trace points only */
debug_level = ACPI_LV_TRACE_POINT ;
debug_layer = ACPI_EXECUTER ;
}
flags = ACPI_TRACE_ENABLED ;
if ( ! strcmp ( enable_arg , " OPCODE " ) ) {
flags | = ACPI_TRACE_OPCODE ;
}
if ( once_arg & & ! strcmp ( once_arg , " ONCE " ) ) {
flags | = ACPI_TRACE_ONESHOT ;
}
}
( void ) acpi_debug_trace ( acpi_db_trace_method_name ,
debug_level , debug_layer , flags ) ;
}