1/******************************************************************************
2 *
3 * Module Name: nsdump - table dumping routines for debug
4 *              $Revision: 1.1.1.1 $
5 *
6 *****************************************************************************/
7
8/*
9 *  Copyright (C) 2000, 2001 R. Byron Moore
10 *
11 *  This program is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This program is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with this program; if not, write to the Free Software
23 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 */
25
26
27#include "acpi.h"
28#include "acinterp.h"
29#include "acnamesp.h"
30#include "actables.h"
31#include "acparser.h"
32
33
34#define _COMPONENT          ACPI_NAMESPACE
35	 MODULE_NAME         ("nsdump")
36
37
38#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER)
39
40/*******************************************************************************
41 *
42 * FUNCTION:    Acpi_ns_dump_pathname
43 *
44 * PARAMETERS:  Handle              - Object
45 *              Msg                 - Prefix message
46 *              Level               - Desired debug level
47 *              Component           - Caller's component ID
48 *
49 * DESCRIPTION: Print an object's full namespace pathname
50 *              Manages allocation/freeing of a pathname buffer
51 *
52 ******************************************************************************/
53
54acpi_status
55acpi_ns_dump_pathname (
56	acpi_handle             handle,
57	NATIVE_CHAR             *msg,
58	u32                     level,
59	u32                     component)
60{
61	NATIVE_CHAR             *buffer;
62	u32                     length;
63
64
65	FUNCTION_TRACE ("Ns_dump_pathname");
66
67
68	/* Do this only if the requested debug level and component are enabled */
69
70	if (!(acpi_dbg_level & level) || !(acpi_dbg_layer & component)) {
71		return_ACPI_STATUS (AE_OK);
72	}
73
74	buffer = ACPI_MEM_ALLOCATE (PATHNAME_MAX);
75	if (!buffer) {
76		return_ACPI_STATUS (AE_NO_MEMORY);
77	}
78
79	/* Convert handle to a full pathname and print it (with supplied message) */
80
81	length = PATHNAME_MAX;
82	if (ACPI_SUCCESS (acpi_ns_handle_to_pathname (handle, &length, buffer))) {
83		acpi_os_printf ("%s %s (%p)\n", msg, buffer, handle);
84	}
85
86	ACPI_MEM_FREE (buffer);
87
88	return_ACPI_STATUS (AE_OK);
89}
90
91
92/*******************************************************************************
93 *
94 * FUNCTION:    Acpi_ns_dump_one_object
95 *
96 * PARAMETERS:  Handle              - Node to be dumped
97 *              Level               - Nesting level of the handle
98 *              Context             - Passed into Walk_namespace
99 *
100 * DESCRIPTION: Dump a single Node
101 *              This procedure is a User_function called by Acpi_ns_walk_namespace.
102 *
103 ******************************************************************************/
104
105acpi_status
106acpi_ns_dump_one_object (
107	acpi_handle             obj_handle,
108	u32                     level,
109	void                    *context,
110	void                    **return_value)
111{
112	acpi_walk_info          *info = (acpi_walk_info *) context;
113	acpi_namespace_node     *this_node;
114	acpi_operand_object     *obj_desc = NULL;
115	acpi_object_type8       obj_type;
116	acpi_object_type8       type;
117	u32                     bytes_to_dump;
118	u32                     downstream_sibling_mask = 0;
119	u32                     level_tmp;
120	u32                     which_bit;
121	u32                     i;
122
123
124	PROC_NAME ("Ns_dump_one_object");
125
126
127	this_node = acpi_ns_map_handle_to_node (obj_handle);
128
129	level_tmp   = level;
130	type        = this_node->type;
131	which_bit   = 1;
132
133
134	if (!(acpi_dbg_level & info->debug_level)) {
135		return (AE_OK);
136	}
137
138	if (!obj_handle) {
139		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n"));
140		return (AE_OK);
141	}
142
143	/* Check if the owner matches */
144
145	if ((info->owner_id != ACPI_UINT32_MAX) &&
146		(info->owner_id != this_node->owner_id)) {
147		return (AE_OK);
148	}
149
150
151	/* Indent the object according to the level */
152
153	while (level_tmp--) {
154
155		/* Print appropriate characters to form tree structure */
156
157		if (level_tmp) {
158			if (downstream_sibling_mask & which_bit) {
159				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "|"));
160			}
161
162			else {
163				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " "));
164			}
165
166			which_bit <<= 1;
167		}
168
169		else {
170			if (acpi_ns_exist_downstream_sibling (this_node + 1)) {
171				downstream_sibling_mask |= (1 << (level - 1));
172				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+"));
173			}
174
175			else {
176				downstream_sibling_mask &= ACPI_UINT32_MAX ^ (1 << (level - 1));
177				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+"));
178			}
179
180			if (this_node->child == NULL) {
181				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-"));
182			}
183
184			else if (acpi_ns_exist_downstream_sibling (this_node->child)) {
185				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+"));
186			}
187
188			else {
189				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-"));
190			}
191		}
192	}
193
194
195	/* Check the integrity of our data */
196
197	if (type > INTERNAL_TYPE_MAX) {
198		type = INTERNAL_TYPE_DEF_ANY;                                /* prints as *ERROR* */
199	}
200
201	if (!acpi_ut_valid_acpi_name (this_node->name)) {
202		REPORT_WARNING (("Invalid ACPI Name %08X\n", this_node->name));
203	}
204
205	/*
206	 * Now we can print out the pertinent information
207	 */
208	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %4.4s %-12s %p",
209			(char*)&this_node->name, acpi_ut_get_type_name (type), this_node));
210
211	obj_desc = this_node->object;
212
213	switch (info->display_type) {
214	case ACPI_DISPLAY_SUMMARY:
215
216		if (!obj_desc) {
217			/* No attached object, we are done */
218
219			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
220			return (AE_OK);
221		}
222
223
224		switch (type) {
225		case ACPI_TYPE_PROCESSOR:
226			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ID %d Addr %.4X Len %.4X\n",
227					 obj_desc->processor.proc_id,
228					 obj_desc->processor.address,
229					 (unsigned)obj_desc->processor.length));
230			break;
231
232		case ACPI_TYPE_DEVICE:
233			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Notification object: %p", obj_desc));
234			break;
235
236		case ACPI_TYPE_METHOD:
237			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Args %d Len %.4X Aml %p \n",
238					 obj_desc->method.param_count,
239					 obj_desc->method.aml_length,
240					 obj_desc->method.aml_start));
241			break;
242
243		case ACPI_TYPE_INTEGER:
244			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " = %8.8X%8.8X\n",
245					 HIDWORD (obj_desc->integer.value),
246					 LODWORD (obj_desc->integer.value)));
247			break;
248
249		case ACPI_TYPE_PACKAGE:
250			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Elements %.2X\n",
251					 obj_desc->package.count));
252			break;
253
254		case ACPI_TYPE_BUFFER:
255			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Len %.2X",
256					 obj_desc->buffer.length));
257
258			/* Dump some of the buffer */
259
260			if (obj_desc->buffer.length > 0) {
261				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ="));
262				for (i = 0; (i < obj_desc->buffer.length && i < 12); i++) {
263					ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %.2X",
264							obj_desc->buffer.pointer[i]));
265				}
266			}
267			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
268			break;
269
270		case ACPI_TYPE_STRING:
271			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Len %.2X",
272					 obj_desc->string.length));
273
274			if (obj_desc->string.length > 0) {
275				 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " = \"%.32s\"...",
276						 obj_desc->string.pointer));
277			}
278			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
279			break;
280
281		case ACPI_TYPE_REGION:
282			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " [%s]",
283					 acpi_ut_get_region_name (obj_desc->region.space_id)));
284			if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
285				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Addr %8.8X%8.8X Len %.4X\n",
286						 HIDWORD(obj_desc->region.address),
287						 LODWORD(obj_desc->region.address),
288						 obj_desc->region.length));
289			}
290			else {
291				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " [Address/Length not evaluated]\n"));
292			}
293			break;
294
295		case INTERNAL_TYPE_REFERENCE:
296			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " [%s]\n",
297					 acpi_ps_get_opcode_name (obj_desc->reference.opcode)));
298			break;
299
300		case ACPI_TYPE_BUFFER_FIELD:
301
302			/* TBD: print Buffer name when we can easily get it */
303			break;
304
305		case INTERNAL_TYPE_REGION_FIELD:
306			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Rgn [%4.4s]",
307					 (char *) &obj_desc->common_field.region_obj->region.node->name));
308			break;
309
310		case INTERNAL_TYPE_BANK_FIELD:
311			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Rgn [%4.4s]",
312					 (char *) &obj_desc->common_field.region_obj->region.node->name));
313			break;
314
315		case INTERNAL_TYPE_INDEX_FIELD:
316			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Rgn [%4.4s]",
317					 (char *) &obj_desc->index_field.index_obj->common_field.region_obj->region.node->name));
318			break;
319
320		default:
321
322			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Object %p\n", obj_desc));
323			break;
324		}
325
326		/* Common field handling */
327
328		switch (type) {
329		case ACPI_TYPE_BUFFER_FIELD:
330		case INTERNAL_TYPE_REGION_FIELD:
331		case INTERNAL_TYPE_BANK_FIELD:
332		case INTERNAL_TYPE_INDEX_FIELD:
333			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Off %.2X Len %.2X Acc %.2d\n",
334					 (obj_desc->common_field.base_byte_offset * 8) + obj_desc->common_field.start_field_bit_offset,
335					 obj_desc->common_field.bit_length,
336					 obj_desc->common_field.access_bit_width));
337			break;
338		}
339
340		break;
341
342
343	case ACPI_DISPLAY_OBJECTS:
344
345		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "%p O:%p",
346				this_node, obj_desc));
347
348		if (!obj_desc) {
349			/* No attached object, we are done */
350
351			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
352			return (AE_OK);
353		}
354
355		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(R%d)",
356				obj_desc->common.reference_count));
357
358		switch (type) {
359
360		case ACPI_TYPE_METHOD:
361
362			/* Name is a Method and its AML offset/length are set */
363
364			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " M:%p-%X\n",
365					 obj_desc->method.aml_start,
366					 obj_desc->method.aml_length));
367
368			break;
369
370
371		case ACPI_TYPE_INTEGER:
372
373			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " N:%X%X\n",
374					 HIDWORD(obj_desc->integer.value),
375					 LODWORD(obj_desc->integer.value)));
376			break;
377
378
379		case ACPI_TYPE_STRING:
380
381			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " S:%p-%X\n",
382					 obj_desc->string.pointer,
383					 obj_desc->string.length));
384			break;
385
386
387		case ACPI_TYPE_BUFFER:
388
389			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " B:%p-%X\n",
390					 obj_desc->buffer.pointer,
391					 obj_desc->buffer.length));
392			break;
393
394
395		default:
396
397			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
398			break;
399		}
400		break;
401	}
402
403	/* If debug turned off, done */
404
405	if (!(acpi_dbg_level & ACPI_LV_VALUES)) {
406		return (AE_OK);
407	}
408
409
410	/* If there is an attached object, display it */
411
412	obj_desc = this_node->object;
413
414	/* Dump attached objects */
415
416	while (obj_desc) {
417		obj_type = INTERNAL_TYPE_INVALID;
418
419		/* Decode the type of attached object and dump the contents */
420
421		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "        Attached Object %p: ", obj_desc));
422
423		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
424			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to Node)\n"));
425			bytes_to_dump = sizeof (acpi_namespace_node);
426		}
427
428
429		else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
430			obj_type = obj_desc->common.type;
431
432			if (obj_type > INTERNAL_TYPE_MAX) {
433				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [UNKNOWN])\n", obj_type));
434				bytes_to_dump = 32;
435			}
436
437			else {
438				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %2.2X [%s])\n",
439						   obj_type, acpi_ut_get_type_name (obj_type)));
440				bytes_to_dump = sizeof (acpi_operand_object);
441			}
442		}
443
444		else {
445			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(String or Buffer - not descriptor)\n"));
446			bytes_to_dump = 16;
447		}
448
449		DUMP_BUFFER (obj_desc, bytes_to_dump);
450
451		/* If value is NOT an internal object, we are done */
452
453		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
454			goto cleanup;
455		}
456
457		/*
458		 * Valid object, get the pointer to next level, if any
459		 */
460		switch (obj_type) {
461		case ACPI_TYPE_STRING:
462			obj_desc = (acpi_operand_object *) obj_desc->string.pointer;
463			break;
464
465		case ACPI_TYPE_BUFFER:
466			obj_desc = (acpi_operand_object *) obj_desc->buffer.pointer;
467			break;
468
469		case ACPI_TYPE_BUFFER_FIELD:
470			obj_desc = (acpi_operand_object *) obj_desc->buffer_field.buffer_obj;
471			break;
472
473		case ACPI_TYPE_PACKAGE:
474			obj_desc = (acpi_operand_object *) obj_desc->package.elements;
475			break;
476
477		case ACPI_TYPE_METHOD:
478			obj_desc = (acpi_operand_object *) obj_desc->method.aml_start;
479			break;
480
481		case INTERNAL_TYPE_REGION_FIELD:
482			obj_desc = (acpi_operand_object *) obj_desc->field.region_obj;
483			break;
484
485		case INTERNAL_TYPE_BANK_FIELD:
486			obj_desc = (acpi_operand_object *) obj_desc->bank_field.region_obj;
487			break;
488
489		case INTERNAL_TYPE_INDEX_FIELD:
490			obj_desc = (acpi_operand_object *) obj_desc->index_field.index_obj;
491			break;
492
493	   default:
494			goto cleanup;
495		}
496
497		obj_type = INTERNAL_TYPE_INVALID;    /* Terminate loop after next pass */
498	}
499
500cleanup:
501	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
502	return (AE_OK);
503}
504
505
506/*******************************************************************************
507 *
508 * FUNCTION:    Acpi_ns_dump_objects
509 *
510 * PARAMETERS:  Type                - Object type to be dumped
511 *              Max_depth           - Maximum depth of dump.  Use ACPI_UINT32_MAX
512 *                                    for an effectively unlimited depth.
513 *              Owner_id            - Dump only objects owned by this ID.  Use
514 *                                    ACPI_UINT32_MAX to match all owners.
515 *              Start_handle        - Where in namespace to start/end search
516 *
517 * DESCRIPTION: Dump typed objects within the loaded namespace.
518 *              Uses Acpi_ns_walk_namespace in conjunction with Acpi_ns_dump_one_object.
519 *
520 ******************************************************************************/
521
522void
523acpi_ns_dump_objects (
524	acpi_object_type8       type,
525	u8                      display_type,
526	u32                     max_depth,
527	u32                     owner_id,
528	acpi_handle             start_handle)
529{
530	acpi_walk_info          info;
531
532
533	FUNCTION_ENTRY ();
534
535
536	info.debug_level = ACPI_LV_TABLES;
537	info.owner_id = owner_id;
538	info.display_type = display_type;
539
540
541	acpi_ns_walk_namespace (type, start_handle, max_depth, NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object,
542			   (void *) &info, NULL);
543}
544
545
546#ifndef _ACPI_ASL_COMPILER
547/*******************************************************************************
548 *
549 * FUNCTION:    Acpi_ns_dump_one_device
550 *
551 * PARAMETERS:  Handle              - Node to be dumped
552 *              Level               - Nesting level of the handle
553 *              Context             - Passed into Walk_namespace
554 *
555 * DESCRIPTION: Dump a single Node that represents a device
556 *              This procedure is a User_function called by Acpi_ns_walk_namespace.
557 *
558 ******************************************************************************/
559
560acpi_status
561acpi_ns_dump_one_device (
562	acpi_handle             obj_handle,
563	u32                     level,
564	void                    *context,
565	void                    **return_value)
566{
567	acpi_device_info        info;
568	acpi_status             status;
569	u32                     i;
570
571
572	PROC_NAME ("Ns_dump_one_device");
573
574
575	status = acpi_ns_dump_one_object (obj_handle, level, context, return_value);
576
577	status = acpi_get_object_info (obj_handle, &info);
578	if (ACPI_SUCCESS (status)) {
579		for (i = 0; i < level; i++) {
580			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " "));
581		}
582
583		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "    HID: %s, ADR: %8.8X%8.8X, Status: %x\n",
584				  info.hardware_id, HIDWORD(info.address), LODWORD(info.address), info.current_status));
585	}
586
587	return (status);
588}
589
590
591/*******************************************************************************
592 *
593 * FUNCTION:    Acpi_ns_dump_root_devices
594 *
595 * PARAMETERS:  None
596 *
597 * DESCRIPTION: Dump all objects of type "device"
598 *
599 ******************************************************************************/
600
601void
602acpi_ns_dump_root_devices (void)
603{
604	acpi_handle             sys_bus_handle;
605
606
607	PROC_NAME ("Ns_dump_root_devices");
608
609
610	/* Only dump the table if tracing is enabled */
611
612	if (!(ACPI_LV_TABLES & acpi_dbg_level)) {
613		return;
614	}
615
616	acpi_get_handle (0, NS_SYSTEM_BUS, &sys_bus_handle);
617
618	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Display of all devices in the namespace:\n"));
619	acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, sys_bus_handle, ACPI_UINT32_MAX, NS_WALK_NO_UNLOCK,
620			   acpi_ns_dump_one_device, NULL, NULL);
621}
622
623#endif
624
625/*******************************************************************************
626 *
627 * FUNCTION:    Acpi_ns_dump_tables
628 *
629 * PARAMETERS:  Search_base         - Root of subtree to be dumped, or
630 *                                    NS_ALL to dump the entire namespace
631 *              Max_depth           - Maximum depth of dump.  Use INT_MAX
632 *                                    for an effectively unlimited depth.
633 *
634 * DESCRIPTION: Dump the name space, or a portion of it.
635 *
636 ******************************************************************************/
637
638void
639acpi_ns_dump_tables (
640	acpi_handle             search_base,
641	u32                     max_depth)
642{
643	acpi_handle             search_handle = search_base;
644
645
646	FUNCTION_TRACE ("Ns_dump_tables");
647
648
649	if (!acpi_gbl_root_node) {
650		/*
651		 * If the name space has not been initialized,
652		 * there is nothing to dump.
653		 */
654		ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "name space not initialized!\n"));
655		return_VOID;
656	}
657
658	if (NS_ALL == search_base) {
659		/*  entire namespace    */
660
661		search_handle = acpi_gbl_root_node;
662		ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n"));
663	}
664
665
666	acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
667			ACPI_UINT32_MAX, search_handle);
668	return_VOID;
669}
670
671
672/*******************************************************************************
673 *
674 * FUNCTION:    Acpi_ns_dump_entry
675 *
676 * PARAMETERS:  Handle              - Node to be dumped
677 *              Debug_level         - Output level
678 *
679 * DESCRIPTION: Dump a single Node
680 *
681 ******************************************************************************/
682
683void
684acpi_ns_dump_entry (
685	acpi_handle             handle,
686	u32                     debug_level)
687{
688	acpi_walk_info          info;
689
690
691	FUNCTION_ENTRY ();
692
693
694	info.debug_level = debug_level;
695	info.owner_id = ACPI_UINT32_MAX;
696
697	acpi_ns_dump_one_object (handle, 1, &info, NULL);
698}
699
700#endif
701
702