xref: /openbmc/linux/drivers/acpi/acpica/dbdisply.c (revision 8e8e69d6)
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
19 ACPI_MODULE_NAME("dbdisply")
20 
21 /* Local prototypes */
22 static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op);
23 
24 static void *acpi_db_get_pointer(void *target);
25 
26 static acpi_status
27 acpi_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 
43 static 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_DATA_TABLE,
55 	ACPI_ADR_SPACE_FIXED_HARDWARE
56 };
57 
58 /* Global handler information */
59 
60 typedef struct acpi_handler_info {
61 	void *handler;
62 	char *name;
63 
64 } acpi_handler_info;
65 
66 static struct acpi_handler_info acpi_gbl_handler_list[] = {
67 	{&acpi_gbl_global_notify[0].handler, "System Notifications"},
68 	{&acpi_gbl_global_notify[1].handler, "Device Notifications"},
69 	{&acpi_gbl_table_handler, "ACPI Table Events"},
70 	{&acpi_gbl_exception_handler, "Control Method Exceptions"},
71 	{&acpi_gbl_interface_handler, "OSI Invocations"}
72 };
73 
74 /*******************************************************************************
75  *
76  * FUNCTION:    acpi_db_get_pointer
77  *
78  * PARAMETERS:  target          - Pointer to string to be converted
79  *
80  * RETURN:      Converted pointer
81  *
82  * DESCRIPTION: Convert an ascii pointer value to a real value
83  *
84  ******************************************************************************/
85 
86 static void *acpi_db_get_pointer(void *target)
87 {
88 	void *obj_ptr;
89 	acpi_size address;
90 
91 	address = strtoul(target, NULL, 16);
92 	obj_ptr = ACPI_TO_POINTER(address);
93 	return (obj_ptr);
94 }
95 
96 /*******************************************************************************
97  *
98  * FUNCTION:    acpi_db_dump_parser_descriptor
99  *
100  * PARAMETERS:  op              - A parser Op descriptor
101  *
102  * RETURN:      None
103  *
104  * DESCRIPTION: Display a formatted parser object
105  *
106  ******************************************************************************/
107 
108 static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op)
109 {
110 	const struct acpi_opcode_info *info;
111 
112 	info = acpi_ps_get_opcode_info(op->common.aml_opcode);
113 
114 	acpi_os_printf("Parser Op Descriptor:\n");
115 	acpi_os_printf("%20.20s : %4.4X\n", "Opcode", op->common.aml_opcode);
116 
117 	ACPI_DEBUG_ONLY_MEMBERS(acpi_os_printf("%20.20s : %s\n", "Opcode Name",
118 					       info->name));
119 
120 	acpi_os_printf("%20.20s : %p\n", "Value/ArgList", op->common.value.arg);
121 	acpi_os_printf("%20.20s : %p\n", "Parent", op->common.parent);
122 	acpi_os_printf("%20.20s : %p\n", "NextOp", op->common.next);
123 }
124 
125 /*******************************************************************************
126  *
127  * FUNCTION:    acpi_db_decode_and_display_object
128  *
129  * PARAMETERS:  target          - String with object to be displayed. Names
130  *                                and hex pointers are supported.
131  *              output_type     - Byte, Word, Dword, or Qword (B|W|D|Q)
132  *
133  * RETURN:      None
134  *
135  * DESCRIPTION: Display a formatted ACPI object
136  *
137  ******************************************************************************/
138 
139 void acpi_db_decode_and_display_object(char *target, char *output_type)
140 {
141 	void *obj_ptr;
142 	struct acpi_namespace_node *node;
143 	union acpi_operand_object *obj_desc;
144 	u32 display = DB_BYTE_DISPLAY;
145 	char buffer[80];
146 	struct acpi_buffer ret_buf;
147 	acpi_status status;
148 	u32 size;
149 
150 	if (!target) {
151 		return;
152 	}
153 
154 	/* Decode the output type */
155 
156 	if (output_type) {
157 		acpi_ut_strupr(output_type);
158 		if (output_type[0] == 'W') {
159 			display = DB_WORD_DISPLAY;
160 		} else if (output_type[0] == 'D') {
161 			display = DB_DWORD_DISPLAY;
162 		} else if (output_type[0] == 'Q') {
163 			display = DB_QWORD_DISPLAY;
164 		}
165 	}
166 
167 	ret_buf.length = sizeof(buffer);
168 	ret_buf.pointer = buffer;
169 
170 	/* Differentiate between a number and a name */
171 
172 	if ((target[0] >= 0x30) && (target[0] <= 0x39)) {
173 		obj_ptr = acpi_db_get_pointer(target);
174 		if (!acpi_os_readable(obj_ptr, 16)) {
175 			acpi_os_printf
176 			    ("Address %p is invalid in this address space\n",
177 			     obj_ptr);
178 			return;
179 		}
180 
181 		/* Decode the object type */
182 
183 		switch (ACPI_GET_DESCRIPTOR_TYPE(obj_ptr)) {
184 		case ACPI_DESC_TYPE_NAMED:
185 
186 			/* This is a namespace Node */
187 
188 			if (!acpi_os_readable
189 			    (obj_ptr, sizeof(struct acpi_namespace_node))) {
190 				acpi_os_printf
191 				    ("Cannot read entire Named object at address %p\n",
192 				     obj_ptr);
193 				return;
194 			}
195 
196 			node = obj_ptr;
197 			goto dump_node;
198 
199 		case ACPI_DESC_TYPE_OPERAND:
200 
201 			/* This is a ACPI OPERAND OBJECT */
202 
203 			if (!acpi_os_readable
204 			    (obj_ptr, sizeof(union acpi_operand_object))) {
205 				acpi_os_printf
206 				    ("Cannot read entire ACPI object at address %p\n",
207 				     obj_ptr);
208 				return;
209 			}
210 
211 			acpi_ut_debug_dump_buffer(obj_ptr,
212 						  sizeof(union
213 							 acpi_operand_object),
214 						  display, ACPI_UINT32_MAX);
215 			acpi_ex_dump_object_descriptor(obj_ptr, 1);
216 			break;
217 
218 		case ACPI_DESC_TYPE_PARSER:
219 
220 			/* This is a Parser Op object */
221 
222 			if (!acpi_os_readable
223 			    (obj_ptr, sizeof(union acpi_parse_object))) {
224 				acpi_os_printf
225 				    ("Cannot read entire Parser object at address %p\n",
226 				     obj_ptr);
227 				return;
228 			}
229 
230 			acpi_ut_debug_dump_buffer(obj_ptr,
231 						  sizeof(union
232 							 acpi_parse_object),
233 						  display, ACPI_UINT32_MAX);
234 			acpi_db_dump_parser_descriptor((union acpi_parse_object
235 							*)obj_ptr);
236 			break;
237 
238 		default:
239 
240 			/* Is not a recognizable object */
241 
242 			acpi_os_printf
243 			    ("Not a known ACPI internal object, descriptor type %2.2X\n",
244 			     ACPI_GET_DESCRIPTOR_TYPE(obj_ptr));
245 
246 			size = 16;
247 			if (acpi_os_readable(obj_ptr, 64)) {
248 				size = 64;
249 			}
250 
251 			/* Just dump some memory */
252 
253 			acpi_ut_debug_dump_buffer(obj_ptr, size, display,
254 						  ACPI_UINT32_MAX);
255 			break;
256 		}
257 
258 		return;
259 	}
260 
261 	/* The parameter is a name string that must be resolved to a Named obj */
262 
263 	node = acpi_db_local_ns_lookup(target);
264 	if (!node) {
265 		return;
266 	}
267 
268 dump_node:
269 	/* Now dump the NS node */
270 
271 	status = acpi_get_name(node, ACPI_FULL_PATHNAME_NO_TRAILING, &ret_buf);
272 	if (ACPI_FAILURE(status)) {
273 		acpi_os_printf("Could not convert name to pathname\n");
274 	}
275 
276 	else {
277 		acpi_os_printf("Object %p: Namespace Node - Pathname: %s\n",
278 			       node, (char *)ret_buf.pointer);
279 	}
280 
281 	if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
282 		acpi_os_printf("Invalid Named object at address %p\n", node);
283 		return;
284 	}
285 
286 	acpi_ut_debug_dump_buffer((void *)node,
287 				  sizeof(struct acpi_namespace_node), display,
288 				  ACPI_UINT32_MAX);
289 	acpi_ex_dump_namespace_node(node, 1);
290 
291 	obj_desc = acpi_ns_get_attached_object(node);
292 	if (obj_desc) {
293 		acpi_os_printf("\nAttached Object %p:", obj_desc);
294 		if (!acpi_os_readable
295 		    (obj_desc, sizeof(union acpi_operand_object))) {
296 			acpi_os_printf
297 			    ("Invalid internal ACPI Object at address %p\n",
298 			     obj_desc);
299 			return;
300 		}
301 
302 		if (ACPI_GET_DESCRIPTOR_TYPE(((struct acpi_namespace_node *)
303 					      obj_desc)) ==
304 		    ACPI_DESC_TYPE_NAMED) {
305 			acpi_os_printf(" Namespace Node - ");
306 			status =
307 			    acpi_get_name((struct acpi_namespace_node *)
308 					  obj_desc,
309 					  ACPI_FULL_PATHNAME_NO_TRAILING,
310 					  &ret_buf);
311 			if (ACPI_FAILURE(status)) {
312 				acpi_os_printf
313 				    ("Could not convert name to pathname\n");
314 			} else {
315 				acpi_os_printf("Pathname: %s",
316 					       (char *)ret_buf.pointer);
317 			}
318 
319 			acpi_os_printf("\n");
320 			acpi_ut_debug_dump_buffer((void *)obj_desc,
321 						  sizeof(struct
322 							 acpi_namespace_node),
323 						  display, ACPI_UINT32_MAX);
324 		} else {
325 			acpi_os_printf("\n");
326 			acpi_ut_debug_dump_buffer((void *)obj_desc,
327 						  sizeof(union
328 							 acpi_operand_object),
329 						  display, ACPI_UINT32_MAX);
330 		}
331 
332 		acpi_ex_dump_object_descriptor(obj_desc, 1);
333 	}
334 }
335 
336 /*******************************************************************************
337  *
338  * FUNCTION:    acpi_db_display_method_info
339  *
340  * PARAMETERS:  start_op        - Root of the control method parse tree
341  *
342  * RETURN:      None
343  *
344  * DESCRIPTION: Display information about the current method
345  *
346  ******************************************************************************/
347 
348 void acpi_db_display_method_info(union acpi_parse_object *start_op)
349 {
350 	struct acpi_walk_state *walk_state;
351 	union acpi_operand_object *obj_desc;
352 	struct acpi_namespace_node *node;
353 	union acpi_parse_object *root_op;
354 	union acpi_parse_object *op;
355 	const struct acpi_opcode_info *op_info;
356 	u32 num_ops = 0;
357 	u32 num_operands = 0;
358 	u32 num_operators = 0;
359 	u32 num_remaining_ops = 0;
360 	u32 num_remaining_operands = 0;
361 	u32 num_remaining_operators = 0;
362 	u8 count_remaining = FALSE;
363 
364 	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
365 	if (!walk_state) {
366 		acpi_os_printf("There is no method currently executing\n");
367 		return;
368 	}
369 
370 	obj_desc = walk_state->method_desc;
371 	node = walk_state->method_node;
372 
373 	acpi_os_printf("Currently executing control method is [%4.4s]\n",
374 		       acpi_ut_get_node_name(node));
375 	acpi_os_printf("%X Arguments, SyncLevel = %X\n",
376 		       (u32)obj_desc->method.param_count,
377 		       (u32)obj_desc->method.sync_level);
378 
379 	root_op = start_op;
380 	while (root_op->common.parent) {
381 		root_op = root_op->common.parent;
382 	}
383 
384 	op = root_op;
385 
386 	while (op) {
387 		if (op == start_op) {
388 			count_remaining = TRUE;
389 		}
390 
391 		num_ops++;
392 		if (count_remaining) {
393 			num_remaining_ops++;
394 		}
395 
396 		/* Decode the opcode */
397 
398 		op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
399 		switch (op_info->class) {
400 		case AML_CLASS_ARGUMENT:
401 
402 			if (count_remaining) {
403 				num_remaining_operands++;
404 			}
405 
406 			num_operands++;
407 			break;
408 
409 		case AML_CLASS_UNKNOWN:
410 
411 			/* Bad opcode or ASCII character */
412 
413 			continue;
414 
415 		default:
416 
417 			if (count_remaining) {
418 				num_remaining_operators++;
419 			}
420 
421 			num_operators++;
422 			break;
423 		}
424 
425 		op = acpi_ps_get_depth_next(start_op, op);
426 	}
427 
428 	acpi_os_printf
429 	    ("Method contains:       %X AML Opcodes - %X Operators, %X Operands\n",
430 	     num_ops, num_operators, num_operands);
431 
432 	acpi_os_printf
433 	    ("Remaining to execute:  %X AML Opcodes - %X Operators, %X Operands\n",
434 	     num_remaining_ops, num_remaining_operators,
435 	     num_remaining_operands);
436 }
437 
438 /*******************************************************************************
439  *
440  * FUNCTION:    acpi_db_display_locals
441  *
442  * PARAMETERS:  None
443  *
444  * RETURN:      None
445  *
446  * DESCRIPTION: Display all locals for the currently running control method
447  *
448  ******************************************************************************/
449 
450 void acpi_db_display_locals(void)
451 {
452 	struct acpi_walk_state *walk_state;
453 
454 	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
455 	if (!walk_state) {
456 		acpi_os_printf("There is no method currently executing\n");
457 		return;
458 	}
459 
460 	acpi_db_decode_locals(walk_state);
461 }
462 
463 /*******************************************************************************
464  *
465  * FUNCTION:    acpi_db_display_arguments
466  *
467  * PARAMETERS:  None
468  *
469  * RETURN:      None
470  *
471  * DESCRIPTION: Display all arguments for the currently running control method
472  *
473  ******************************************************************************/
474 
475 void acpi_db_display_arguments(void)
476 {
477 	struct acpi_walk_state *walk_state;
478 
479 	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
480 	if (!walk_state) {
481 		acpi_os_printf("There is no method currently executing\n");
482 		return;
483 	}
484 
485 	acpi_db_decode_arguments(walk_state);
486 }
487 
488 /*******************************************************************************
489  *
490  * FUNCTION:    acpi_db_display_results
491  *
492  * PARAMETERS:  None
493  *
494  * RETURN:      None
495  *
496  * DESCRIPTION: Display current contents of a method result stack
497  *
498  ******************************************************************************/
499 
500 void acpi_db_display_results(void)
501 {
502 	u32 i;
503 	struct acpi_walk_state *walk_state;
504 	union acpi_operand_object *obj_desc;
505 	u32 result_count = 0;
506 	struct acpi_namespace_node *node;
507 	union acpi_generic_state *frame;
508 	u32 index;		/* Index onto current frame */
509 
510 	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
511 	if (!walk_state) {
512 		acpi_os_printf("There is no method currently executing\n");
513 		return;
514 	}
515 
516 	obj_desc = walk_state->method_desc;
517 	node = walk_state->method_node;
518 
519 	if (walk_state->results) {
520 		result_count = walk_state->result_count;
521 	}
522 
523 	acpi_os_printf("Method [%4.4s] has %X stacked result objects\n",
524 		       acpi_ut_get_node_name(node), result_count);
525 
526 	/* From the top element of result stack */
527 
528 	frame = walk_state->results;
529 	index = (result_count - 1) % ACPI_RESULTS_FRAME_OBJ_NUM;
530 
531 	for (i = 0; i < result_count; i++) {
532 		obj_desc = frame->results.obj_desc[index];
533 		acpi_os_printf("Result%u: ", i);
534 		acpi_db_display_internal_object(obj_desc, walk_state);
535 
536 		if (index == 0) {
537 			frame = frame->results.next;
538 			index = ACPI_RESULTS_FRAME_OBJ_NUM;
539 		}
540 
541 		index--;
542 	}
543 }
544 
545 /*******************************************************************************
546  *
547  * FUNCTION:    acpi_db_display_calling_tree
548  *
549  * PARAMETERS:  None
550  *
551  * RETURN:      None
552  *
553  * DESCRIPTION: Display current calling tree of nested control methods
554  *
555  ******************************************************************************/
556 
557 void acpi_db_display_calling_tree(void)
558 {
559 	struct acpi_walk_state *walk_state;
560 	struct acpi_namespace_node *node;
561 
562 	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
563 	if (!walk_state) {
564 		acpi_os_printf("There is no method currently executing\n");
565 		return;
566 	}
567 
568 	node = walk_state->method_node;
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 
591 void 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 
656 void
657 acpi_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 
691 void
692 acpi_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 
723 void 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 
930 void 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 
970 found_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 
1054 static acpi_status
1055 acpi_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 }
1097