|
@@ -0,0 +1,1187 @@
|
|
|
+/*******************************************************************************
|
|
|
+ *
|
|
|
+ * Module Name: dbcmds - Miscellaneous debug commands and output routines
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+/*
|
|
|
+ * Copyright (C) 2000 - 2015, Intel Corp.
|
|
|
+ * All rights reserved.
|
|
|
+ *
|
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
|
+ * modification, are permitted provided that the following conditions
|
|
|
+ * are met:
|
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
|
+ * notice, this list of conditions, and the following disclaimer,
|
|
|
+ * without modification.
|
|
|
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
|
|
+ * substantially similar to the "NO WARRANTY" disclaimer below
|
|
|
+ * ("Disclaimer") and any redistribution must be conditioned upon
|
|
|
+ * including a substantially similar Disclaimer requirement for further
|
|
|
+ * binary redistribution.
|
|
|
+ * 3. Neither the names of the above-listed copyright holders nor the names
|
|
|
+ * of any contributors may be used to endorse or promote products derived
|
|
|
+ * from this software without specific prior written permission.
|
|
|
+ *
|
|
|
+ * Alternatively, this software may be distributed under the terms of the
|
|
|
+ * GNU General Public License ("GPL") version 2 as published by the Free
|
|
|
+ * Software Foundation.
|
|
|
+ *
|
|
|
+ * NO WARRANTY
|
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
|
|
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
|
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
|
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
+ * POSSIBILITY OF SUCH DAMAGES.
|
|
|
+ */
|
|
|
+
|
|
|
+#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((AE_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_external_pathname(node);
|
|
|
+ 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;
|
|
|
+
|
|
|
+ if (enable_arg) {
|
|
|
+ acpi_ut_strupr(enable_arg);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (once_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);
|
|
|
+}
|