xref: /openbmc/linux/drivers/acpi/acpica/dbdisply.c (revision 76426e23)
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 	node = walk_state->method_node;
517 
518 	if (walk_state->results) {
519 		result_count = walk_state->result_count;
520 	}
521 
522 	acpi_os_printf("Method [%4.4s] has %X stacked result objects\n",
523 		       acpi_ut_get_node_name(node), result_count);
524 
525 	/* From the top element of result stack */
526 
527 	frame = walk_state->results;
528 	index = (result_count - 1) % ACPI_RESULTS_FRAME_OBJ_NUM;
529 
530 	for (i = 0; i < result_count; i++) {
531 		obj_desc = frame->results.obj_desc[index];
532 		acpi_os_printf("Result%u: ", i);
533 		acpi_db_display_internal_object(obj_desc, walk_state);
534 
535 		if (index == 0) {
536 			frame = frame->results.next;
537 			index = ACPI_RESULTS_FRAME_OBJ_NUM;
538 		}
539 
540 		index--;
541 	}
542 }
543 
544 /*******************************************************************************
545  *
546  * FUNCTION:    acpi_db_display_calling_tree
547  *
548  * PARAMETERS:  None
549  *
550  * RETURN:      None
551  *
552  * DESCRIPTION: Display current calling tree of nested control methods
553  *
554  ******************************************************************************/
555 
556 void acpi_db_display_calling_tree(void)
557 {
558 	struct acpi_walk_state *walk_state;
559 	struct acpi_namespace_node *node;
560 
561 	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
562 	if (!walk_state) {
563 		acpi_os_printf("There is no method currently executing\n");
564 		return;
565 	}
566 
567 	acpi_os_printf("Current Control Method Call Tree\n");
568 
569 	while (walk_state) {
570 		node = walk_state->method_node;
571 		acpi_os_printf("  [%4.4s]\n", acpi_ut_get_node_name(node));
572 
573 		walk_state = walk_state->next;
574 	}
575 }
576 
577 /*******************************************************************************
578  *
579  * FUNCTION:    acpi_db_display_object_type
580  *
581  * PARAMETERS:  object_arg      - User entered NS node handle
582  *
583  * RETURN:      None
584  *
585  * DESCRIPTION: Display type of an arbitrary NS node
586  *
587  ******************************************************************************/
588 
589 void acpi_db_display_object_type(char *object_arg)
590 {
591 	acpi_size arg;
592 	acpi_handle handle;
593 	struct acpi_device_info *info;
594 	acpi_status status;
595 	u32 i;
596 
597 	arg = strtoul(object_arg, NULL, 16);
598 	handle = ACPI_TO_POINTER(arg);
599 
600 	status = acpi_get_object_info(handle, &info);
601 	if (ACPI_FAILURE(status)) {
602 		acpi_os_printf("Could not get object info, %s\n",
603 			       acpi_format_exception(status));
604 		return;
605 	}
606 
607 	acpi_os_printf("ADR: %8.8X%8.8X, Flags: %X\n",
608 		       ACPI_FORMAT_UINT64(info->address), info->flags);
609 
610 	acpi_os_printf("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n",
611 		       info->highest_dstates[0], info->highest_dstates[1],
612 		       info->highest_dstates[2], info->highest_dstates[3]);
613 
614 	acpi_os_printf("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n",
615 		       info->lowest_dstates[0], info->lowest_dstates[1],
616 		       info->lowest_dstates[2], info->lowest_dstates[3],
617 		       info->lowest_dstates[4]);
618 
619 	if (info->valid & ACPI_VALID_HID) {
620 		acpi_os_printf("HID: %s\n", info->hardware_id.string);
621 	}
622 
623 	if (info->valid & ACPI_VALID_UID) {
624 		acpi_os_printf("UID: %s\n", info->unique_id.string);
625 	}
626 
627 	if (info->valid & ACPI_VALID_CID) {
628 		for (i = 0; i < info->compatible_id_list.count; i++) {
629 			acpi_os_printf("CID %u: %s\n", i,
630 				       info->compatible_id_list.ids[i].string);
631 		}
632 	}
633 
634 	ACPI_FREE(info);
635 }
636 
637 /*******************************************************************************
638  *
639  * FUNCTION:    acpi_db_display_result_object
640  *
641  * PARAMETERS:  obj_desc        - Object to be displayed
642  *              walk_state      - Current walk state
643  *
644  * RETURN:      None
645  *
646  * DESCRIPTION: Display the result of an AML opcode
647  *
648  * Note: Currently only displays the result object if we are single stepping.
649  * However, this output may be useful in other contexts and could be enabled
650  * to do so if needed.
651  *
652  ******************************************************************************/
653 
654 void
655 acpi_db_display_result_object(union acpi_operand_object *obj_desc,
656 			      struct acpi_walk_state *walk_state)
657 {
658 
659 #ifndef ACPI_APPLICATION
660 	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
661 		return;
662 	}
663 #endif
664 
665 	/* Only display if single stepping */
666 
667 	if (!acpi_gbl_cm_single_step) {
668 		return;
669 	}
670 
671 	acpi_os_printf("ResultObj: ");
672 	acpi_db_display_internal_object(obj_desc, walk_state);
673 	acpi_os_printf("\n");
674 }
675 
676 /*******************************************************************************
677  *
678  * FUNCTION:    acpi_db_display_argument_object
679  *
680  * PARAMETERS:  obj_desc        - Object to be displayed
681  *              walk_state      - Current walk state
682  *
683  * RETURN:      None
684  *
685  * DESCRIPTION: Display the result of an AML opcode
686  *
687  ******************************************************************************/
688 
689 void
690 acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
691 				struct acpi_walk_state *walk_state)
692 {
693 
694 #ifndef ACPI_APPLICATION
695 	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
696 		return;
697 	}
698 #endif
699 
700 	if (!acpi_gbl_cm_single_step) {
701 		return;
702 	}
703 
704 	acpi_os_printf("ArgObj:  ");
705 	acpi_db_display_internal_object(obj_desc, walk_state);
706 }
707 
708 #if (!ACPI_REDUCED_HARDWARE)
709 /*******************************************************************************
710  *
711  * FUNCTION:    acpi_db_display_gpes
712  *
713  * PARAMETERS:  None
714  *
715  * RETURN:      None
716  *
717  * DESCRIPTION: Display the current GPE structures
718  *
719  ******************************************************************************/
720 
721 void acpi_db_display_gpes(void)
722 {
723 	struct acpi_gpe_block_info *gpe_block;
724 	struct acpi_gpe_xrupt_info *gpe_xrupt_info;
725 	struct acpi_gpe_event_info *gpe_event_info;
726 	struct acpi_gpe_register_info *gpe_register_info;
727 	char *gpe_type;
728 	struct acpi_gpe_notify_info *notify;
729 	u32 gpe_index;
730 	u32 block = 0;
731 	u32 i;
732 	u32 j;
733 	u32 count;
734 	char buffer[80];
735 	struct acpi_buffer ret_buf;
736 	acpi_status status;
737 
738 	ret_buf.length = sizeof(buffer);
739 	ret_buf.pointer = buffer;
740 
741 	block = 0;
742 
743 	/* Walk the GPE lists */
744 
745 	gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
746 	while (gpe_xrupt_info) {
747 		gpe_block = gpe_xrupt_info->gpe_block_list_head;
748 		while (gpe_block) {
749 			status = acpi_get_name(gpe_block->node,
750 					       ACPI_FULL_PATHNAME_NO_TRAILING,
751 					       &ret_buf);
752 			if (ACPI_FAILURE(status)) {
753 				acpi_os_printf
754 				    ("Could not convert name to pathname\n");
755 			}
756 
757 			if (gpe_block->node == acpi_gbl_fadt_gpe_device) {
758 				gpe_type = "FADT-defined GPE block";
759 			} else {
760 				gpe_type = "GPE Block Device";
761 			}
762 
763 			acpi_os_printf
764 			    ("\nBlock %u - Info %p  DeviceNode %p [%s] - %s\n",
765 			     block, gpe_block, gpe_block->node, buffer,
766 			     gpe_type);
767 
768 			acpi_os_printf("    Registers:    %u (%u GPEs)\n",
769 				       gpe_block->register_count,
770 				       gpe_block->gpe_count);
771 
772 			acpi_os_printf
773 			    ("    GPE range:    0x%X to 0x%X on interrupt %u\n",
774 			     gpe_block->block_base_number,
775 			     gpe_block->block_base_number +
776 			     (gpe_block->gpe_count - 1),
777 			     gpe_xrupt_info->interrupt_number);
778 
779 			acpi_os_printf
780 			    ("    RegisterInfo: %p  Status %8.8X%8.8X Enable %8.8X%8.8X\n",
781 			     gpe_block->register_info,
782 			     ACPI_FORMAT_UINT64(gpe_block->register_info->
783 						status_address.address),
784 			     ACPI_FORMAT_UINT64(gpe_block->register_info->
785 						enable_address.address));
786 
787 			acpi_os_printf("  EventInfo:    %p\n",
788 				       gpe_block->event_info);
789 
790 			/* Examine each GPE Register within the block */
791 
792 			for (i = 0; i < gpe_block->register_count; i++) {
793 				gpe_register_info =
794 				    &gpe_block->register_info[i];
795 
796 				acpi_os_printf("    Reg %u: (GPE %.2X-%.2X)  "
797 					       "RunEnable %2.2X WakeEnable %2.2X"
798 					       " Status %8.8X%8.8X Enable %8.8X%8.8X\n",
799 					       i,
800 					       gpe_register_info->
801 					       base_gpe_number,
802 					       gpe_register_info->
803 					       base_gpe_number +
804 					       (ACPI_GPE_REGISTER_WIDTH - 1),
805 					       gpe_register_info->
806 					       enable_for_run,
807 					       gpe_register_info->
808 					       enable_for_wake,
809 					       ACPI_FORMAT_UINT64
810 					       (gpe_register_info->
811 						status_address.address),
812 					       ACPI_FORMAT_UINT64
813 					       (gpe_register_info->
814 						enable_address.address));
815 
816 				/* Now look at the individual GPEs in this byte register */
817 
818 				for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
819 					gpe_index =
820 					    (i * ACPI_GPE_REGISTER_WIDTH) + j;
821 					gpe_event_info =
822 					    &gpe_block->event_info[gpe_index];
823 
824 					if (ACPI_GPE_DISPATCH_TYPE
825 					    (gpe_event_info->flags) ==
826 					    ACPI_GPE_DISPATCH_NONE) {
827 
828 						/* This GPE is not used (no method or handler), ignore it */
829 
830 						continue;
831 					}
832 
833 					acpi_os_printf
834 					    ("        GPE %.2X: %p  RunRefs %2.2X Flags %2.2X (",
835 					     gpe_block->block_base_number +
836 					     gpe_index, gpe_event_info,
837 					     gpe_event_info->runtime_count,
838 					     gpe_event_info->flags);
839 
840 					/* Decode the flags byte */
841 
842 					if (gpe_event_info->
843 					    flags & ACPI_GPE_LEVEL_TRIGGERED) {
844 						acpi_os_printf("Level, ");
845 					} else {
846 						acpi_os_printf("Edge, ");
847 					}
848 
849 					if (gpe_event_info->
850 					    flags & ACPI_GPE_CAN_WAKE) {
851 						acpi_os_printf("CanWake, ");
852 					} else {
853 						acpi_os_printf("RunOnly, ");
854 					}
855 
856 					switch (ACPI_GPE_DISPATCH_TYPE
857 						(gpe_event_info->flags)) {
858 					case ACPI_GPE_DISPATCH_NONE:
859 
860 						acpi_os_printf("NotUsed");
861 						break;
862 
863 					case ACPI_GPE_DISPATCH_METHOD:
864 
865 						acpi_os_printf("Method");
866 						break;
867 
868 					case ACPI_GPE_DISPATCH_HANDLER:
869 
870 						acpi_os_printf("Handler");
871 						break;
872 
873 					case ACPI_GPE_DISPATCH_NOTIFY:
874 
875 						count = 0;
876 						notify =
877 						    gpe_event_info->dispatch.
878 						    notify_list;
879 						while (notify) {
880 							count++;
881 							notify = notify->next;
882 						}
883 
884 						acpi_os_printf
885 						    ("Implicit Notify on %u devices",
886 						     count);
887 						break;
888 
889 					case ACPI_GPE_DISPATCH_RAW_HANDLER:
890 
891 						acpi_os_printf("RawHandler");
892 						break;
893 
894 					default:
895 
896 						acpi_os_printf("UNKNOWN: %X",
897 							       ACPI_GPE_DISPATCH_TYPE
898 							       (gpe_event_info->
899 								flags));
900 						break;
901 					}
902 
903 					acpi_os_printf(")\n");
904 				}
905 			}
906 
907 			block++;
908 			gpe_block = gpe_block->next;
909 		}
910 
911 		gpe_xrupt_info = gpe_xrupt_info->next;
912 	}
913 }
914 #endif				/* !ACPI_REDUCED_HARDWARE */
915 
916 /*******************************************************************************
917  *
918  * FUNCTION:    acpi_db_display_handlers
919  *
920  * PARAMETERS:  None
921  *
922  * RETURN:      None
923  *
924  * DESCRIPTION: Display the currently installed global handlers
925  *
926  ******************************************************************************/
927 
928 void acpi_db_display_handlers(void)
929 {
930 	union acpi_operand_object *obj_desc;
931 	union acpi_operand_object *handler_obj;
932 	acpi_adr_space_type space_id;
933 	u32 i;
934 
935 	/* Operation region handlers */
936 
937 	acpi_os_printf("\nOperation Region Handlers at the namespace root:\n");
938 
939 	obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node);
940 	if (obj_desc) {
941 		for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_space_id_list); i++) {
942 			space_id = acpi_gbl_space_id_list[i];
943 
944 			acpi_os_printf(ACPI_PREDEFINED_PREFIX,
945 				       acpi_ut_get_region_name((u8)space_id),
946 				       space_id);
947 
948 			handler_obj =
949 			    acpi_ev_find_region_handler(space_id,
950 							obj_desc->common_notify.
951 							handler);
952 			if (handler_obj) {
953 				acpi_os_printf(ACPI_HANDLER_PRESENT_STRING,
954 					       (handler_obj->address_space.
955 						handler_flags &
956 						ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
957 					       ? "Default" : "User",
958 					       handler_obj->address_space.
959 					       handler);
960 
961 				goto found_handler;
962 			}
963 
964 			/* There is no handler for this space_id */
965 
966 			acpi_os_printf("None\n");
967 
968 found_handler:		;
969 		}
970 
971 		/* Find all handlers for user-defined space_IDs */
972 
973 		handler_obj = obj_desc->common_notify.handler;
974 		while (handler_obj) {
975 			if (handler_obj->address_space.space_id >=
976 			    ACPI_USER_REGION_BEGIN) {
977 				acpi_os_printf(ACPI_PREDEFINED_PREFIX,
978 					       "User-defined ID",
979 					       handler_obj->address_space.
980 					       space_id);
981 				acpi_os_printf(ACPI_HANDLER_PRESENT_STRING,
982 					       (handler_obj->address_space.
983 						handler_flags &
984 						ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
985 					       ? "Default" : "User",
986 					       handler_obj->address_space.
987 					       handler);
988 			}
989 
990 			handler_obj = handler_obj->address_space.next;
991 		}
992 	}
993 #if (!ACPI_REDUCED_HARDWARE)
994 
995 	/* Fixed event handlers */
996 
997 	acpi_os_printf("\nFixed Event Handlers:\n");
998 
999 	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
1000 		acpi_os_printf(ACPI_PREDEFINED_PREFIX,
1001 			       acpi_ut_get_event_name(i), i);
1002 		if (acpi_gbl_fixed_event_handlers[i].handler) {
1003 			acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User",
1004 				       acpi_gbl_fixed_event_handlers[i].
1005 				       handler);
1006 		} else {
1007 			acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None");
1008 		}
1009 	}
1010 
1011 #endif				/* !ACPI_REDUCED_HARDWARE */
1012 
1013 	/* Miscellaneous global handlers */
1014 
1015 	acpi_os_printf("\nMiscellaneous Global Handlers:\n");
1016 
1017 	for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_handler_list); i++) {
1018 		acpi_os_printf(ACPI_HANDLER_NAME_STRING,
1019 			       acpi_gbl_handler_list[i].name);
1020 
1021 		if (acpi_gbl_handler_list[i].handler) {
1022 			acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User",
1023 				       acpi_gbl_handler_list[i].handler);
1024 		} else {
1025 			acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None");
1026 		}
1027 	}
1028 
1029 	/* Other handlers that are installed throughout the namespace */
1030 
1031 	acpi_os_printf("\nOperation Region Handlers for specific devices:\n");
1032 
1033 	(void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1034 				  ACPI_UINT32_MAX,
1035 				  acpi_db_display_non_root_handlers, NULL, NULL,
1036 				  NULL);
1037 }
1038 
1039 /*******************************************************************************
1040  *
1041  * FUNCTION:    acpi_db_display_non_root_handlers
1042  *
1043  * PARAMETERS:  acpi_walk_callback
1044  *
1045  * RETURN:      Status
1046  *
1047  * DESCRIPTION: Display information about all handlers installed for a
1048  *              device object.
1049  *
1050  ******************************************************************************/
1051 
1052 static acpi_status
1053 acpi_db_display_non_root_handlers(acpi_handle obj_handle,
1054 				  u32 nesting_level,
1055 				  void *context, void **return_value)
1056 {
1057 	struct acpi_namespace_node *node =
1058 	    ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
1059 	union acpi_operand_object *obj_desc;
1060 	union acpi_operand_object *handler_obj;
1061 	char *pathname;
1062 
1063 	obj_desc = acpi_ns_get_attached_object(node);
1064 	if (!obj_desc) {
1065 		return (AE_OK);
1066 	}
1067 
1068 	pathname = acpi_ns_get_normalized_pathname(node, TRUE);
1069 	if (!pathname) {
1070 		return (AE_OK);
1071 	}
1072 
1073 	/* Display all handlers associated with this device */
1074 
1075 	handler_obj = obj_desc->common_notify.handler;
1076 	while (handler_obj) {
1077 		acpi_os_printf(ACPI_PREDEFINED_PREFIX,
1078 			       acpi_ut_get_region_name((u8)handler_obj->
1079 						       address_space.space_id),
1080 			       handler_obj->address_space.space_id);
1081 
1082 		acpi_os_printf(ACPI_HANDLER_PRESENT_STRING2,
1083 			       (handler_obj->address_space.handler_flags &
1084 				ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default"
1085 			       : "User", handler_obj->address_space.handler);
1086 
1087 		acpi_os_printf(" Device Name: %s (%p)\n", pathname, node);
1088 
1089 		handler_obj = handler_obj->address_space.next;
1090 	}
1091 
1092 	ACPI_FREE(pathname);
1093 	return (AE_OK);
1094 }
1095