cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dbcmds.c (30880B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/*******************************************************************************
      3 *
      4 * Module Name: dbcmds - Miscellaneous debug commands and output routines
      5 *
      6 ******************************************************************************/
      7
      8#include <acpi/acpi.h>
      9#include "accommon.h"
     10#include "acevents.h"
     11#include "acdebug.h"
     12#include "acnamesp.h"
     13#include "acresrc.h"
     14#include "actables.h"
     15
     16#define _COMPONENT          ACPI_CA_DEBUGGER
     17ACPI_MODULE_NAME("dbcmds")
     18
     19/* Local prototypes */
     20static void
     21acpi_dm_compare_aml_resources(u8 *aml1_buffer,
     22			      acpi_rsdesc_size aml1_buffer_length,
     23			      u8 *aml2_buffer,
     24			      acpi_rsdesc_size aml2_buffer_length);
     25
     26static acpi_status
     27acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name);
     28
     29static acpi_status
     30acpi_db_resource_callback(struct acpi_resource *resource, void *context);
     31
     32static acpi_status
     33acpi_db_device_resources(acpi_handle obj_handle,
     34			 u32 nesting_level, void *context, void **return_value);
     35
     36static void acpi_db_do_one_sleep_state(u8 sleep_state);
     37
     38static char *acpi_db_trace_method_name = NULL;
     39
     40/*******************************************************************************
     41 *
     42 * FUNCTION:    acpi_db_convert_to_node
     43 *
     44 * PARAMETERS:  in_string           - String to convert
     45 *
     46 * RETURN:      Pointer to a NS node
     47 *
     48 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
     49 *              alphanumeric strings.
     50 *
     51 ******************************************************************************/
     52
     53struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string)
     54{
     55	struct acpi_namespace_node *node;
     56	acpi_size address;
     57
     58	if ((*in_string >= 0x30) && (*in_string <= 0x39)) {
     59
     60		/* Numeric argument, convert */
     61
     62		address = strtoul(in_string, NULL, 16);
     63		node = ACPI_TO_POINTER(address);
     64		if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
     65			acpi_os_printf("Address %p is invalid", node);
     66			return (NULL);
     67		}
     68
     69		/* Make sure pointer is valid NS node */
     70
     71		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
     72			acpi_os_printf
     73			    ("Address %p is not a valid namespace node [%s]\n",
     74			     node, acpi_ut_get_descriptor_name(node));
     75			return (NULL);
     76		}
     77	} else {
     78		/*
     79		 * Alpha argument: The parameter is a name string that must be
     80		 * resolved to a Namespace object.
     81		 */
     82		node = acpi_db_local_ns_lookup(in_string);
     83		if (!node) {
     84			acpi_os_printf
     85			    ("Could not find [%s] in namespace, defaulting to root node\n",
     86			     in_string);
     87			node = acpi_gbl_root_node;
     88		}
     89	}
     90
     91	return (node);
     92}
     93
     94/*******************************************************************************
     95 *
     96 * FUNCTION:    acpi_db_sleep
     97 *
     98 * PARAMETERS:  object_arg          - Desired sleep state (0-5). NULL means
     99 *                                    invoke all possible sleep states.
    100 *
    101 * RETURN:      Status
    102 *
    103 * DESCRIPTION: Simulate sleep/wake sequences
    104 *
    105 ******************************************************************************/
    106
    107acpi_status acpi_db_sleep(char *object_arg)
    108{
    109	u8 sleep_state;
    110	u32 i;
    111
    112	ACPI_FUNCTION_TRACE(acpi_db_sleep);
    113
    114	/* Null input (no arguments) means to invoke all sleep states */
    115
    116	if (!object_arg) {
    117		acpi_os_printf("Invoking all possible sleep states, 0-%d\n",
    118			       ACPI_S_STATES_MAX);
    119
    120		for (i = 0; i <= ACPI_S_STATES_MAX; i++) {
    121			acpi_db_do_one_sleep_state((u8)i);
    122		}
    123
    124		return_ACPI_STATUS(AE_OK);
    125	}
    126
    127	/* Convert argument to binary and invoke the sleep state */
    128
    129	sleep_state = (u8)strtoul(object_arg, NULL, 0);
    130	acpi_db_do_one_sleep_state(sleep_state);
    131	return_ACPI_STATUS(AE_OK);
    132}
    133
    134/*******************************************************************************
    135 *
    136 * FUNCTION:    acpi_db_do_one_sleep_state
    137 *
    138 * PARAMETERS:  sleep_state         - Desired sleep state (0-5)
    139 *
    140 * RETURN:      None
    141 *
    142 * DESCRIPTION: Simulate a sleep/wake sequence
    143 *
    144 ******************************************************************************/
    145
    146static void acpi_db_do_one_sleep_state(u8 sleep_state)
    147{
    148	acpi_status status;
    149	u8 sleep_type_a;
    150	u8 sleep_type_b;
    151
    152	/* Validate parameter */
    153
    154	if (sleep_state > ACPI_S_STATES_MAX) {
    155		acpi_os_printf("Sleep state %d out of range (%d max)\n",
    156			       sleep_state, ACPI_S_STATES_MAX);
    157		return;
    158	}
    159
    160	acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n",
    161		       sleep_state, acpi_gbl_sleep_state_names[sleep_state]);
    162
    163	/* Get the values for the sleep type registers (for display only) */
    164
    165	status =
    166	    acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b);
    167	if (ACPI_FAILURE(status)) {
    168		acpi_os_printf("Could not evaluate [%s] method, %s\n",
    169			       acpi_gbl_sleep_state_names[sleep_state],
    170			       acpi_format_exception(status));
    171		return;
    172	}
    173
    174	acpi_os_printf
    175	    ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
    176	     sleep_state, sleep_type_a, sleep_type_b);
    177
    178	/* Invoke the various sleep/wake interfaces */
    179
    180	acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n",
    181		       sleep_state);
    182	status = acpi_enter_sleep_state_prep(sleep_state);
    183	if (ACPI_FAILURE(status)) {
    184		goto error_exit;
    185	}
    186
    187	acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state);
    188	status = acpi_enter_sleep_state(sleep_state);
    189	if (ACPI_FAILURE(status)) {
    190		goto error_exit;
    191	}
    192
    193	acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n",
    194		       sleep_state);
    195	status = acpi_leave_sleep_state_prep(sleep_state);
    196	if (ACPI_FAILURE(status)) {
    197		goto error_exit;
    198	}
    199
    200	acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n",
    201		       sleep_state);
    202	status = acpi_leave_sleep_state(sleep_state);
    203	if (ACPI_FAILURE(status)) {
    204		goto error_exit;
    205	}
    206
    207	return;
    208
    209error_exit:
    210	ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d",
    211			sleep_state));
    212}
    213
    214/*******************************************************************************
    215 *
    216 * FUNCTION:    acpi_db_display_locks
    217 *
    218 * PARAMETERS:  None
    219 *
    220 * RETURN:      None
    221 *
    222 * DESCRIPTION: Display information about internal mutexes.
    223 *
    224 ******************************************************************************/
    225
    226void acpi_db_display_locks(void)
    227{
    228	u32 i;
    229
    230	for (i = 0; i < ACPI_MAX_MUTEX; i++) {
    231		acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i),
    232			       acpi_gbl_mutex_info[i].thread_id ==
    233			       ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked");
    234	}
    235}
    236
    237/*******************************************************************************
    238 *
    239 * FUNCTION:    acpi_db_display_table_info
    240 *
    241 * PARAMETERS:  table_arg           - Name of table to be displayed
    242 *
    243 * RETURN:      None
    244 *
    245 * DESCRIPTION: Display information about loaded tables. Current
    246 *              implementation displays all loaded tables.
    247 *
    248 ******************************************************************************/
    249
    250void acpi_db_display_table_info(char *table_arg)
    251{
    252	u32 i;
    253	struct acpi_table_desc *table_desc;
    254	acpi_status status;
    255
    256	/* Header */
    257
    258	acpi_os_printf("Idx ID  Status Type                    "
    259		       "TableHeader (Sig, Address, Length, Misc)\n");
    260
    261	/* Walk the entire root table list */
    262
    263	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
    264		table_desc = &acpi_gbl_root_table_list.tables[i];
    265
    266		/* Index and Table ID */
    267
    268		acpi_os_printf("%3u %.2u ", i, table_desc->owner_id);
    269
    270		/* Decode the table flags */
    271
    272		if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) {
    273			acpi_os_printf("NotLoaded ");
    274		} else {
    275			acpi_os_printf(" Loaded ");
    276		}
    277
    278		switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
    279		case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
    280
    281			acpi_os_printf("External/virtual ");
    282			break;
    283
    284		case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
    285
    286			acpi_os_printf("Internal/physical ");
    287			break;
    288
    289		case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
    290
    291			acpi_os_printf("Internal/virtual ");
    292			break;
    293
    294		default:
    295
    296			acpi_os_printf("INVALID TYPE    ");
    297			break;
    298		}
    299
    300		/* Make sure that the table is mapped */
    301
    302		status = acpi_tb_validate_table(table_desc);
    303		if (ACPI_FAILURE(status)) {
    304			return;
    305		}
    306
    307		/* Dump the table header */
    308
    309		if (table_desc->pointer) {
    310			acpi_tb_print_table_header(table_desc->address,
    311						   table_desc->pointer);
    312		} else {
    313			/* If the pointer is null, the table has been unloaded */
    314
    315			ACPI_INFO(("%4.4s - Table has been unloaded",
    316				   table_desc->signature.ascii));
    317		}
    318	}
    319}
    320
    321/*******************************************************************************
    322 *
    323 * FUNCTION:    acpi_db_unload_acpi_table
    324 *
    325 * PARAMETERS:  object_name         - Namespace pathname for an object that
    326 *                                    is owned by the table to be unloaded
    327 *
    328 * RETURN:      None
    329 *
    330 * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
    331 *              by the table.
    332 *
    333 ******************************************************************************/
    334
    335void acpi_db_unload_acpi_table(char *object_name)
    336{
    337	struct acpi_namespace_node *node;
    338	acpi_status status;
    339
    340	/* Translate name to an Named object */
    341
    342	node = acpi_db_convert_to_node(object_name);
    343	if (!node) {
    344		return;
    345	}
    346
    347	status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node));
    348	if (ACPI_SUCCESS(status)) {
    349		acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n",
    350			       object_name, node);
    351	} else {
    352		acpi_os_printf("%s, while unloading parent table of [%s]\n",
    353			       acpi_format_exception(status), object_name);
    354	}
    355}
    356
    357/*******************************************************************************
    358 *
    359 * FUNCTION:    acpi_db_send_notify
    360 *
    361 * PARAMETERS:  name                - Name of ACPI object where to send notify
    362 *              value               - Value of the notify to send.
    363 *
    364 * RETURN:      None
    365 *
    366 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
    367 *              named object as an ACPI notify.
    368 *
    369 ******************************************************************************/
    370
    371void acpi_db_send_notify(char *name, u32 value)
    372{
    373	struct acpi_namespace_node *node;
    374	acpi_status status;
    375
    376	/* Translate name to an Named object */
    377
    378	node = acpi_db_convert_to_node(name);
    379	if (!node) {
    380		return;
    381	}
    382
    383	/* Dispatch the notify if legal */
    384
    385	if (acpi_ev_is_notify_object(node)) {
    386		status = acpi_ev_queue_notify_request(node, value);
    387		if (ACPI_FAILURE(status)) {
    388			acpi_os_printf("Could not queue notify\n");
    389		}
    390	} else {
    391		acpi_os_printf("Named object [%4.4s] Type %s, "
    392			       "must be Device/Thermal/Processor type\n",
    393			       acpi_ut_get_node_name(node),
    394			       acpi_ut_get_type_name(node->type));
    395	}
    396}
    397
    398/*******************************************************************************
    399 *
    400 * FUNCTION:    acpi_db_display_interfaces
    401 *
    402 * PARAMETERS:  action_arg          - Null, "install", or "remove"
    403 *              interface_name_arg  - Name for install/remove options
    404 *
    405 * RETURN:      None
    406 *
    407 * DESCRIPTION: Display or modify the global _OSI interface list
    408 *
    409 ******************************************************************************/
    410
    411void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg)
    412{
    413	struct acpi_interface_info *next_interface;
    414	char *sub_string;
    415	acpi_status status;
    416
    417	/* If no arguments, just display current interface list */
    418
    419	if (!action_arg) {
    420		(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex,
    421					    ACPI_WAIT_FOREVER);
    422
    423		next_interface = acpi_gbl_supported_interfaces;
    424		while (next_interface) {
    425			if (!(next_interface->flags & ACPI_OSI_INVALID)) {
    426				acpi_os_printf("%s\n", next_interface->name);
    427			}
    428
    429			next_interface = next_interface->next;
    430		}
    431
    432		acpi_os_release_mutex(acpi_gbl_osi_mutex);
    433		return;
    434	}
    435
    436	/* If action_arg exists, so must interface_name_arg */
    437
    438	if (!interface_name_arg) {
    439		acpi_os_printf("Missing Interface Name argument\n");
    440		return;
    441	}
    442
    443	/* Uppercase the action for match below */
    444
    445	acpi_ut_strupr(action_arg);
    446
    447	/* install - install an interface */
    448
    449	sub_string = strstr("INSTALL", action_arg);
    450	if (sub_string) {
    451		status = acpi_install_interface(interface_name_arg);
    452		if (ACPI_FAILURE(status)) {
    453			acpi_os_printf("%s, while installing \"%s\"\n",
    454				       acpi_format_exception(status),
    455				       interface_name_arg);
    456		}
    457		return;
    458	}
    459
    460	/* remove - remove an interface */
    461
    462	sub_string = strstr("REMOVE", action_arg);
    463	if (sub_string) {
    464		status = acpi_remove_interface(interface_name_arg);
    465		if (ACPI_FAILURE(status)) {
    466			acpi_os_printf("%s, while removing \"%s\"\n",
    467				       acpi_format_exception(status),
    468				       interface_name_arg);
    469		}
    470		return;
    471	}
    472
    473	/* Invalid action_arg */
    474
    475	acpi_os_printf("Invalid action argument: %s\n", action_arg);
    476	return;
    477}
    478
    479/*******************************************************************************
    480 *
    481 * FUNCTION:    acpi_db_display_template
    482 *
    483 * PARAMETERS:  buffer_arg          - Buffer name or address
    484 *
    485 * RETURN:      None
    486 *
    487 * DESCRIPTION: Dump a buffer that contains a resource template
    488 *
    489 ******************************************************************************/
    490
    491void acpi_db_display_template(char *buffer_arg)
    492{
    493	struct acpi_namespace_node *node;
    494	acpi_status status;
    495	struct acpi_buffer return_buffer;
    496
    497	/* Translate buffer_arg to an Named object */
    498
    499	node = acpi_db_convert_to_node(buffer_arg);
    500	if (!node || (node == acpi_gbl_root_node)) {
    501		acpi_os_printf("Invalid argument: %s\n", buffer_arg);
    502		return;
    503	}
    504
    505	/* We must have a buffer object */
    506
    507	if (node->type != ACPI_TYPE_BUFFER) {
    508		acpi_os_printf
    509		    ("Not a Buffer object, cannot be a template: %s\n",
    510		     buffer_arg);
    511		return;
    512	}
    513
    514	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
    515	return_buffer.pointer = acpi_gbl_db_buffer;
    516
    517	/* Attempt to convert the raw buffer to a resource list */
    518
    519	status = acpi_rs_create_resource_list(node->object, &return_buffer);
    520
    521	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
    522	acpi_dbg_level |= ACPI_LV_RESOURCES;
    523
    524	if (ACPI_FAILURE(status)) {
    525		acpi_os_printf
    526		    ("Could not convert Buffer to a resource list: %s, %s\n",
    527		     buffer_arg, acpi_format_exception(status));
    528		goto dump_buffer;
    529	}
    530
    531	/* Now we can dump the resource list */
    532
    533	acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
    534						 return_buffer.pointer));
    535
    536dump_buffer:
    537	acpi_os_printf("\nRaw data buffer:\n");
    538	acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer,
    539				  node->object->buffer.length,
    540				  DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
    541
    542	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
    543	return;
    544}
    545
    546/*******************************************************************************
    547 *
    548 * FUNCTION:    acpi_dm_compare_aml_resources
    549 *
    550 * PARAMETERS:  aml1_buffer         - Contains first resource list
    551 *              aml1_buffer_length  - Length of first resource list
    552 *              aml2_buffer         - Contains second resource list
    553 *              aml2_buffer_length  - Length of second resource list
    554 *
    555 * RETURN:      None
    556 *
    557 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
    558 *              order to isolate a miscompare to an individual resource)
    559 *
    560 ******************************************************************************/
    561
    562static void
    563acpi_dm_compare_aml_resources(u8 *aml1_buffer,
    564			      acpi_rsdesc_size aml1_buffer_length,
    565			      u8 *aml2_buffer,
    566			      acpi_rsdesc_size aml2_buffer_length)
    567{
    568	u8 *aml1;
    569	u8 *aml2;
    570	u8 *aml1_end;
    571	u8 *aml2_end;
    572	acpi_rsdesc_size aml1_length;
    573	acpi_rsdesc_size aml2_length;
    574	acpi_rsdesc_size offset = 0;
    575	u8 resource_type;
    576	u32 count = 0;
    577	u32 i;
    578
    579	/* Compare overall buffer sizes (may be different due to size rounding) */
    580
    581	if (aml1_buffer_length != aml2_buffer_length) {
    582		acpi_os_printf("**** Buffer length mismatch in converted "
    583			       "AML: Original %X, New %X ****\n",
    584			       aml1_buffer_length, aml2_buffer_length);
    585	}
    586
    587	aml1 = aml1_buffer;
    588	aml2 = aml2_buffer;
    589	aml1_end = aml1_buffer + aml1_buffer_length;
    590	aml2_end = aml2_buffer + aml2_buffer_length;
    591
    592	/* Walk the descriptor lists, comparing each descriptor */
    593
    594	while ((aml1 < aml1_end) && (aml2 < aml2_end)) {
    595
    596		/* Get the lengths of each descriptor */
    597
    598		aml1_length = acpi_ut_get_descriptor_length(aml1);
    599		aml2_length = acpi_ut_get_descriptor_length(aml2);
    600		resource_type = acpi_ut_get_resource_type(aml1);
    601
    602		/* Check for descriptor length match */
    603
    604		if (aml1_length != aml2_length) {
    605			acpi_os_printf
    606			    ("**** Length mismatch in descriptor [%.2X] type %2.2X, "
    607			     "Offset %8.8X Len1 %X, Len2 %X ****\n", count,
    608			     resource_type, offset, aml1_length, aml2_length);
    609		}
    610
    611		/* Check for descriptor byte match */
    612
    613		else if (memcmp(aml1, aml2, aml1_length)) {
    614			acpi_os_printf
    615			    ("**** Data mismatch in descriptor [%.2X] type %2.2X, "
    616			     "Offset %8.8X ****\n", count, resource_type,
    617			     offset);
    618
    619			for (i = 0; i < aml1_length; i++) {
    620				if (aml1[i] != aml2[i]) {
    621					acpi_os_printf
    622					    ("Mismatch at byte offset %.2X: is %2.2X, "
    623					     "should be %2.2X\n", i, aml2[i],
    624					     aml1[i]);
    625				}
    626			}
    627		}
    628
    629		/* Exit on end_tag descriptor */
    630
    631		if (resource_type == ACPI_RESOURCE_NAME_END_TAG) {
    632			return;
    633		}
    634
    635		/* Point to next descriptor in each buffer */
    636
    637		count++;
    638		offset += aml1_length;
    639		aml1 += aml1_length;
    640		aml2 += aml2_length;
    641	}
    642}
    643
    644/*******************************************************************************
    645 *
    646 * FUNCTION:    acpi_dm_test_resource_conversion
    647 *
    648 * PARAMETERS:  node                - Parent device node
    649 *              name                - resource method name (_CRS)
    650 *
    651 * RETURN:      Status
    652 *
    653 * DESCRIPTION: Compare the original AML with a conversion of the AML to
    654 *              internal resource list, then back to AML.
    655 *
    656 ******************************************************************************/
    657
    658static acpi_status
    659acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name)
    660{
    661	acpi_status status;
    662	struct acpi_buffer return_buffer;
    663	struct acpi_buffer resource_buffer;
    664	struct acpi_buffer new_aml;
    665	union acpi_object *original_aml;
    666
    667	acpi_os_printf("Resource Conversion Comparison:\n");
    668
    669	new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    670	return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    671	resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    672
    673	/* Get the original _CRS AML resource template */
    674
    675	status = acpi_evaluate_object(node, name, NULL, &return_buffer);
    676	if (ACPI_FAILURE(status)) {
    677		acpi_os_printf("Could not obtain %s: %s\n",
    678			       name, acpi_format_exception(status));
    679		return (status);
    680	}
    681
    682	/* Get the AML resource template, converted to internal resource structs */
    683
    684	status = acpi_get_current_resources(node, &resource_buffer);
    685	if (ACPI_FAILURE(status)) {
    686		acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
    687			       acpi_format_exception(status));
    688		goto exit1;
    689	}
    690
    691	/* Convert internal resource list to external AML resource template */
    692
    693	status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml);
    694	if (ACPI_FAILURE(status)) {
    695		acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n",
    696			       acpi_format_exception(status));
    697		goto exit2;
    698	}
    699
    700	/* Compare original AML to the newly created AML resource list */
    701
    702	original_aml = return_buffer.pointer;
    703
    704	acpi_dm_compare_aml_resources(original_aml->buffer.pointer,
    705				      (acpi_rsdesc_size)original_aml->buffer.
    706				      length, new_aml.pointer,
    707				      (acpi_rsdesc_size)new_aml.length);
    708
    709	/* Cleanup and exit */
    710
    711	ACPI_FREE(new_aml.pointer);
    712exit2:
    713	ACPI_FREE(resource_buffer.pointer);
    714exit1:
    715	ACPI_FREE(return_buffer.pointer);
    716	return (status);
    717}
    718
    719/*******************************************************************************
    720 *
    721 * FUNCTION:    acpi_db_resource_callback
    722 *
    723 * PARAMETERS:  acpi_walk_resource_callback
    724 *
    725 * RETURN:      Status
    726 *
    727 * DESCRIPTION: Simple callback to exercise acpi_walk_resources and
    728 *              acpi_walk_resource_buffer.
    729 *
    730 ******************************************************************************/
    731
    732static acpi_status
    733acpi_db_resource_callback(struct acpi_resource *resource, void *context)
    734{
    735
    736	return (AE_OK);
    737}
    738
    739/*******************************************************************************
    740 *
    741 * FUNCTION:    acpi_db_device_resources
    742 *
    743 * PARAMETERS:  acpi_walk_callback
    744 *
    745 * RETURN:      Status
    746 *
    747 * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
    748 *
    749 ******************************************************************************/
    750
    751static acpi_status
    752acpi_db_device_resources(acpi_handle obj_handle,
    753			 u32 nesting_level, void *context, void **return_value)
    754{
    755	struct acpi_namespace_node *node;
    756	struct acpi_namespace_node *prt_node = NULL;
    757	struct acpi_namespace_node *crs_node = NULL;
    758	struct acpi_namespace_node *prs_node = NULL;
    759	struct acpi_namespace_node *aei_node = NULL;
    760	char *parent_path;
    761	struct acpi_buffer return_buffer;
    762	acpi_status status;
    763
    764	node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
    765	parent_path = acpi_ns_get_normalized_pathname(node, TRUE);
    766	if (!parent_path) {
    767		return (AE_NO_MEMORY);
    768	}
    769
    770	/* Get handles to the resource methods for this device */
    771
    772	(void)acpi_get_handle(node, METHOD_NAME__PRT,
    773			      ACPI_CAST_PTR(acpi_handle, &prt_node));
    774	(void)acpi_get_handle(node, METHOD_NAME__CRS,
    775			      ACPI_CAST_PTR(acpi_handle, &crs_node));
    776	(void)acpi_get_handle(node, METHOD_NAME__PRS,
    777			      ACPI_CAST_PTR(acpi_handle, &prs_node));
    778	(void)acpi_get_handle(node, METHOD_NAME__AEI,
    779			      ACPI_CAST_PTR(acpi_handle, &aei_node));
    780
    781	if (!prt_node && !crs_node && !prs_node && !aei_node) {
    782		goto cleanup;	/* Nothing to do */
    783	}
    784
    785	acpi_os_printf("\nDevice: %s\n", parent_path);
    786
    787	/* Prepare for a return object of arbitrary size */
    788
    789	return_buffer.pointer = acpi_gbl_db_buffer;
    790	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
    791
    792	/* _PRT */
    793
    794	if (prt_node) {
    795		acpi_os_printf("Evaluating _PRT\n");
    796
    797		status =
    798		    acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer);
    799		if (ACPI_FAILURE(status)) {
    800			acpi_os_printf("Could not evaluate _PRT: %s\n",
    801				       acpi_format_exception(status));
    802			goto get_crs;
    803		}
    804
    805		return_buffer.pointer = acpi_gbl_db_buffer;
    806		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
    807
    808		status = acpi_get_irq_routing_table(node, &return_buffer);
    809		if (ACPI_FAILURE(status)) {
    810			acpi_os_printf("GetIrqRoutingTable failed: %s\n",
    811				       acpi_format_exception(status));
    812			goto get_crs;
    813		}
    814
    815		acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer));
    816	}
    817
    818	/* _CRS */
    819
    820get_crs:
    821	if (crs_node) {
    822		acpi_os_printf("Evaluating _CRS\n");
    823
    824		return_buffer.pointer = acpi_gbl_db_buffer;
    825		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
    826
    827		status =
    828		    acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer);
    829		if (ACPI_FAILURE(status)) {
    830			acpi_os_printf("Could not evaluate _CRS: %s\n",
    831				       acpi_format_exception(status));
    832			goto get_prs;
    833		}
    834
    835		/* This code exercises the acpi_walk_resources interface */
    836
    837		status = acpi_walk_resources(node, METHOD_NAME__CRS,
    838					     acpi_db_resource_callback, NULL);
    839		if (ACPI_FAILURE(status)) {
    840			acpi_os_printf("AcpiWalkResources failed: %s\n",
    841				       acpi_format_exception(status));
    842			goto get_prs;
    843		}
    844
    845		/* Get the _CRS resource list (test ALLOCATE buffer) */
    846
    847		return_buffer.pointer = NULL;
    848		return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    849
    850		status = acpi_get_current_resources(node, &return_buffer);
    851		if (ACPI_FAILURE(status)) {
    852			acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
    853				       acpi_format_exception(status));
    854			goto get_prs;
    855		}
    856
    857		/* This code exercises the acpi_walk_resource_buffer interface */
    858
    859		status = acpi_walk_resource_buffer(&return_buffer,
    860						   acpi_db_resource_callback,
    861						   NULL);
    862		if (ACPI_FAILURE(status)) {
    863			acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n",
    864				       acpi_format_exception(status));
    865			goto end_crs;
    866		}
    867
    868		/* Dump the _CRS resource list */
    869
    870		acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
    871							 return_buffer.
    872							 pointer));
    873
    874		/*
    875		 * Perform comparison of original AML to newly created AML. This
    876		 * tests both the AML->Resource conversion and the Resource->AML
    877		 * conversion.
    878		 */
    879		(void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS);
    880
    881		/* Execute _SRS with the resource list */
    882
    883		acpi_os_printf("Evaluating _SRS\n");
    884
    885		status = acpi_set_current_resources(node, &return_buffer);
    886		if (ACPI_FAILURE(status)) {
    887			acpi_os_printf("AcpiSetCurrentResources failed: %s\n",
    888				       acpi_format_exception(status));
    889			goto end_crs;
    890		}
    891
    892end_crs:
    893		ACPI_FREE(return_buffer.pointer);
    894	}
    895
    896	/* _PRS */
    897
    898get_prs:
    899	if (prs_node) {
    900		acpi_os_printf("Evaluating _PRS\n");
    901
    902		return_buffer.pointer = acpi_gbl_db_buffer;
    903		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
    904
    905		status =
    906		    acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer);
    907		if (ACPI_FAILURE(status)) {
    908			acpi_os_printf("Could not evaluate _PRS: %s\n",
    909				       acpi_format_exception(status));
    910			goto get_aei;
    911		}
    912
    913		return_buffer.pointer = acpi_gbl_db_buffer;
    914		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
    915
    916		status = acpi_get_possible_resources(node, &return_buffer);
    917		if (ACPI_FAILURE(status)) {
    918			acpi_os_printf("AcpiGetPossibleResources failed: %s\n",
    919				       acpi_format_exception(status));
    920			goto get_aei;
    921		}
    922
    923		acpi_rs_dump_resource_list(ACPI_CAST_PTR
    924					   (struct acpi_resource,
    925					    acpi_gbl_db_buffer));
    926	}
    927
    928	/* _AEI */
    929
    930get_aei:
    931	if (aei_node) {
    932		acpi_os_printf("Evaluating _AEI\n");
    933
    934		return_buffer.pointer = acpi_gbl_db_buffer;
    935		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
    936
    937		status =
    938		    acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer);
    939		if (ACPI_FAILURE(status)) {
    940			acpi_os_printf("Could not evaluate _AEI: %s\n",
    941				       acpi_format_exception(status));
    942			goto cleanup;
    943		}
    944
    945		return_buffer.pointer = acpi_gbl_db_buffer;
    946		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
    947
    948		status = acpi_get_event_resources(node, &return_buffer);
    949		if (ACPI_FAILURE(status)) {
    950			acpi_os_printf("AcpiGetEventResources failed: %s\n",
    951				       acpi_format_exception(status));
    952			goto cleanup;
    953		}
    954
    955		acpi_rs_dump_resource_list(ACPI_CAST_PTR
    956					   (struct acpi_resource,
    957					    acpi_gbl_db_buffer));
    958	}
    959
    960cleanup:
    961	ACPI_FREE(parent_path);
    962	return (AE_OK);
    963}
    964
    965/*******************************************************************************
    966 *
    967 * FUNCTION:    acpi_db_display_resources
    968 *
    969 * PARAMETERS:  object_arg          - String object name or object pointer.
    970 *                                    NULL or "*" means "display resources for
    971 *                                    all devices"
    972 *
    973 * RETURN:      None
    974 *
    975 * DESCRIPTION: Display the resource objects associated with a device.
    976 *
    977 ******************************************************************************/
    978
    979void acpi_db_display_resources(char *object_arg)
    980{
    981	struct acpi_namespace_node *node;
    982
    983	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
    984	acpi_dbg_level |= ACPI_LV_RESOURCES;
    985
    986	/* Asterisk means "display resources for all devices" */
    987
    988	if (!object_arg || (!strcmp(object_arg, "*"))) {
    989		(void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
    990					  ACPI_UINT32_MAX,
    991					  acpi_db_device_resources, NULL, NULL,
    992					  NULL);
    993	} else {
    994		/* Convert string to object pointer */
    995
    996		node = acpi_db_convert_to_node(object_arg);
    997		if (node) {
    998			if (node->type != ACPI_TYPE_DEVICE) {
    999				acpi_os_printf
   1000				    ("%4.4s: Name is not a device object (%s)\n",
   1001				     node->name.ascii,
   1002				     acpi_ut_get_type_name(node->type));
   1003			} else {
   1004				(void)acpi_db_device_resources(node, 0, NULL,
   1005							       NULL);
   1006			}
   1007		}
   1008	}
   1009
   1010	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
   1011}
   1012
   1013#if (!ACPI_REDUCED_HARDWARE)
   1014/*******************************************************************************
   1015 *
   1016 * FUNCTION:    acpi_db_generate_gpe
   1017 *
   1018 * PARAMETERS:  gpe_arg             - Raw GPE number, ascii string
   1019 *              block_arg           - GPE block number, ascii string
   1020 *                                    0 or 1 for FADT GPE blocks
   1021 *
   1022 * RETURN:      None
   1023 *
   1024 * DESCRIPTION: Simulate firing of a GPE
   1025 *
   1026 ******************************************************************************/
   1027
   1028void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)
   1029{
   1030	u32 block_number = 0;
   1031	u32 gpe_number;
   1032	struct acpi_gpe_event_info *gpe_event_info;
   1033
   1034	gpe_number = strtoul(gpe_arg, NULL, 0);
   1035
   1036	/*
   1037	 * If no block arg, or block arg == 0 or 1, use the FADT-defined
   1038	 * GPE blocks.
   1039	 */
   1040	if (block_arg) {
   1041		block_number = strtoul(block_arg, NULL, 0);
   1042		if (block_number == 1) {
   1043			block_number = 0;
   1044		}
   1045	}
   1046
   1047	gpe_event_info =
   1048	    acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),
   1049				       gpe_number);
   1050	if (!gpe_event_info) {
   1051		acpi_os_printf("Invalid GPE\n");
   1052		return;
   1053	}
   1054
   1055	(void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);
   1056}
   1057
   1058/*******************************************************************************
   1059 *
   1060 * FUNCTION:    acpi_db_generate_sci
   1061 *
   1062 * PARAMETERS:  None
   1063 *
   1064 * RETURN:      None
   1065 *
   1066 * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
   1067 *
   1068 ******************************************************************************/
   1069
   1070void acpi_db_generate_sci(void)
   1071{
   1072	acpi_ev_sci_dispatch();
   1073}
   1074
   1075#endif				/* !ACPI_REDUCED_HARDWARE */
   1076
   1077/*******************************************************************************
   1078 *
   1079 * FUNCTION:    acpi_db_trace
   1080 *
   1081 * PARAMETERS:  enable_arg          - ENABLE/AML to enable tracer
   1082 *                                    DISABLE to disable tracer
   1083 *              method_arg          - Method to trace
   1084 *              once_arg            - Whether trace once
   1085 *
   1086 * RETURN:      None
   1087 *
   1088 * DESCRIPTION: Control method tracing facility
   1089 *
   1090 ******************************************************************************/
   1091
   1092void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg)
   1093{
   1094	u32 debug_level = 0;
   1095	u32 debug_layer = 0;
   1096	u32 flags = 0;
   1097
   1098	acpi_ut_strupr(enable_arg);
   1099	acpi_ut_strupr(once_arg);
   1100
   1101	if (method_arg) {
   1102		if (acpi_db_trace_method_name) {
   1103			ACPI_FREE(acpi_db_trace_method_name);
   1104			acpi_db_trace_method_name = NULL;
   1105		}
   1106
   1107		acpi_db_trace_method_name =
   1108		    ACPI_ALLOCATE(strlen(method_arg) + 1);
   1109		if (!acpi_db_trace_method_name) {
   1110			acpi_os_printf("Failed to allocate method name (%s)\n",
   1111				       method_arg);
   1112			return;
   1113		}
   1114
   1115		strcpy(acpi_db_trace_method_name, method_arg);
   1116	}
   1117
   1118	if (!strcmp(enable_arg, "ENABLE") ||
   1119	    !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) {
   1120		if (!strcmp(enable_arg, "ENABLE")) {
   1121
   1122			/* Inherit current console settings */
   1123
   1124			debug_level = acpi_gbl_db_console_debug_level;
   1125			debug_layer = acpi_dbg_layer;
   1126		} else {
   1127			/* Restrict console output to trace points only */
   1128
   1129			debug_level = ACPI_LV_TRACE_POINT;
   1130			debug_layer = ACPI_EXECUTER;
   1131		}
   1132
   1133		flags = ACPI_TRACE_ENABLED;
   1134
   1135		if (!strcmp(enable_arg, "OPCODE")) {
   1136			flags |= ACPI_TRACE_OPCODE;
   1137		}
   1138
   1139		if (once_arg && !strcmp(once_arg, "ONCE")) {
   1140			flags |= ACPI_TRACE_ONESHOT;
   1141		}
   1142	}
   1143
   1144	(void)acpi_debug_trace(acpi_db_trace_method_name,
   1145			       debug_level, debug_layer, flags);
   1146}