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

dbdisply.c (28188B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/*******************************************************************************
      3 *
      4 * Module Name: dbdisply - debug display commands
      5 *
      6 ******************************************************************************/
      7
      8#include <acpi/acpi.h>
      9#include "accommon.h"
     10#include "amlcode.h"
     11#include "acdispat.h"
     12#include "acnamesp.h"
     13#include "acparser.h"
     14#include "acinterp.h"
     15#include "acevents.h"
     16#include "acdebug.h"
     17
     18#define _COMPONENT          ACPI_CA_DEBUGGER
     19ACPI_MODULE_NAME("dbdisply")
     20
     21/* Local prototypes */
     22static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op);
     23
     24static void *acpi_db_get_pointer(void *target);
     25
     26static acpi_status
     27acpi_db_display_non_root_handlers(acpi_handle obj_handle,
     28				  u32 nesting_level,
     29				  void *context, void **return_value);
     30
     31/*
     32 * System handler information.
     33 * Used for Handlers command, in acpi_db_display_handlers.
     34 */
     35#define ACPI_PREDEFINED_PREFIX          "%25s (%.2X) : "
     36#define ACPI_HANDLER_NAME_STRING               "%30s : "
     37#define ACPI_HANDLER_PRESENT_STRING                    "%-9s (%p)\n"
     38#define ACPI_HANDLER_PRESENT_STRING2                   "%-9s (%p)"
     39#define ACPI_HANDLER_NOT_PRESENT_STRING                "%-9s\n"
     40
     41/* All predefined Address Space IDs */
     42
     43static acpi_adr_space_type acpi_gbl_space_id_list[] = {
     44	ACPI_ADR_SPACE_SYSTEM_MEMORY,
     45	ACPI_ADR_SPACE_SYSTEM_IO,
     46	ACPI_ADR_SPACE_PCI_CONFIG,
     47	ACPI_ADR_SPACE_EC,
     48	ACPI_ADR_SPACE_SMBUS,
     49	ACPI_ADR_SPACE_CMOS,
     50	ACPI_ADR_SPACE_PCI_BAR_TARGET,
     51	ACPI_ADR_SPACE_IPMI,
     52	ACPI_ADR_SPACE_GPIO,
     53	ACPI_ADR_SPACE_GSBUS,
     54	ACPI_ADR_SPACE_PLATFORM_COMM,
     55	ACPI_ADR_SPACE_PLATFORM_RT,
     56	ACPI_ADR_SPACE_DATA_TABLE,
     57	ACPI_ADR_SPACE_FIXED_HARDWARE
     58};
     59
     60/* Global handler information */
     61
     62typedef struct acpi_handler_info {
     63	void *handler;
     64	char *name;
     65
     66} acpi_handler_info;
     67
     68static struct acpi_handler_info acpi_gbl_handler_list[] = {
     69	{&acpi_gbl_global_notify[0].handler, "System Notifications"},
     70	{&acpi_gbl_global_notify[1].handler, "Device Notifications"},
     71	{&acpi_gbl_table_handler, "ACPI Table Events"},
     72	{&acpi_gbl_exception_handler, "Control Method Exceptions"},
     73	{&acpi_gbl_interface_handler, "OSI Invocations"}
     74};
     75
     76/*******************************************************************************
     77 *
     78 * FUNCTION:    acpi_db_get_pointer
     79 *
     80 * PARAMETERS:  target          - Pointer to string to be converted
     81 *
     82 * RETURN:      Converted pointer
     83 *
     84 * DESCRIPTION: Convert an ascii pointer value to a real value
     85 *
     86 ******************************************************************************/
     87
     88static void *acpi_db_get_pointer(void *target)
     89{
     90	void *obj_ptr;
     91	acpi_size address;
     92
     93	address = strtoul(target, NULL, 16);
     94	obj_ptr = ACPI_TO_POINTER(address);
     95	return (obj_ptr);
     96}
     97
     98/*******************************************************************************
     99 *
    100 * FUNCTION:    acpi_db_dump_parser_descriptor
    101 *
    102 * PARAMETERS:  op              - A parser Op descriptor
    103 *
    104 * RETURN:      None
    105 *
    106 * DESCRIPTION: Display a formatted parser object
    107 *
    108 ******************************************************************************/
    109
    110static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op)
    111{
    112	const struct acpi_opcode_info *info;
    113
    114	info = acpi_ps_get_opcode_info(op->common.aml_opcode);
    115
    116	acpi_os_printf("Parser Op Descriptor:\n");
    117	acpi_os_printf("%20.20s : %4.4X\n", "Opcode", op->common.aml_opcode);
    118
    119	ACPI_DEBUG_ONLY_MEMBERS(acpi_os_printf("%20.20s : %s\n", "Opcode Name",
    120					       info->name));
    121
    122	acpi_os_printf("%20.20s : %p\n", "Value/ArgList", op->common.value.arg);
    123	acpi_os_printf("%20.20s : %p\n", "Parent", op->common.parent);
    124	acpi_os_printf("%20.20s : %p\n", "NextOp", op->common.next);
    125}
    126
    127/*******************************************************************************
    128 *
    129 * FUNCTION:    acpi_db_decode_and_display_object
    130 *
    131 * PARAMETERS:  target          - String with object to be displayed. Names
    132 *                                and hex pointers are supported.
    133 *              output_type     - Byte, Word, Dword, or Qword (B|W|D|Q)
    134 *
    135 * RETURN:      None
    136 *
    137 * DESCRIPTION: Display a formatted ACPI object
    138 *
    139 ******************************************************************************/
    140
    141void acpi_db_decode_and_display_object(char *target, char *output_type)
    142{
    143	void *obj_ptr;
    144	struct acpi_namespace_node *node;
    145	union acpi_operand_object *obj_desc;
    146	u32 display = DB_BYTE_DISPLAY;
    147	char buffer[80];
    148	struct acpi_buffer ret_buf;
    149	acpi_status status;
    150	u32 size;
    151
    152	if (!target) {
    153		return;
    154	}
    155
    156	/* Decode the output type */
    157
    158	if (output_type) {
    159		acpi_ut_strupr(output_type);
    160		if (output_type[0] == 'W') {
    161			display = DB_WORD_DISPLAY;
    162		} else if (output_type[0] == 'D') {
    163			display = DB_DWORD_DISPLAY;
    164		} else if (output_type[0] == 'Q') {
    165			display = DB_QWORD_DISPLAY;
    166		}
    167	}
    168
    169	ret_buf.length = sizeof(buffer);
    170	ret_buf.pointer = buffer;
    171
    172	/* Differentiate between a number and a name */
    173
    174	if ((target[0] >= 0x30) && (target[0] <= 0x39)) {
    175		obj_ptr = acpi_db_get_pointer(target);
    176		if (!acpi_os_readable(obj_ptr, 16)) {
    177			acpi_os_printf
    178			    ("Address %p is invalid in this address space\n",
    179			     obj_ptr);
    180			return;
    181		}
    182
    183		/* Decode the object type */
    184
    185		switch (ACPI_GET_DESCRIPTOR_TYPE(obj_ptr)) {
    186		case ACPI_DESC_TYPE_NAMED:
    187
    188			/* This is a namespace Node */
    189
    190			if (!acpi_os_readable
    191			    (obj_ptr, sizeof(struct acpi_namespace_node))) {
    192				acpi_os_printf
    193				    ("Cannot read entire Named object at address %p\n",
    194				     obj_ptr);
    195				return;
    196			}
    197
    198			node = obj_ptr;
    199			goto dump_node;
    200
    201		case ACPI_DESC_TYPE_OPERAND:
    202
    203			/* This is a ACPI OPERAND OBJECT */
    204
    205			if (!acpi_os_readable
    206			    (obj_ptr, sizeof(union acpi_operand_object))) {
    207				acpi_os_printf
    208				    ("Cannot read entire ACPI object at address %p\n",
    209				     obj_ptr);
    210				return;
    211			}
    212
    213			acpi_ut_debug_dump_buffer(obj_ptr,
    214						  sizeof(union
    215							 acpi_operand_object),
    216						  display, ACPI_UINT32_MAX);
    217			acpi_ex_dump_object_descriptor(obj_ptr, 1);
    218			break;
    219
    220		case ACPI_DESC_TYPE_PARSER:
    221
    222			/* This is a Parser Op object */
    223
    224			if (!acpi_os_readable
    225			    (obj_ptr, sizeof(union acpi_parse_object))) {
    226				acpi_os_printf
    227				    ("Cannot read entire Parser object at address %p\n",
    228				     obj_ptr);
    229				return;
    230			}
    231
    232			acpi_ut_debug_dump_buffer(obj_ptr,
    233						  sizeof(union
    234							 acpi_parse_object),
    235						  display, ACPI_UINT32_MAX);
    236			acpi_db_dump_parser_descriptor((union acpi_parse_object
    237							*)obj_ptr);
    238			break;
    239
    240		default:
    241
    242			/* Is not a recognizable object */
    243
    244			acpi_os_printf
    245			    ("Not a known ACPI internal object, descriptor type %2.2X\n",
    246			     ACPI_GET_DESCRIPTOR_TYPE(obj_ptr));
    247
    248			size = 16;
    249			if (acpi_os_readable(obj_ptr, 64)) {
    250				size = 64;
    251			}
    252
    253			/* Just dump some memory */
    254
    255			acpi_ut_debug_dump_buffer(obj_ptr, size, display,
    256						  ACPI_UINT32_MAX);
    257			break;
    258		}
    259
    260		return;
    261	}
    262
    263	/* The parameter is a name string that must be resolved to a Named obj */
    264
    265	node = acpi_db_local_ns_lookup(target);
    266	if (!node) {
    267		return;
    268	}
    269
    270dump_node:
    271	/* Now dump the NS node */
    272
    273	status = acpi_get_name(node, ACPI_FULL_PATHNAME_NO_TRAILING, &ret_buf);
    274	if (ACPI_FAILURE(status)) {
    275		acpi_os_printf("Could not convert name to pathname\n");
    276	}
    277
    278	else {
    279		acpi_os_printf("Object %p: Namespace Node - Pathname: %s\n",
    280			       node, (char *)ret_buf.pointer);
    281	}
    282
    283	if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
    284		acpi_os_printf("Invalid Named object at address %p\n", node);
    285		return;
    286	}
    287
    288	acpi_ut_debug_dump_buffer((void *)node,
    289				  sizeof(struct acpi_namespace_node), display,
    290				  ACPI_UINT32_MAX);
    291	acpi_ex_dump_namespace_node(node, 1);
    292
    293	obj_desc = acpi_ns_get_attached_object(node);
    294	if (obj_desc) {
    295		acpi_os_printf("\nAttached Object %p:", obj_desc);
    296		if (!acpi_os_readable
    297		    (obj_desc, sizeof(union acpi_operand_object))) {
    298			acpi_os_printf
    299			    ("Invalid internal ACPI Object at address %p\n",
    300			     obj_desc);
    301			return;
    302		}
    303
    304		if (ACPI_GET_DESCRIPTOR_TYPE(((struct acpi_namespace_node *)
    305					      obj_desc)) ==
    306		    ACPI_DESC_TYPE_NAMED) {
    307			acpi_os_printf(" Namespace Node - ");
    308			status =
    309			    acpi_get_name((struct acpi_namespace_node *)
    310					  obj_desc,
    311					  ACPI_FULL_PATHNAME_NO_TRAILING,
    312					  &ret_buf);
    313			if (ACPI_FAILURE(status)) {
    314				acpi_os_printf
    315				    ("Could not convert name to pathname\n");
    316			} else {
    317				acpi_os_printf("Pathname: %s",
    318					       (char *)ret_buf.pointer);
    319			}
    320
    321			acpi_os_printf("\n");
    322			acpi_ut_debug_dump_buffer((void *)obj_desc,
    323						  sizeof(struct
    324							 acpi_namespace_node),
    325						  display, ACPI_UINT32_MAX);
    326		} else {
    327			acpi_os_printf("\n");
    328			acpi_ut_debug_dump_buffer((void *)obj_desc,
    329						  sizeof(union
    330							 acpi_operand_object),
    331						  display, ACPI_UINT32_MAX);
    332		}
    333
    334		acpi_ex_dump_object_descriptor(obj_desc, 1);
    335	}
    336}
    337
    338/*******************************************************************************
    339 *
    340 * FUNCTION:    acpi_db_display_method_info
    341 *
    342 * PARAMETERS:  start_op        - Root of the control method parse tree
    343 *
    344 * RETURN:      None
    345 *
    346 * DESCRIPTION: Display information about the current method
    347 *
    348 ******************************************************************************/
    349
    350void acpi_db_display_method_info(union acpi_parse_object *start_op)
    351{
    352	struct acpi_walk_state *walk_state;
    353	union acpi_operand_object *obj_desc;
    354	struct acpi_namespace_node *node;
    355	union acpi_parse_object *root_op;
    356	union acpi_parse_object *op;
    357	const struct acpi_opcode_info *op_info;
    358	u32 num_ops = 0;
    359	u32 num_operands = 0;
    360	u32 num_operators = 0;
    361	u32 num_remaining_ops = 0;
    362	u32 num_remaining_operands = 0;
    363	u32 num_remaining_operators = 0;
    364	u8 count_remaining = FALSE;
    365
    366	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
    367	if (!walk_state) {
    368		acpi_os_printf("There is no method currently executing\n");
    369		return;
    370	}
    371
    372	obj_desc = walk_state->method_desc;
    373	node = walk_state->method_node;
    374
    375	acpi_os_printf("Currently executing control method is [%4.4s]\n",
    376		       acpi_ut_get_node_name(node));
    377	acpi_os_printf("%X Arguments, SyncLevel = %X\n",
    378		       (u32)obj_desc->method.param_count,
    379		       (u32)obj_desc->method.sync_level);
    380
    381	root_op = start_op;
    382	while (root_op->common.parent) {
    383		root_op = root_op->common.parent;
    384	}
    385
    386	op = root_op;
    387
    388	while (op) {
    389		if (op == start_op) {
    390			count_remaining = TRUE;
    391		}
    392
    393		num_ops++;
    394		if (count_remaining) {
    395			num_remaining_ops++;
    396		}
    397
    398		/* Decode the opcode */
    399
    400		op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
    401		switch (op_info->class) {
    402		case AML_CLASS_ARGUMENT:
    403
    404			if (count_remaining) {
    405				num_remaining_operands++;
    406			}
    407
    408			num_operands++;
    409			break;
    410
    411		case AML_CLASS_UNKNOWN:
    412
    413			/* Bad opcode or ASCII character */
    414
    415			continue;
    416
    417		default:
    418
    419			if (count_remaining) {
    420				num_remaining_operators++;
    421			}
    422
    423			num_operators++;
    424			break;
    425		}
    426
    427		op = acpi_ps_get_depth_next(start_op, op);
    428	}
    429
    430	acpi_os_printf
    431	    ("Method contains:       %X AML Opcodes - %X Operators, %X Operands\n",
    432	     num_ops, num_operators, num_operands);
    433
    434	acpi_os_printf
    435	    ("Remaining to execute:  %X AML Opcodes - %X Operators, %X Operands\n",
    436	     num_remaining_ops, num_remaining_operators,
    437	     num_remaining_operands);
    438}
    439
    440/*******************************************************************************
    441 *
    442 * FUNCTION:    acpi_db_display_locals
    443 *
    444 * PARAMETERS:  None
    445 *
    446 * RETURN:      None
    447 *
    448 * DESCRIPTION: Display all locals for the currently running control method
    449 *
    450 ******************************************************************************/
    451
    452void acpi_db_display_locals(void)
    453{
    454	struct acpi_walk_state *walk_state;
    455
    456	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
    457	if (!walk_state) {
    458		acpi_os_printf("There is no method currently executing\n");
    459		return;
    460	}
    461
    462	acpi_db_decode_locals(walk_state);
    463}
    464
    465/*******************************************************************************
    466 *
    467 * FUNCTION:    acpi_db_display_arguments
    468 *
    469 * PARAMETERS:  None
    470 *
    471 * RETURN:      None
    472 *
    473 * DESCRIPTION: Display all arguments for the currently running control method
    474 *
    475 ******************************************************************************/
    476
    477void acpi_db_display_arguments(void)
    478{
    479	struct acpi_walk_state *walk_state;
    480
    481	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
    482	if (!walk_state) {
    483		acpi_os_printf("There is no method currently executing\n");
    484		return;
    485	}
    486
    487	acpi_db_decode_arguments(walk_state);
    488}
    489
    490/*******************************************************************************
    491 *
    492 * FUNCTION:    acpi_db_display_results
    493 *
    494 * PARAMETERS:  None
    495 *
    496 * RETURN:      None
    497 *
    498 * DESCRIPTION: Display current contents of a method result stack
    499 *
    500 ******************************************************************************/
    501
    502void acpi_db_display_results(void)
    503{
    504	u32 i;
    505	struct acpi_walk_state *walk_state;
    506	union acpi_operand_object *obj_desc;
    507	u32 result_count = 0;
    508	struct acpi_namespace_node *node;
    509	union acpi_generic_state *frame;
    510	u32 index;		/* Index onto current frame */
    511
    512	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
    513	if (!walk_state) {
    514		acpi_os_printf("There is no method currently executing\n");
    515		return;
    516	}
    517
    518	node = walk_state->method_node;
    519
    520	if (walk_state->results) {
    521		result_count = walk_state->result_count;
    522	}
    523
    524	acpi_os_printf("Method [%4.4s] has %X stacked result objects\n",
    525		       acpi_ut_get_node_name(node), result_count);
    526
    527	/* From the top element of result stack */
    528
    529	frame = walk_state->results;
    530	index = (result_count - 1) % ACPI_RESULTS_FRAME_OBJ_NUM;
    531
    532	for (i = 0; i < result_count; i++) {
    533		obj_desc = frame->results.obj_desc[index];
    534		acpi_os_printf("Result%u: ", i);
    535		acpi_db_display_internal_object(obj_desc, walk_state);
    536
    537		if (index == 0) {
    538			frame = frame->results.next;
    539			index = ACPI_RESULTS_FRAME_OBJ_NUM;
    540		}
    541
    542		index--;
    543	}
    544}
    545
    546/*******************************************************************************
    547 *
    548 * FUNCTION:    acpi_db_display_calling_tree
    549 *
    550 * PARAMETERS:  None
    551 *
    552 * RETURN:      None
    553 *
    554 * DESCRIPTION: Display current calling tree of nested control methods
    555 *
    556 ******************************************************************************/
    557
    558void acpi_db_display_calling_tree(void)
    559{
    560	struct acpi_walk_state *walk_state;
    561	struct acpi_namespace_node *node;
    562
    563	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
    564	if (!walk_state) {
    565		acpi_os_printf("There is no method currently executing\n");
    566		return;
    567	}
    568
    569	acpi_os_printf("Current Control Method Call Tree\n");
    570
    571	while (walk_state) {
    572		node = walk_state->method_node;
    573		acpi_os_printf("  [%4.4s]\n", acpi_ut_get_node_name(node));
    574
    575		walk_state = walk_state->next;
    576	}
    577}
    578
    579/*******************************************************************************
    580 *
    581 * FUNCTION:    acpi_db_display_object_type
    582 *
    583 * PARAMETERS:  object_arg      - User entered NS node handle
    584 *
    585 * RETURN:      None
    586 *
    587 * DESCRIPTION: Display type of an arbitrary NS node
    588 *
    589 ******************************************************************************/
    590
    591void acpi_db_display_object_type(char *object_arg)
    592{
    593	acpi_size arg;
    594	acpi_handle handle;
    595	struct acpi_device_info *info;
    596	acpi_status status;
    597	u32 i;
    598
    599	arg = strtoul(object_arg, NULL, 16);
    600	handle = ACPI_TO_POINTER(arg);
    601
    602	status = acpi_get_object_info(handle, &info);
    603	if (ACPI_FAILURE(status)) {
    604		acpi_os_printf("Could not get object info, %s\n",
    605			       acpi_format_exception(status));
    606		return;
    607	}
    608
    609	acpi_os_printf("ADR: %8.8X%8.8X, Flags: %X\n",
    610		       ACPI_FORMAT_UINT64(info->address), info->flags);
    611
    612	acpi_os_printf("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n",
    613		       info->highest_dstates[0], info->highest_dstates[1],
    614		       info->highest_dstates[2], info->highest_dstates[3]);
    615
    616	acpi_os_printf("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n",
    617		       info->lowest_dstates[0], info->lowest_dstates[1],
    618		       info->lowest_dstates[2], info->lowest_dstates[3],
    619		       info->lowest_dstates[4]);
    620
    621	if (info->valid & ACPI_VALID_HID) {
    622		acpi_os_printf("HID: %s\n", info->hardware_id.string);
    623	}
    624
    625	if (info->valid & ACPI_VALID_UID) {
    626		acpi_os_printf("UID: %s\n", info->unique_id.string);
    627	}
    628
    629	if (info->valid & ACPI_VALID_CID) {
    630		for (i = 0; i < info->compatible_id_list.count; i++) {
    631			acpi_os_printf("CID %u: %s\n", i,
    632				       info->compatible_id_list.ids[i].string);
    633		}
    634	}
    635
    636	ACPI_FREE(info);
    637}
    638
    639/*******************************************************************************
    640 *
    641 * FUNCTION:    acpi_db_display_result_object
    642 *
    643 * PARAMETERS:  obj_desc        - Object to be displayed
    644 *              walk_state      - Current walk state
    645 *
    646 * RETURN:      None
    647 *
    648 * DESCRIPTION: Display the result of an AML opcode
    649 *
    650 * Note: Currently only displays the result object if we are single stepping.
    651 * However, this output may be useful in other contexts and could be enabled
    652 * to do so if needed.
    653 *
    654 ******************************************************************************/
    655
    656void
    657acpi_db_display_result_object(union acpi_operand_object *obj_desc,
    658			      struct acpi_walk_state *walk_state)
    659{
    660
    661#ifndef ACPI_APPLICATION
    662	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
    663		return;
    664	}
    665#endif
    666
    667	/* Only display if single stepping */
    668
    669	if (!acpi_gbl_cm_single_step) {
    670		return;
    671	}
    672
    673	acpi_os_printf("ResultObj: ");
    674	acpi_db_display_internal_object(obj_desc, walk_state);
    675	acpi_os_printf("\n");
    676}
    677
    678/*******************************************************************************
    679 *
    680 * FUNCTION:    acpi_db_display_argument_object
    681 *
    682 * PARAMETERS:  obj_desc        - Object to be displayed
    683 *              walk_state      - Current walk state
    684 *
    685 * RETURN:      None
    686 *
    687 * DESCRIPTION: Display the result of an AML opcode
    688 *
    689 ******************************************************************************/
    690
    691void
    692acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
    693				struct acpi_walk_state *walk_state)
    694{
    695
    696#ifndef ACPI_APPLICATION
    697	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
    698		return;
    699	}
    700#endif
    701
    702	if (!acpi_gbl_cm_single_step) {
    703		return;
    704	}
    705
    706	acpi_os_printf("ArgObj:  ");
    707	acpi_db_display_internal_object(obj_desc, walk_state);
    708}
    709
    710#if (!ACPI_REDUCED_HARDWARE)
    711/*******************************************************************************
    712 *
    713 * FUNCTION:    acpi_db_display_gpes
    714 *
    715 * PARAMETERS:  None
    716 *
    717 * RETURN:      None
    718 *
    719 * DESCRIPTION: Display the current GPE structures
    720 *
    721 ******************************************************************************/
    722
    723void acpi_db_display_gpes(void)
    724{
    725	struct acpi_gpe_block_info *gpe_block;
    726	struct acpi_gpe_xrupt_info *gpe_xrupt_info;
    727	struct acpi_gpe_event_info *gpe_event_info;
    728	struct acpi_gpe_register_info *gpe_register_info;
    729	char *gpe_type;
    730	struct acpi_gpe_notify_info *notify;
    731	u32 gpe_index;
    732	u32 block = 0;
    733	u32 i;
    734	u32 j;
    735	u32 count;
    736	char buffer[80];
    737	struct acpi_buffer ret_buf;
    738	acpi_status status;
    739
    740	ret_buf.length = sizeof(buffer);
    741	ret_buf.pointer = buffer;
    742
    743	block = 0;
    744
    745	/* Walk the GPE lists */
    746
    747	gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
    748	while (gpe_xrupt_info) {
    749		gpe_block = gpe_xrupt_info->gpe_block_list_head;
    750		while (gpe_block) {
    751			status = acpi_get_name(gpe_block->node,
    752					       ACPI_FULL_PATHNAME_NO_TRAILING,
    753					       &ret_buf);
    754			if (ACPI_FAILURE(status)) {
    755				acpi_os_printf
    756				    ("Could not convert name to pathname\n");
    757			}
    758
    759			if (gpe_block->node == acpi_gbl_fadt_gpe_device) {
    760				gpe_type = "FADT-defined GPE block";
    761			} else {
    762				gpe_type = "GPE Block Device";
    763			}
    764
    765			acpi_os_printf
    766			    ("\nBlock %u - Info %p  DeviceNode %p [%s] - %s\n",
    767			     block, gpe_block, gpe_block->node, buffer,
    768			     gpe_type);
    769
    770			acpi_os_printf("    Registers:    %u (%u GPEs)\n",
    771				       gpe_block->register_count,
    772				       gpe_block->gpe_count);
    773
    774			acpi_os_printf
    775			    ("    GPE range:    0x%X to 0x%X on interrupt %u\n",
    776			     gpe_block->block_base_number,
    777			     gpe_block->block_base_number +
    778			     (gpe_block->gpe_count - 1),
    779			     gpe_xrupt_info->interrupt_number);
    780
    781			acpi_os_printf
    782			    ("    RegisterInfo: %p  Status %8.8X%8.8X Enable %8.8X%8.8X\n",
    783			     gpe_block->register_info,
    784			     ACPI_FORMAT_UINT64(gpe_block->register_info->
    785						status_address.address),
    786			     ACPI_FORMAT_UINT64(gpe_block->register_info->
    787						enable_address.address));
    788
    789			acpi_os_printf("  EventInfo:    %p\n",
    790				       gpe_block->event_info);
    791
    792			/* Examine each GPE Register within the block */
    793
    794			for (i = 0; i < gpe_block->register_count; i++) {
    795				gpe_register_info =
    796				    &gpe_block->register_info[i];
    797
    798				acpi_os_printf("    Reg %u: (GPE %.2X-%.2X)  "
    799					       "RunEnable %2.2X WakeEnable %2.2X"
    800					       " Status %8.8X%8.8X Enable %8.8X%8.8X\n",
    801					       i,
    802					       gpe_register_info->
    803					       base_gpe_number,
    804					       gpe_register_info->
    805					       base_gpe_number +
    806					       (ACPI_GPE_REGISTER_WIDTH - 1),
    807					       gpe_register_info->
    808					       enable_for_run,
    809					       gpe_register_info->
    810					       enable_for_wake,
    811					       ACPI_FORMAT_UINT64
    812					       (gpe_register_info->
    813						status_address.address),
    814					       ACPI_FORMAT_UINT64
    815					       (gpe_register_info->
    816						enable_address.address));
    817
    818				/* Now look at the individual GPEs in this byte register */
    819
    820				for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
    821					gpe_index =
    822					    (i * ACPI_GPE_REGISTER_WIDTH) + j;
    823					gpe_event_info =
    824					    &gpe_block->event_info[gpe_index];
    825
    826					if (ACPI_GPE_DISPATCH_TYPE
    827					    (gpe_event_info->flags) ==
    828					    ACPI_GPE_DISPATCH_NONE) {
    829
    830						/* This GPE is not used (no method or handler), ignore it */
    831
    832						continue;
    833					}
    834
    835					acpi_os_printf
    836					    ("        GPE %.2X: %p  RunRefs %2.2X Flags %2.2X (",
    837					     gpe_block->block_base_number +
    838					     gpe_index, gpe_event_info,
    839					     gpe_event_info->runtime_count,
    840					     gpe_event_info->flags);
    841
    842					/* Decode the flags byte */
    843
    844					if (gpe_event_info->
    845					    flags & ACPI_GPE_LEVEL_TRIGGERED) {
    846						acpi_os_printf("Level, ");
    847					} else {
    848						acpi_os_printf("Edge, ");
    849					}
    850
    851					if (gpe_event_info->
    852					    flags & ACPI_GPE_CAN_WAKE) {
    853						acpi_os_printf("CanWake, ");
    854					} else {
    855						acpi_os_printf("RunOnly, ");
    856					}
    857
    858					switch (ACPI_GPE_DISPATCH_TYPE
    859						(gpe_event_info->flags)) {
    860					case ACPI_GPE_DISPATCH_NONE:
    861
    862						acpi_os_printf("NotUsed");
    863						break;
    864
    865					case ACPI_GPE_DISPATCH_METHOD:
    866
    867						acpi_os_printf("Method");
    868						break;
    869
    870					case ACPI_GPE_DISPATCH_HANDLER:
    871
    872						acpi_os_printf("Handler");
    873						break;
    874
    875					case ACPI_GPE_DISPATCH_NOTIFY:
    876
    877						count = 0;
    878						notify =
    879						    gpe_event_info->dispatch.
    880						    notify_list;
    881						while (notify) {
    882							count++;
    883							notify = notify->next;
    884						}
    885
    886						acpi_os_printf
    887						    ("Implicit Notify on %u devices",
    888						     count);
    889						break;
    890
    891					case ACPI_GPE_DISPATCH_RAW_HANDLER:
    892
    893						acpi_os_printf("RawHandler");
    894						break;
    895
    896					default:
    897
    898						acpi_os_printf("UNKNOWN: %X",
    899							       ACPI_GPE_DISPATCH_TYPE
    900							       (gpe_event_info->
    901								flags));
    902						break;
    903					}
    904
    905					acpi_os_printf(")\n");
    906				}
    907			}
    908
    909			block++;
    910			gpe_block = gpe_block->next;
    911		}
    912
    913		gpe_xrupt_info = gpe_xrupt_info->next;
    914	}
    915}
    916#endif				/* !ACPI_REDUCED_HARDWARE */
    917
    918/*******************************************************************************
    919 *
    920 * FUNCTION:    acpi_db_display_handlers
    921 *
    922 * PARAMETERS:  None
    923 *
    924 * RETURN:      None
    925 *
    926 * DESCRIPTION: Display the currently installed global handlers
    927 *
    928 ******************************************************************************/
    929
    930void acpi_db_display_handlers(void)
    931{
    932	union acpi_operand_object *obj_desc;
    933	union acpi_operand_object *handler_obj;
    934	acpi_adr_space_type space_id;
    935	u32 i;
    936
    937	/* Operation region handlers */
    938
    939	acpi_os_printf("\nOperation Region Handlers at the namespace root:\n");
    940
    941	obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node);
    942	if (obj_desc) {
    943		for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_space_id_list); i++) {
    944			space_id = acpi_gbl_space_id_list[i];
    945
    946			acpi_os_printf(ACPI_PREDEFINED_PREFIX,
    947				       acpi_ut_get_region_name((u8)space_id),
    948				       space_id);
    949
    950			handler_obj =
    951			    acpi_ev_find_region_handler(space_id,
    952							obj_desc->common_notify.
    953							handler);
    954			if (handler_obj) {
    955				acpi_os_printf(ACPI_HANDLER_PRESENT_STRING,
    956					       (handler_obj->address_space.
    957						handler_flags &
    958						ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
    959					       ? "Default" : "User",
    960					       handler_obj->address_space.
    961					       handler);
    962
    963				goto found_handler;
    964			}
    965
    966			/* There is no handler for this space_id */
    967
    968			acpi_os_printf("None\n");
    969
    970found_handler:		;
    971		}
    972
    973		/* Find all handlers for user-defined space_IDs */
    974
    975		handler_obj = obj_desc->common_notify.handler;
    976		while (handler_obj) {
    977			if (handler_obj->address_space.space_id >=
    978			    ACPI_USER_REGION_BEGIN) {
    979				acpi_os_printf(ACPI_PREDEFINED_PREFIX,
    980					       "User-defined ID",
    981					       handler_obj->address_space.
    982					       space_id);
    983				acpi_os_printf(ACPI_HANDLER_PRESENT_STRING,
    984					       (handler_obj->address_space.
    985						handler_flags &
    986						ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
    987					       ? "Default" : "User",
    988					       handler_obj->address_space.
    989					       handler);
    990			}
    991
    992			handler_obj = handler_obj->address_space.next;
    993		}
    994	}
    995#if (!ACPI_REDUCED_HARDWARE)
    996
    997	/* Fixed event handlers */
    998
    999	acpi_os_printf("\nFixed Event Handlers:\n");
   1000
   1001	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
   1002		acpi_os_printf(ACPI_PREDEFINED_PREFIX,
   1003			       acpi_ut_get_event_name(i), i);
   1004		if (acpi_gbl_fixed_event_handlers[i].handler) {
   1005			acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User",
   1006				       acpi_gbl_fixed_event_handlers[i].
   1007				       handler);
   1008		} else {
   1009			acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None");
   1010		}
   1011	}
   1012
   1013#endif				/* !ACPI_REDUCED_HARDWARE */
   1014
   1015	/* Miscellaneous global handlers */
   1016
   1017	acpi_os_printf("\nMiscellaneous Global Handlers:\n");
   1018
   1019	for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_handler_list); i++) {
   1020		acpi_os_printf(ACPI_HANDLER_NAME_STRING,
   1021			       acpi_gbl_handler_list[i].name);
   1022
   1023		if (acpi_gbl_handler_list[i].handler) {
   1024			acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User",
   1025				       acpi_gbl_handler_list[i].handler);
   1026		} else {
   1027			acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None");
   1028		}
   1029	}
   1030
   1031	/* Other handlers that are installed throughout the namespace */
   1032
   1033	acpi_os_printf("\nOperation Region Handlers for specific devices:\n");
   1034
   1035	(void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
   1036				  ACPI_UINT32_MAX,
   1037				  acpi_db_display_non_root_handlers, NULL, NULL,
   1038				  NULL);
   1039}
   1040
   1041/*******************************************************************************
   1042 *
   1043 * FUNCTION:    acpi_db_display_non_root_handlers
   1044 *
   1045 * PARAMETERS:  acpi_walk_callback
   1046 *
   1047 * RETURN:      Status
   1048 *
   1049 * DESCRIPTION: Display information about all handlers installed for a
   1050 *              device object.
   1051 *
   1052 ******************************************************************************/
   1053
   1054static acpi_status
   1055acpi_db_display_non_root_handlers(acpi_handle obj_handle,
   1056				  u32 nesting_level,
   1057				  void *context, void **return_value)
   1058{
   1059	struct acpi_namespace_node *node =
   1060	    ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
   1061	union acpi_operand_object *obj_desc;
   1062	union acpi_operand_object *handler_obj;
   1063	char *pathname;
   1064
   1065	obj_desc = acpi_ns_get_attached_object(node);
   1066	if (!obj_desc) {
   1067		return (AE_OK);
   1068	}
   1069
   1070	pathname = acpi_ns_get_normalized_pathname(node, TRUE);
   1071	if (!pathname) {
   1072		return (AE_OK);
   1073	}
   1074
   1075	/* Display all handlers associated with this device */
   1076
   1077	handler_obj = obj_desc->common_notify.handler;
   1078	while (handler_obj) {
   1079		acpi_os_printf(ACPI_PREDEFINED_PREFIX,
   1080			       acpi_ut_get_region_name((u8)handler_obj->
   1081						       address_space.space_id),
   1082			       handler_obj->address_space.space_id);
   1083
   1084		acpi_os_printf(ACPI_HANDLER_PRESENT_STRING2,
   1085			       (handler_obj->address_space.handler_flags &
   1086				ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default"
   1087			       : "User", handler_obj->address_space.handler);
   1088
   1089		acpi_os_printf(" Device Name: %s (%p)\n", pathname, node);
   1090
   1091		handler_obj = handler_obj->address_space.next;
   1092	}
   1093
   1094	ACPI_FREE(pathname);
   1095	return (AE_OK);
   1096}