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 : dbutils - AML debugger utilities
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <acpi/acpi.h>
# include "accommon.h"
# include "acnamesp.h"
# include "acdebug.h"
# define _COMPONENT ACPI_CA_DEBUGGER
ACPI_MODULE_NAME ( " dbutils " )
/* Local prototypes */
# ifdef ACPI_OBSOLETE_FUNCTIONS
acpi_status acpi_db_second_pass_parse ( union acpi_parse_object * root ) ;
void acpi_db_dump_buffer ( u32 address ) ;
# endif
/*******************************************************************************
*
* FUNCTION : acpi_db_match_argument
*
* PARAMETERS : user_argument - User command line
* arguments - Array of commands to match against
*
* RETURN : Index into command array or ACPI_TYPE_NOT_FOUND if not found
*
* DESCRIPTION : Search command array for a command match
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_object_type
acpi_db_match_argument ( char * user_argument ,
struct acpi_db_argument_info * arguments )
{
u32 i ;
if ( ! user_argument | | user_argument [ 0 ] = = 0 ) {
return ( ACPI_TYPE_NOT_FOUND ) ;
}
for ( i = 0 ; arguments [ i ] . name ; i + + ) {
2016-03-24 04:40:40 +03:00
if ( strstr ( ACPI_CAST_PTR ( char , arguments [ i ] . name ) ,
ACPI_CAST_PTR ( char ,
user_argument ) ) = = arguments [ i ] . name ) {
2015-10-19 05:25:20 +03:00
return ( i ) ;
}
}
/* Argument not recognized */
return ( ACPI_TYPE_NOT_FOUND ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_set_output_destination
*
* PARAMETERS : output_flags - Current flags word
*
* RETURN : None
*
* DESCRIPTION : Set the current destination for debugger output . Also sets
* the debug output level accordingly .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_set_output_destination ( u32 output_flags )
{
acpi_gbl_db_output_flags = ( u8 ) output_flags ;
if ( ( output_flags & ACPI_DB_REDIRECTABLE_OUTPUT ) & &
acpi_gbl_db_output_to_file ) {
acpi_dbg_level = acpi_gbl_db_debug_level ;
} else {
acpi_dbg_level = acpi_gbl_db_console_debug_level ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_dump_external_object
*
* PARAMETERS : obj_desc - External ACPI object to dump
* level - Nesting level .
*
* RETURN : None
*
* DESCRIPTION : Dump the contents of an ACPI external object
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_dump_external_object ( union acpi_object * obj_desc , u32 level )
{
u32 i ;
if ( ! obj_desc ) {
acpi_os_printf ( " [Null Object] \n " ) ;
return ;
}
for ( i = 0 ; i < level ; i + + ) {
acpi_os_printf ( " " ) ;
}
switch ( obj_desc - > type ) {
case ACPI_TYPE_ANY :
acpi_os_printf ( " [Null Object] (Type=0) \n " ) ;
break ;
case ACPI_TYPE_INTEGER :
acpi_os_printf ( " [Integer] = %8.8X%8.8X \n " ,
ACPI_FORMAT_UINT64 ( obj_desc - > integer . value ) ) ;
break ;
case ACPI_TYPE_STRING :
acpi_os_printf ( " [String] Length %.2X = " ,
obj_desc - > string . length ) ;
acpi_ut_print_string ( obj_desc - > string . pointer , ACPI_UINT8_MAX ) ;
acpi_os_printf ( " \n " ) ;
break ;
case ACPI_TYPE_BUFFER :
acpi_os_printf ( " [Buffer] Length %.2X = " ,
obj_desc - > buffer . length ) ;
if ( obj_desc - > buffer . length ) {
if ( obj_desc - > buffer . length > 16 ) {
acpi_os_printf ( " \n " ) ;
}
2015-12-29 08:54:36 +03:00
2015-10-19 05:25:20 +03:00
acpi_ut_debug_dump_buffer ( ACPI_CAST_PTR
( u8 ,
obj_desc - > buffer . pointer ) ,
obj_desc - > buffer . length ,
DB_BYTE_DISPLAY , _COMPONENT ) ;
} else {
acpi_os_printf ( " \n " ) ;
}
break ;
case ACPI_TYPE_PACKAGE :
acpi_os_printf ( " [Package] Contains %u Elements: \n " ,
obj_desc - > package . count ) ;
for ( i = 0 ; i < obj_desc - > package . count ; i + + ) {
acpi_db_dump_external_object ( & obj_desc - > package .
elements [ i ] , level + 1 ) ;
}
break ;
case ACPI_TYPE_LOCAL_REFERENCE :
acpi_os_printf ( " [Object Reference] = " ) ;
acpi_db_display_internal_object ( obj_desc - > reference . handle ,
NULL ) ;
break ;
case ACPI_TYPE_PROCESSOR :
acpi_os_printf ( " [Processor] \n " ) ;
break ;
case ACPI_TYPE_POWER :
acpi_os_printf ( " [Power Resource] \n " ) ;
break ;
default :
acpi_os_printf ( " [Unknown Type] %X \n " , obj_desc - > type ) ;
break ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_prep_namestring
*
* PARAMETERS : name - String to prepare
*
* RETURN : None
*
* DESCRIPTION : Translate all forward slashes and dots to backslashes .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_prep_namestring ( char * name )
{
if ( ! name ) {
return ;
}
acpi_ut_strupr ( name ) ;
/* Convert a leading forward slash to a backslash */
if ( * name = = ' / ' ) {
* name = ' \\ ' ;
}
/* Ignore a leading backslash, this is the root prefix */
if ( ACPI_IS_ROOT_PREFIX ( * name ) ) {
name + + ;
}
/* Convert all slash path separators to dots */
while ( * name ) {
if ( ( * name = = ' / ' ) | | ( * name = = ' \\ ' ) ) {
* name = ' . ' ;
}
name + + ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_db_local_ns_lookup
*
* PARAMETERS : name - Name to lookup
*
* RETURN : Pointer to a namespace node , null on failure
*
* DESCRIPTION : Lookup a name in the ACPI namespace
*
* Note : Currently begins search from the root . Could be enhanced to use
* the current prefix ( scope ) node as the search beginning point .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct acpi_namespace_node * acpi_db_local_ns_lookup ( char * name )
{
char * internal_path ;
acpi_status status ;
struct acpi_namespace_node * node = NULL ;
acpi_db_prep_namestring ( name ) ;
/* Build an internal namestring */
status = acpi_ns_internalize_name ( name , & internal_path ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " Invalid namestring: %s \n " , name ) ;
return ( NULL ) ;
}
/*
* Lookup the name .
* ( Uses root node as the search starting point )
*/
status = acpi_ns_lookup ( NULL , internal_path , ACPI_TYPE_ANY ,
ACPI_IMODE_EXECUTE ,
ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE ,
NULL , & node ) ;
if ( ACPI_FAILURE ( status ) ) {
acpi_os_printf ( " Could not locate name: %s, %s \n " ,
name , acpi_format_exception ( status ) ) ;
}
ACPI_FREE ( internal_path ) ;
return ( node ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_uint32_to_hex_string
*
* PARAMETERS : value - The value to be converted to string
* buffer - Buffer for result ( not less than 11 bytes )
*
* RETURN : None
*
* DESCRIPTION : Convert the unsigned 32 - bit value to the hexadecimal image
*
* NOTE : It is the caller ' s responsibility to ensure that the length of buffer
* is sufficient .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_uint32_to_hex_string ( u32 value , char * buffer )
{
int i ;
if ( value = = 0 ) {
strcpy ( buffer , " 0 " ) ;
return ;
}
buffer [ 8 ] = ' \0 ' ;
for ( i = 7 ; i > = 0 ; i - - ) {
2016-03-24 04:40:40 +03:00
buffer [ i ] = acpi_gbl_upper_hex_digits [ value & 0x0F ] ;
2015-10-19 05:25:20 +03:00
value = value > > 4 ;
}
}
# ifdef ACPI_OBSOLETE_FUNCTIONS
/*******************************************************************************
*
* FUNCTION : acpi_db_second_pass_parse
*
* PARAMETERS : root - Root of the parse tree
*
* RETURN : Status
*
* DESCRIPTION : Second pass parse of the ACPI tables . We need to wait until
* second pass to parse the control methods
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status acpi_db_second_pass_parse ( union acpi_parse_object * root )
{
union acpi_parse_object * op = root ;
union acpi_parse_object * method ;
union acpi_parse_object * search_op ;
union acpi_parse_object * start_op ;
acpi_status status = AE_OK ;
u32 base_aml_offset ;
struct acpi_walk_state * walk_state ;
ACPI_FUNCTION_ENTRY ( ) ;
acpi_os_printf ( " Pass two parse .... \n " ) ;
while ( op ) {
if ( op - > common . aml_opcode = = AML_METHOD_OP ) {
method = op ;
/* Create a new walk state for the parse */
walk_state =
acpi_ds_create_walk_state ( 0 , NULL , NULL , NULL ) ;
if ( ! walk_state ) {
return ( AE_NO_MEMORY ) ;
}
/* Init the Walk State */
walk_state - > parser_state . aml =
walk_state - > parser_state . aml_start =
method - > named . data ;
walk_state - > parser_state . aml_end =
walk_state - > parser_state . pkg_end =
method - > named . data + method - > named . length ;
walk_state - > parser_state . start_scope = op ;
walk_state - > descending_callback =
acpi_ds_load1_begin_op ;
walk_state - > ascending_callback = acpi_ds_load1_end_op ;
/* Perform the AML parse */
status = acpi_ps_parse_aml ( walk_state ) ;
base_aml_offset =
( method - > common . value . arg ) - > common . aml_offset + 1 ;
start_op = ( method - > common . value . arg ) - > common . next ;
search_op = start_op ;
while ( search_op ) {
search_op - > common . aml_offset + = base_aml_offset ;
search_op =
acpi_ps_get_depth_next ( start_op , search_op ) ;
}
}
if ( op - > common . aml_opcode = = AML_REGION_OP ) {
/* TBD: [Investigate] this isn't quite the right thing to do! */
/*
*
* Method = ( ACPI_DEFERRED_OP * ) Op ;
* Status = acpi_ps_parse_aml ( Op , Method - > Body , Method - > body_length ) ;
*/
}
if ( ACPI_FAILURE ( status ) ) {
break ;
}
op = acpi_ps_get_depth_next ( root , op ) ;
}
return ( status ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_db_dump_buffer
*
* PARAMETERS : address - Pointer to the buffer
*
* RETURN : None
*
* DESCRIPTION : Print a portion of a buffer
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_db_dump_buffer ( u32 address )
{
acpi_os_printf ( " \n Location %X: \n " , address ) ;
acpi_dbg_level | = ACPI_LV_TABLES ;
acpi_ut_debug_dump_buffer ( ACPI_TO_POINTER ( address ) , 64 , DB_BYTE_DISPLAY ,
ACPI_UINT32_MAX ) ;
}
# endif