xref: /openbmc/linux/drivers/acpi/acpica/dbdisply.c (revision f21e49be)
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_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 
62 typedef struct acpi_handler_info {
63 	void *handler;
64 	char *name;
65 
66 } acpi_handler_info;
67 
68 static 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 
88 static 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 
110 static 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 
141 void 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 
270 dump_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 
350 void 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 
452 void 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 
477 void 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 
502 void 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 
558 void 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 
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