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 : dbobject - ACPI object decode and display
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <acpi/acpi.h>
# include "accommon.h"
# include "acnamesp.h"
# include "acdebug.h"
# define _COMPONENT ACPI_CA_DEBUGGER
ACPI_MODULE_NAME ( " dbobject " )
/* Local prototypes */
static void acpi_db_decode_node ( struct acpi_namespace_node * node ) ;
/*******************************************************************************
*
* FUNCTION : acpi_db_dump_method_info
*
* PARAMETERS : status - Method execution status
* walk_state - Current state of the parse tree walk
*
* RETURN : None
*
* DESCRIPTION : Called when a method has been aborted because of an error .
* Dumps the method execution stack , and the method locals / args ,
* and disassembles the AML opcode that failed .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
acpi_db_dump_method_info ( acpi_status status , struct acpi_walk_state * walk_state )
{
struct acpi_thread_state * thread ;
2018-06-01 22:06:42 +03:00
struct acpi_namespace_node * node ;
node = walk_state - > method_node ;
/* There are no locals or arguments for the module-level code case */
if ( node = = acpi_gbl_root_node ) {
return ;
}
2015-10-19 05:25:20 +03:00
/* Ignore control codes, they are not errors */
2021-01-15 21:48:19 +03:00
if ( ACPI_CNTL_EXCEPTION ( status ) ) {
2015-10-19 05:25:20 +03:00
return ;
}
/* We may be executing a deferred opcode */
if ( walk_state - > deferred_node ) {
acpi_os_printf ( " Executing subtree for Buffer/Package/Region \n " ) ;
return ;
}
/*
* If there is no Thread , we are not actually executing a method .
* This can happen when the iASL compiler calls the interpreter
* to perform constant folding .
*/
thread = walk_state - > thread ;
if ( ! thread ) {
return ;
}
/* Display the method locals and arguments */
acpi_os_printf ( " \n " ) ;
acpi_db_decode_locals ( walk_state ) ;
acpi_os_printf ( " \n " ) ;
acpi_db_decode_arguments ( walk_state ) ;
acpi_os_printf ( " \n " ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_decode_internal_object
*
* PARAMETERS : obj_desc - Object to be displayed
*
* RETURN : None
*
* DESCRIPTION : Short display of an internal object . Numbers / Strings / Buffers .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_decode_internal_object ( union acpi_operand_object * obj_desc )
{
u32 i ;
if ( ! obj_desc ) {
acpi_os_printf ( " Uninitialized " ) ;
return ;
}
if ( ACPI_GET_DESCRIPTOR_TYPE ( obj_desc ) ! = ACPI_DESC_TYPE_OPERAND ) {
acpi_os_printf ( " %p [%s] " , obj_desc ,
acpi_ut_get_descriptor_name ( obj_desc ) ) ;
return ;
}
acpi_os_printf ( " %s " , acpi_ut_get_object_type_name ( obj_desc ) ) ;
switch ( obj_desc - > common . type ) {
case ACPI_TYPE_INTEGER :
acpi_os_printf ( " %8.8X%8.8X " ,
ACPI_FORMAT_UINT64 ( obj_desc - > integer . value ) ) ;
break ;
case ACPI_TYPE_STRING :
2016-08-04 11:42:55 +03:00
acpi_os_printf ( " (%u) \" %.60s " ,
2015-10-19 05:25:20 +03:00
obj_desc - > string . length ,
obj_desc - > string . pointer ) ;
2016-08-04 11:42:55 +03:00
if ( obj_desc - > string . length > 60 ) {
2015-10-19 05:25:20 +03:00
acpi_os_printf ( " ... " ) ;
} else {
acpi_os_printf ( " \" " ) ;
}
break ;
case ACPI_TYPE_BUFFER :
acpi_os_printf ( " (%u) " , obj_desc - > buffer . length ) ;
for ( i = 0 ; ( i < 8 ) & & ( i < obj_desc - > buffer . length ) ; i + + ) {
acpi_os_printf ( " %2.2X " , obj_desc - > buffer . pointer [ i ] ) ;
}
break ;
default :
acpi_os_printf ( " %p " , obj_desc ) ;
break ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_decode_node
*
* PARAMETERS : node - Object to be displayed
*
* RETURN : None
*
* DESCRIPTION : Short display of a namespace node
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void acpi_db_decode_node ( struct acpi_namespace_node * node )
{
acpi_os_printf ( " <Node> Name %4.4s " ,
acpi_ut_get_node_name ( node ) ) ;
if ( node - > flags & ANOBJ_METHOD_ARG ) {
acpi_os_printf ( " [Method Arg] " ) ;
}
if ( node - > flags & ANOBJ_METHOD_LOCAL ) {
acpi_os_printf ( " [Method Local] " ) ;
}
switch ( node - > type ) {
/* These types have no attached object */
case ACPI_TYPE_DEVICE :
acpi_os_printf ( " Device " ) ;
break ;
case ACPI_TYPE_THERMAL :
acpi_os_printf ( " Thermal Zone " ) ;
break ;
default :
acpi_db_decode_internal_object ( acpi_ns_get_attached_object
( node ) ) ;
break ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_display_internal_object
*
* PARAMETERS : obj_desc - Object to be displayed
* walk_state - Current walk state
*
* RETURN : None
*
* DESCRIPTION : Short display of an internal object
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
acpi_db_display_internal_object ( union acpi_operand_object * obj_desc ,
struct acpi_walk_state * walk_state )
{
u8 type ;
acpi_os_printf ( " %p " , obj_desc ) ;
if ( ! obj_desc ) {
acpi_os_printf ( " <Null Object> \n " ) ;
return ;
}
/* Decode the object type */
switch ( ACPI_GET_DESCRIPTOR_TYPE ( obj_desc ) ) {
case ACPI_DESC_TYPE_PARSER :
acpi_os_printf ( " <Parser> " ) ;
break ;
case ACPI_DESC_TYPE_NAMED :
acpi_db_decode_node ( ( struct acpi_namespace_node * ) obj_desc ) ;
break ;
case ACPI_DESC_TYPE_OPERAND :
type = obj_desc - > common . type ;
if ( type > ACPI_TYPE_LOCAL_MAX ) {
acpi_os_printf ( " Type %X [Invalid Type] " , ( u32 ) type ) ;
return ;
}
/* Decode the ACPI object type */
switch ( obj_desc - > common . type ) {
case ACPI_TYPE_LOCAL_REFERENCE :
acpi_os_printf ( " [%s] " ,
acpi_ut_get_reference_name ( obj_desc ) ) ;
2019-02-16 00:36:19 +03:00
/* Decode the reference */
2015-10-19 05:25:20 +03:00
switch ( obj_desc - > reference . class ) {
case ACPI_REFCLASS_LOCAL :
acpi_os_printf ( " %X " ,
obj_desc - > reference . value ) ;
if ( walk_state ) {
obj_desc = walk_state - > local_variables
[ obj_desc - > reference . value ] . object ;
acpi_os_printf ( " %p " , obj_desc ) ;
acpi_db_decode_internal_object
( obj_desc ) ;
}
break ;
case ACPI_REFCLASS_ARG :
acpi_os_printf ( " %X " ,
obj_desc - > reference . value ) ;
if ( walk_state ) {
obj_desc = walk_state - > arguments
[ obj_desc - > reference . value ] . object ;
acpi_os_printf ( " %p " , obj_desc ) ;
acpi_db_decode_internal_object
( obj_desc ) ;
}
break ;
case ACPI_REFCLASS_INDEX :
switch ( obj_desc - > reference . target_type ) {
case ACPI_TYPE_BUFFER_FIELD :
acpi_os_printf ( " %p " ,
obj_desc - > reference .
object ) ;
acpi_db_decode_internal_object
( obj_desc - > reference . object ) ;
break ;
case ACPI_TYPE_PACKAGE :
acpi_os_printf ( " %p " ,
obj_desc - > reference .
where ) ;
if ( ! obj_desc - > reference . where ) {
acpi_os_printf
( " Uninitialized WHERE pointer " ) ;
} else {
acpi_db_decode_internal_object ( *
( obj_desc - >
reference .
where ) ) ;
}
break ;
default :
acpi_os_printf
( " Unknown index target type " ) ;
break ;
}
break ;
case ACPI_REFCLASS_REFOF :
if ( ! obj_desc - > reference . object ) {
acpi_os_printf
( " Uninitialized reference subobject pointer " ) ;
break ;
}
/* Reference can be to a Node or an Operand object */
switch ( ACPI_GET_DESCRIPTOR_TYPE
( obj_desc - > reference . object ) ) {
case ACPI_DESC_TYPE_NAMED :
acpi_db_decode_node ( obj_desc - > reference .
object ) ;
break ;
case ACPI_DESC_TYPE_OPERAND :
acpi_db_decode_internal_object
( obj_desc - > reference . object ) ;
break ;
default :
break ;
}
break ;
case ACPI_REFCLASS_NAME :
acpi_db_decode_node ( obj_desc - > reference . node ) ;
break ;
case ACPI_REFCLASS_DEBUG :
case ACPI_REFCLASS_TABLE :
acpi_os_printf ( " \n " ) ;
break ;
default : /* Unknown reference class */
acpi_os_printf ( " %2.2X \n " ,
obj_desc - > reference . class ) ;
break ;
}
break ;
default :
acpi_os_printf ( " <Obj> " ) ;
acpi_db_decode_internal_object ( obj_desc ) ;
break ;
}
break ;
default :
acpi_os_printf ( " <Not a valid ACPI Object Descriptor> [%s] " ,
acpi_ut_get_descriptor_name ( obj_desc ) ) ;
break ;
}
acpi_os_printf ( " \n " ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_decode_locals
*
* PARAMETERS : walk_state - State for current method
*
* RETURN : None
*
* DESCRIPTION : Display all locals for the currently running control method
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_decode_locals ( struct acpi_walk_state * walk_state )
{
u32 i ;
union acpi_operand_object * obj_desc ;
struct acpi_namespace_node * node ;
u8 display_locals = FALSE ;
node = walk_state - > method_node ;
2018-06-01 22:06:42 +03:00
/* There are no locals for the module-level code case */
if ( node = = acpi_gbl_root_node ) {
return ;
}
2015-10-19 05:25:20 +03:00
if ( ! node ) {
acpi_os_printf
( " No method node (Executing subtree for buffer or opregion) \n " ) ;
return ;
}
if ( node - > type ! = ACPI_TYPE_METHOD ) {
acpi_os_printf ( " Executing subtree for Buffer/Package/Region \n " ) ;
return ;
}
/* Are any locals actually set? */
for ( i = 0 ; i < ACPI_METHOD_NUM_LOCALS ; i + + ) {
obj_desc = walk_state - > local_variables [ i ] . object ;
if ( obj_desc ) {
display_locals = TRUE ;
break ;
}
}
/* If any are set, only display the ones that are set */
if ( display_locals ) {
acpi_os_printf
2017-06-05 11:40:21 +03:00
( " \n Initialized Local Variables for Method [%4.4s]: \n " ,
2015-10-19 05:25:20 +03:00
acpi_ut_get_node_name ( node ) ) ;
for ( i = 0 ; i < ACPI_METHOD_NUM_LOCALS ; i + + ) {
obj_desc = walk_state - > local_variables [ i ] . object ;
if ( obj_desc ) {
acpi_os_printf ( " Local%X: " , i ) ;
acpi_db_display_internal_object ( obj_desc ,
walk_state ) ;
}
}
} else {
acpi_os_printf
2017-06-05 11:40:21 +03:00
( " No Local Variables are initialized for Method [%4.4s] \n " ,
2015-10-19 05:25:20 +03:00
acpi_ut_get_node_name ( node ) ) ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_decode_arguments
*
* PARAMETERS : walk_state - State for current method
*
* RETURN : None
*
* DESCRIPTION : Display all arguments for the currently running control method
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_decode_arguments ( struct acpi_walk_state * walk_state )
{
u32 i ;
union acpi_operand_object * obj_desc ;
struct acpi_namespace_node * node ;
u8 display_args = FALSE ;
node = walk_state - > method_node ;
2018-06-01 22:06:42 +03:00
/* There are no arguments for the module-level code case */
if ( node = = acpi_gbl_root_node ) {
return ;
}
2015-10-19 05:25:20 +03:00
if ( ! node ) {
acpi_os_printf
( " No method node (Executing subtree for buffer or opregion) \n " ) ;
return ;
}
if ( node - > type ! = ACPI_TYPE_METHOD ) {
acpi_os_printf ( " Executing subtree for Buffer/Package/Region \n " ) ;
return ;
}
/* Are any arguments actually set? */
for ( i = 0 ; i < ACPI_METHOD_NUM_ARGS ; i + + ) {
obj_desc = walk_state - > arguments [ i ] . object ;
if ( obj_desc ) {
display_args = TRUE ;
break ;
}
}
/* If any are set, only display the ones that are set */
if ( display_args ) {
acpi_os_printf ( " Initialized Arguments for Method [%4.4s]: "
" (%X arguments defined for method invocation) \n " ,
acpi_ut_get_node_name ( node ) ,
2017-06-05 11:40:21 +03:00
node - > object - > method . param_count ) ;
2015-10-19 05:25:20 +03:00
for ( i = 0 ; i < ACPI_METHOD_NUM_ARGS ; i + + ) {
obj_desc = walk_state - > arguments [ i ] . object ;
if ( obj_desc ) {
acpi_os_printf ( " Arg%u: " , i ) ;
acpi_db_display_internal_object ( obj_desc ,
walk_state ) ;
}
}
} else {
acpi_os_printf
( " No Arguments are initialized for method [%4.4s] \n " ,
acpi_ut_get_node_name ( node ) ) ;
}
}