// 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 = 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 */

			ACPI_INFO(("%4.4s - Table has been unloaded",
				   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("\nRaw 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,
				      (acpi_rsdesc_size)original_aml->buffer.
				      length, new_aml.pointer,
				      (acpi_rsdesc_size)new_aml.length);

	/* 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);
	parent_path = acpi_ns_get_normalized_pathname(node, TRUE);
	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("\nDevice: %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;

	acpi_ut_strupr(enable_arg);
	acpi_ut_strupr(once_arg);

	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);
}
