// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/*******************************************************************************
*
* 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<