Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: dbnames - Debugger commands for the acpi namespace
4
 *
5
 ******************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2015, Intel Corp.
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions, and the following disclaimer,
16
 *    without modification.
17
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18
 *    substantially similar to the "NO WARRANTY" disclaimer below
19
 *    ("Disclaimer") and any redistribution must be conditioned upon
20
 *    including a substantially similar Disclaimer requirement for further
21
 *    binary redistribution.
22
 * 3. Neither the names of the above-listed copyright holders nor the names
23
 *    of any contributors may be used to endorse or promote products derived
24
 *    from this software without specific prior written permission.
25
 *
26
 * Alternatively, this software may be distributed under the terms of the
27
 * GNU General Public License ("GPL") version 2 as published by the Free
28
 * Software Foundation.
29
 *
30
 * NO WARRANTY
31
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41
 * POSSIBILITY OF SUCH DAMAGES.
42
 */
43
 
44
#include 
45
#include "accommon.h"
46
#include "acnamesp.h"
47
#include "acdebug.h"
48
#include "acpredef.h"
49
 
50
#define _COMPONENT          ACPI_CA_DEBUGGER
51
ACPI_MODULE_NAME("dbnames")
52
 
53
/* Local prototypes */
54
static acpi_status
55
acpi_db_walk_and_match_name(acpi_handle obj_handle,
56
			    u32 nesting_level,
57
			    void *context, void **return_value);
58
 
59
static acpi_status
60
acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
61
				  u32 nesting_level,
62
				  void *context, void **return_value);
63
 
64
static acpi_status
65
acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
66
				  u32 nesting_level,
67
				  void *context, void **return_value);
68
 
69
static acpi_status
70
acpi_db_walk_for_object_counts(acpi_handle obj_handle,
71
			       u32 nesting_level,
72
			       void *context, void **return_value);
73
 
74
static acpi_status
75
acpi_db_integrity_walk(acpi_handle obj_handle,
76
		       u32 nesting_level, void *context, void **return_value);
77
 
78
static acpi_status
79
acpi_db_walk_for_references(acpi_handle obj_handle,
80
			    u32 nesting_level,
81
			    void *context, void **return_value);
82
 
83
static acpi_status
84
acpi_db_bus_walk(acpi_handle obj_handle,
85
		 u32 nesting_level, void *context, void **return_value);
86
 
87
/*
88
 * Arguments for the Objects command
89
 * These object types map directly to the ACPI_TYPES
90
 */
91
static struct acpi_db_argument_info acpi_db_object_types[] = {
92
	{"ANY"},
93
	{"INTEGERS"},
94
	{"STRINGS"},
95
	{"BUFFERS"},
96
	{"PACKAGES"},
97
	{"FIELDS"},
98
	{"DEVICES"},
99
	{"EVENTS"},
100
	{"METHODS"},
101
	{"MUTEXES"},
102
	{"REGIONS"},
103
	{"POWERRESOURCES"},
104
	{"PROCESSORS"},
105
	{"THERMALZONES"},
106
	{"BUFFERFIELDS"},
107
	{"DDBHANDLES"},
108
	{"DEBUG"},
109
	{"REGIONFIELDS"},
110
	{"BANKFIELDS"},
111
	{"INDEXFIELDS"},
112
	{"REFERENCES"},
113
	{"ALIASES"},
114
	{"METHODALIASES"},
115
	{"NOTIFY"},
116
	{"ADDRESSHANDLER"},
117
	{"RESOURCE"},
118
	{"RESOURCEFIELD"},
119
	{"SCOPES"},
120
	{NULL}			/* Must be null terminated */
121
};
122
 
123
/*******************************************************************************
124
 *
125
 * FUNCTION:    acpi_db_set_scope
126
 *
127
 * PARAMETERS:  name                - New scope path
128
 *
129
 * RETURN:      Status
130
 *
131
 * DESCRIPTION: Set the "current scope" as maintained by this utility.
132
 *              The scope is used as a prefix to ACPI paths.
133
 *
134
 ******************************************************************************/
135
 
136
void acpi_db_set_scope(char *name)
137
{
138
	acpi_status status;
139
	struct acpi_namespace_node *node;
140
 
141
	if (!name || name[0] == 0) {
142
		acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf);
143
		return;
144
	}
145
 
146
	acpi_db_prep_namestring(name);
147
 
148
	if (ACPI_IS_ROOT_PREFIX(name[0])) {
149
 
150
		/* Validate new scope from the root */
151
 
152
		status = acpi_ns_get_node(acpi_gbl_root_node, name,
153
					  ACPI_NS_NO_UPSEARCH, &node);
154
		if (ACPI_FAILURE(status)) {
155
			goto error_exit;
156
		}
157
 
158
		acpi_gbl_db_scope_buf[0] = 0;
159
	} else {
160
		/* Validate new scope relative to old scope */
161
 
162
		status = acpi_ns_get_node(acpi_gbl_db_scope_node, name,
163
					  ACPI_NS_NO_UPSEARCH, &node);
164
		if (ACPI_FAILURE(status)) {
165
			goto error_exit;
166
		}
167
	}
168
 
169
	/* Build the final pathname */
170
 
171
	if (acpi_ut_safe_strcat
172
	    (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) {
173
		status = AE_BUFFER_OVERFLOW;
174
		goto error_exit;
175
	}
176
 
177
	if (acpi_ut_safe_strcat
178
	    (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) {
179
		status = AE_BUFFER_OVERFLOW;
180
		goto error_exit;
181
	}
182
 
183
	acpi_gbl_db_scope_node = node;
184
	acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf);
185
	return;
186
 
187
error_exit:
188
 
189
	acpi_os_printf("Could not attach scope: %s, %s\n",
190
		       name, acpi_format_exception(status));
191
}
192
 
193
/*******************************************************************************
194
 *
195
 * FUNCTION:    acpi_db_dump_namespace
196
 *
197
 * PARAMETERS:  start_arg       - Node to begin namespace dump
198
 *              depth_arg       - Maximum tree depth to be dumped
199
 *
200
 * RETURN:      None
201
 *
202
 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
203
 *              with type and other information.
204
 *
205
 ******************************************************************************/
206
 
207
void acpi_db_dump_namespace(char *start_arg, char *depth_arg)
208
{
209
	acpi_handle subtree_entry = acpi_gbl_root_node;
210
	u32 max_depth = ACPI_UINT32_MAX;
211
 
212
	/* No argument given, just start at the root and dump entire namespace */
213
 
214
	if (start_arg) {
215
		subtree_entry = acpi_db_convert_to_node(start_arg);
216
		if (!subtree_entry) {
217
			return;
218
		}
219
 
220
		/* Now we can check for the depth argument */
221
 
222
		if (depth_arg) {
223
			max_depth = strtoul(depth_arg, NULL, 0);
224
		}
225
	}
226
 
227
	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
228
	acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
229
		       ((struct acpi_namespace_node *)subtree_entry)->name.
230
		       ascii, subtree_entry);
231
 
232
	/* Display the subtree */
233
 
234
	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
235
	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
236
			     ACPI_OWNER_ID_MAX, subtree_entry);
237
	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
238
}
239
 
240
/*******************************************************************************
241
 *
242
 * FUNCTION:    acpi_db_dump_namespace_paths
243
 *
244
 * PARAMETERS:  None
245
 *
246
 * RETURN:      None
247
 *
248
 * DESCRIPTION: Dump entire namespace with full object pathnames and object
249
 *              type information. Alternative to "namespace" command.
250
 *
251
 ******************************************************************************/
252
 
253
void acpi_db_dump_namespace_paths(void)
254
{
255
 
256
	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
257
	acpi_os_printf("ACPI Namespace (from root):\n");
258
 
259
	/* Display the entire namespace */
260
 
261
	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
262
	acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
263
				  ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX,
264
				  acpi_gbl_root_node);
265
 
266
	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
267
}
268
 
269
/*******************************************************************************
270
 *
271
 * FUNCTION:    acpi_db_dump_namespace_by_owner
272
 *
273
 * PARAMETERS:  owner_arg       - Owner ID whose nodes will be displayed
274
 *              depth_arg       - Maximum tree depth to be dumped
275
 *
276
 * RETURN:      None
277
 *
278
 * DESCRIPTION: Dump elements of the namespace that are owned by the owner_id.
279
 *
280
 ******************************************************************************/
281
 
282
void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg)
283
{
284
	acpi_handle subtree_entry = acpi_gbl_root_node;
285
	u32 max_depth = ACPI_UINT32_MAX;
286
	acpi_owner_id owner_id;
287
 
288
	owner_id = (acpi_owner_id) strtoul(owner_arg, NULL, 0);
289
 
290
	/* Now we can check for the depth argument */
291
 
292
	if (depth_arg) {
293
		max_depth = strtoul(depth_arg, NULL, 0);
294
	}
295
 
296
	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
297
	acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id);
298
 
299
	/* Display the subtree */
300
 
301
	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
302
	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
303
			     owner_id, subtree_entry);
304
	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
305
}
306
 
307
/*******************************************************************************
308
 *
309
 * FUNCTION:    acpi_db_walk_and_match_name
310
 *
311
 * PARAMETERS:  Callback from walk_namespace
312
 *
313
 * RETURN:      Status
314
 *
315
 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
316
 *              are supported -- '?' matches any character.
317
 *
318
 ******************************************************************************/
319
 
320
static acpi_status
321
acpi_db_walk_and_match_name(acpi_handle obj_handle,
322
			    u32 nesting_level,
323
			    void *context, void **return_value)
324
{
325
	acpi_status status;
326
	char *requested_name = (char *)context;
327
	u32 i;
328
	struct acpi_buffer buffer;
329
	struct acpi_walk_info info;
330
 
331
	/* Check for a name match */
332
 
333
	for (i = 0; i < 4; i++) {
334
 
335
		/* Wildcard support */
336
 
337
		if ((requested_name[i] != '?') &&
338
		    (requested_name[i] != ((struct acpi_namespace_node *)
339
					   obj_handle)->name.ascii[i])) {
340
 
341
			/* No match, just exit */
342
 
343
			return (AE_OK);
344
		}
345
	}
346
 
347
	/* Get the full pathname to this object */
348
 
349
	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
350
	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
351
	if (ACPI_FAILURE(status)) {
352
		acpi_os_printf("Could Not get pathname for object %p\n",
353
			       obj_handle);
354
	} else {
355
		info.owner_id = ACPI_OWNER_ID_MAX;
356
		info.debug_level = ACPI_UINT32_MAX;
357
		info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
358
 
359
		acpi_os_printf("%32s", (char *)buffer.pointer);
360
		(void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info,
361
					      NULL);
362
		ACPI_FREE(buffer.pointer);
363
	}
364
 
365
	return (AE_OK);
366
}
367
 
368
/*******************************************************************************
369
 *
370
 * FUNCTION:    acpi_db_find_name_in_namespace
371
 *
372
 * PARAMETERS:  name_arg        - The 4-character ACPI name to find.
373
 *                                wildcards are supported.
374
 *
375
 * RETURN:      None
376
 *
377
 * DESCRIPTION: Search the namespace for a given name (with wildcards)
378
 *
379
 ******************************************************************************/
380
 
381
acpi_status acpi_db_find_name_in_namespace(char *name_arg)
382
{
383
	char acpi_name[5] = "____";
384
	char *acpi_name_ptr = acpi_name;
385
 
386
	if (strlen(name_arg) > ACPI_NAME_SIZE) {
387
		acpi_os_printf("Name must be no longer than 4 characters\n");
388
		return (AE_OK);
389
	}
390
 
391
	/* Pad out name with underscores as necessary to create a 4-char name */
392
 
393
	acpi_ut_strupr(name_arg);
394
	while (*name_arg) {
395
		*acpi_name_ptr = *name_arg;
396
		acpi_name_ptr++;
397
		name_arg++;
398
	}
399
 
400
	/* Walk the namespace from the root */
401
 
402
	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
403
				  ACPI_UINT32_MAX, acpi_db_walk_and_match_name,
404
				  NULL, acpi_name, NULL);
405
 
406
	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
407
	return (AE_OK);
408
}
409
 
410
/*******************************************************************************
411
 *
412
 * FUNCTION:    acpi_db_walk_for_predefined_names
413
 *
414
 * PARAMETERS:  Callback from walk_namespace
415
 *
416
 * RETURN:      Status
417
 *
418
 * DESCRIPTION: Detect and display predefined ACPI names (names that start with
419
 *              an underscore)
420
 *
421
 ******************************************************************************/
422
 
423
static acpi_status
424
acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
425
				  u32 nesting_level,
426
				  void *context, void **return_value)
427
{
428
	struct acpi_namespace_node *node =
429
	    (struct acpi_namespace_node *)obj_handle;
430
	u32 *count = (u32 *)context;
431
	const union acpi_predefined_info *predefined;
432
	const union acpi_predefined_info *package = NULL;
433
	char *pathname;
434
	char string_buffer[48];
435
 
436
	predefined = acpi_ut_match_predefined_method(node->name.ascii);
437
	if (!predefined) {
438
		return (AE_OK);
439
	}
440
 
441
	pathname = acpi_ns_get_external_pathname(node);
442
	if (!pathname) {
443
		return (AE_OK);
444
	}
445
 
446
	/* If method returns a package, the info is in the next table entry */
447
 
448
	if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
449
		package = predefined + 1;
450
	}
451
 
452
	acpi_ut_get_expected_return_types(string_buffer,
453
					  predefined->info.expected_btypes);
454
 
455
	acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname,
456
		       METHOD_GET_ARG_COUNT(predefined->info.argument_list),
457
		       string_buffer);
458
 
459
	if (package) {
460
		acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
461
			       package->ret_info.type,
462
			       package->ret_info.object_type1,
463
			       package->ret_info.count1);
464
	}
465
 
466
	acpi_os_printf("\n");
467
 
468
	/* Check that the declared argument count matches the ACPI spec */
469
 
470
	acpi_ns_check_acpi_compliance(pathname, node, predefined);
471
 
472
	ACPI_FREE(pathname);
473
	(*count)++;
474
	return (AE_OK);
475
}
476
 
477
/*******************************************************************************
478
 *
479
 * FUNCTION:    acpi_db_check_predefined_names
480
 *
481
 * PARAMETERS:  None
482
 *
483
 * RETURN:      None
484
 *
485
 * DESCRIPTION: Validate all predefined names in the namespace
486
 *
487
 ******************************************************************************/
488
 
489
void acpi_db_check_predefined_names(void)
490
{
491
	u32 count = 0;
492
 
493
	/* Search all nodes in namespace */
494
 
495
	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
496
				  ACPI_UINT32_MAX,
497
				  acpi_db_walk_for_predefined_names, NULL,
498
				  (void *)&count, NULL);
499
 
500
	acpi_os_printf("Found %u predefined names in the namespace\n", count);
501
}
502
 
503
/*******************************************************************************
504
 *
505
 * FUNCTION:    acpi_db_walk_for_object_counts
506
 *
507
 * PARAMETERS:  Callback from walk_namespace
508
 *
509
 * RETURN:      Status
510
 *
511
 * DESCRIPTION: Display short info about objects in the namespace
512
 *
513
 ******************************************************************************/
514
 
515
static acpi_status
516
acpi_db_walk_for_object_counts(acpi_handle obj_handle,
517
			       u32 nesting_level,
518
			       void *context, void **return_value)
519
{
520
	struct acpi_object_info *info = (struct acpi_object_info *)context;
521
	struct acpi_namespace_node *node =
522
	    (struct acpi_namespace_node *)obj_handle;
523
 
524
	if (node->type > ACPI_TYPE_NS_NODE_MAX) {
525
		acpi_os_printf("[%4.4s]: Unknown object type %X\n",
526
			       node->name.ascii, node->type);
527
	} else {
528
		info->types[node->type]++;
529
	}
530
 
531
	return (AE_OK);
532
}
533
 
534
/*******************************************************************************
535
 *
536
 * FUNCTION:    acpi_db_walk_for_specific_objects
537
 *
538
 * PARAMETERS:  Callback from walk_namespace
539
 *
540
 * RETURN:      Status
541
 *
542
 * DESCRIPTION: Display short info about objects in the namespace
543
 *
544
 ******************************************************************************/
545
 
546
static acpi_status
547
acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
548
				  u32 nesting_level,
549
				  void *context, void **return_value)
550
{
551
	struct acpi_walk_info *info = (struct acpi_walk_info *)context;
552
	struct acpi_buffer buffer;
553
	acpi_status status;
554
 
555
	info->count++;
556
 
557
	/* Get and display the full pathname to this object */
558
 
559
	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
560
	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
561
	if (ACPI_FAILURE(status)) {
562
		acpi_os_printf("Could Not get pathname for object %p\n",
563
			       obj_handle);
564
		return (AE_OK);
565
	}
566
 
567
	acpi_os_printf("%32s", (char *)buffer.pointer);
568
	ACPI_FREE(buffer.pointer);
569
 
570
	/* Dump short info about the object */
571
 
572
	(void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL);
573
	return (AE_OK);
574
}
575
 
576
/*******************************************************************************
577
 *
578
 * FUNCTION:    acpi_db_display_objects
579
 *
580
 * PARAMETERS:  obj_type_arg        - Type of object to display
581
 *              display_count_arg   - Max depth to display
582
 *
583
 * RETURN:      None
584
 *
585
 * DESCRIPTION: Display objects in the namespace of the requested type
586
 *
587
 ******************************************************************************/
588
 
589
acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
590
{
591
	struct acpi_walk_info info;
592
	acpi_object_type type;
593
	struct acpi_object_info *object_info;
594
	u32 i;
595
	u32 total_objects = 0;
596
 
597
	/* No argument means display summary/count of all object types */
598
 
599
	if (!obj_type_arg) {
600
		object_info =
601
		    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
602
 
603
		/* Walk the namespace from the root */
604
 
605
		(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
606
					  ACPI_UINT32_MAX,
607
					  acpi_db_walk_for_object_counts, NULL,
608
					  (void *)object_info, NULL);
609
 
610
		acpi_os_printf("\nSummary of namespace objects:\n\n");
611
 
612
		for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
613
			acpi_os_printf("%8u %s\n", object_info->types[i],
614
				       acpi_ut_get_type_name(i));
615
 
616
			total_objects += object_info->types[i];
617
		}
618
 
619
		acpi_os_printf("\n%8u Total namespace objects\n\n",
620
			       total_objects);
621
 
622
		ACPI_FREE(object_info);
623
		return (AE_OK);
624
	}
625
 
626
	/* Get the object type */
627
 
628
	type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
629
	if (type == ACPI_TYPE_NOT_FOUND) {
630
		acpi_os_printf("Invalid or unsupported argument\n");
631
		return (AE_OK);
632
	}
633
 
634
	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
635
	acpi_os_printf
636
	    ("Objects of type [%s] defined in the current ACPI Namespace:\n",
637
	     acpi_ut_get_type_name(type));
638
 
639
	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
640
 
641
	info.count = 0;
642
	info.owner_id = ACPI_OWNER_ID_MAX;
643
	info.debug_level = ACPI_UINT32_MAX;
644
	info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
645
 
646
	/* Walk the namespace from the root */
647
 
648
	(void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
649
				  acpi_db_walk_for_specific_objects, NULL,
650
				  (void *)&info, NULL);
651
 
652
	acpi_os_printf
653
	    ("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
654
	     info.count, acpi_ut_get_type_name(type));
655
 
656
	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
657
	return (AE_OK);
658
}
659
 
660
/*******************************************************************************
661
 *
662
 * FUNCTION:    acpi_db_integrity_walk
663
 *
664
 * PARAMETERS:  Callback from walk_namespace
665
 *
666
 * RETURN:      Status
667
 *
668
 * DESCRIPTION: Examine one NS node for valid values.
669
 *
670
 ******************************************************************************/
671
 
672
static acpi_status
673
acpi_db_integrity_walk(acpi_handle obj_handle,
674
		       u32 nesting_level, void *context, void **return_value)
675
{
676
	struct acpi_integrity_info *info =
677
	    (struct acpi_integrity_info *)context;
678
	struct acpi_namespace_node *node =
679
	    (struct acpi_namespace_node *)obj_handle;
680
	union acpi_operand_object *object;
681
	u8 alias = TRUE;
682
 
683
	info->nodes++;
684
 
685
	/* Verify the NS node, and dereference aliases */
686
 
687
	while (alias) {
688
		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
689
			acpi_os_printf
690
			    ("Invalid Descriptor Type for Node %p [%s] - "
691
			     "is %2.2X should be %2.2X\n", node,
692
			     acpi_ut_get_descriptor_name(node),
693
			     ACPI_GET_DESCRIPTOR_TYPE(node),
694
			     ACPI_DESC_TYPE_NAMED);
695
			return (AE_OK);
696
		}
697
 
698
		if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
699
		    (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
700
			node = (struct acpi_namespace_node *)node->object;
701
		} else {
702
			alias = FALSE;
703
		}
704
	}
705
 
706
	if (node->type > ACPI_TYPE_LOCAL_MAX) {
707
		acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
708
			       node, node->type);
709
		return (AE_OK);
710
	}
711
 
712
	if (!acpi_ut_valid_acpi_name(node->name.ascii)) {
713
		acpi_os_printf("Invalid AcpiName for Node %p\n", node);
714
		return (AE_OK);
715
	}
716
 
717
	object = acpi_ns_get_attached_object(node);
718
	if (object) {
719
		info->objects++;
720
		if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
721
			acpi_os_printf
722
			    ("Invalid Descriptor Type for Object %p [%s]\n",
723
			     object, acpi_ut_get_descriptor_name(object));
724
		}
725
	}
726
 
727
	return (AE_OK);
728
}
729
 
730
/*******************************************************************************
731
 *
732
 * FUNCTION:    acpi_db_check_integrity
733
 *
734
 * PARAMETERS:  None
735
 *
736
 * RETURN:      None
737
 *
738
 * DESCRIPTION: Check entire namespace for data structure integrity
739
 *
740
 ******************************************************************************/
741
 
742
void acpi_db_check_integrity(void)
743
{
744
	struct acpi_integrity_info info = { 0, 0 };
745
 
746
	/* Search all nodes in namespace */
747
 
748
	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
749
				  ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
750
				  (void *)&info, NULL);
751
 
752
	acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
753
		       info.nodes, info.objects);
754
}
755
 
756
/*******************************************************************************
757
 *
758
 * FUNCTION:    acpi_db_walk_for_references
759
 *
760
 * PARAMETERS:  Callback from walk_namespace
761
 *
762
 * RETURN:      Status
763
 *
764
 * DESCRIPTION: Check if this namespace object refers to the target object
765
 *              that is passed in as the context value.
766
 *
767
 * Note: Currently doesn't check subobjects within the Node's object
768
 *
769
 ******************************************************************************/
770
 
771
static acpi_status
772
acpi_db_walk_for_references(acpi_handle obj_handle,
773
			    u32 nesting_level,
774
			    void *context, void **return_value)
775
{
776
	union acpi_operand_object *obj_desc =
777
	    (union acpi_operand_object *)context;
778
	struct acpi_namespace_node *node =
779
	    (struct acpi_namespace_node *)obj_handle;
780
 
781
	/* Check for match against the namespace node itself */
782
 
783
	if (node == (void *)obj_desc) {
784
		acpi_os_printf("Object is a Node [%4.4s]\n",
785
			       acpi_ut_get_node_name(node));
786
	}
787
 
788
	/* Check for match against the object attached to the node */
789
 
790
	if (acpi_ns_get_attached_object(node) == obj_desc) {
791
		acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
792
			       node, acpi_ut_get_node_name(node));
793
	}
794
 
795
	return (AE_OK);
796
}
797
 
798
/*******************************************************************************
799
 *
800
 * FUNCTION:    acpi_db_find_references
801
 *
802
 * PARAMETERS:  object_arg      - String with hex value of the object
803
 *
804
 * RETURN:      None
805
 *
806
 * DESCRIPTION: Search namespace for all references to the input object
807
 *
808
 ******************************************************************************/
809
 
810
void acpi_db_find_references(char *object_arg)
811
{
812
	union acpi_operand_object *obj_desc;
813
	acpi_size address;
814
 
815
	/* Convert string to object pointer */
816
 
817
	address = strtoul(object_arg, NULL, 16);
818
	obj_desc = ACPI_TO_POINTER(address);
819
 
820
	/* Search all nodes in namespace */
821
 
822
	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
823
				  ACPI_UINT32_MAX, acpi_db_walk_for_references,
824
				  NULL, (void *)obj_desc, NULL);
825
}
826
 
827
/*******************************************************************************
828
 *
829
 * FUNCTION:    acpi_db_bus_walk
830
 *
831
 * PARAMETERS:  Callback from walk_namespace
832
 *
833
 * RETURN:      Status
834
 *
835
 * DESCRIPTION: Display info about device objects that have a corresponding
836
 *              _PRT method.
837
 *
838
 ******************************************************************************/
839
 
840
static acpi_status
841
acpi_db_bus_walk(acpi_handle obj_handle,
842
		 u32 nesting_level, void *context, void **return_value)
843
{
844
	struct acpi_namespace_node *node =
845
	    (struct acpi_namespace_node *)obj_handle;
846
	acpi_status status;
847
	struct acpi_buffer buffer;
848
	struct acpi_namespace_node *temp_node;
849
	struct acpi_device_info *info;
850
	u32 i;
851
 
852
	if ((node->type != ACPI_TYPE_DEVICE) &&
853
	    (node->type != ACPI_TYPE_PROCESSOR)) {
854
		return (AE_OK);
855
	}
856
 
857
	/* Exit if there is no _PRT under this device */
858
 
859
	status = acpi_get_handle(node, METHOD_NAME__PRT,
860
				 ACPI_CAST_PTR(acpi_handle, &temp_node));
861
	if (ACPI_FAILURE(status)) {
862
		return (AE_OK);
863
	}
864
 
865
	/* Get the full path to this device object */
866
 
867
	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
868
	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
869
	if (ACPI_FAILURE(status)) {
870
		acpi_os_printf("Could Not get pathname for object %p\n",
871
			       obj_handle);
872
		return (AE_OK);
873
	}
874
 
875
	status = acpi_get_object_info(obj_handle, &info);
876
	if (ACPI_FAILURE(status)) {
877
		return (AE_OK);
878
	}
879
 
880
	/* Display the full path */
881
 
882
	acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
883
	ACPI_FREE(buffer.pointer);
884
 
885
	if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
886
		acpi_os_printf(" - Is PCI Root Bridge");
887
	}
888
	acpi_os_printf("\n");
889
 
890
	/* _PRT info */
891
 
892
	acpi_os_printf("_PRT: %p\n", temp_node);
893
 
894
	/* Dump _ADR, _HID, _UID, _CID */
895
 
896
	if (info->valid & ACPI_VALID_ADR) {
897
		acpi_os_printf("_ADR: %8.8X%8.8X\n",
898
			       ACPI_FORMAT_UINT64(info->address));
899
	} else {
900
		acpi_os_printf("_ADR: \n");
901
	}
902
 
903
	if (info->valid & ACPI_VALID_HID) {
904
		acpi_os_printf("_HID: %s\n", info->hardware_id.string);
905
	} else {
906
		acpi_os_printf("_HID: \n");
907
	}
908
 
909
	if (info->valid & ACPI_VALID_UID) {
910
		acpi_os_printf("_UID: %s\n", info->unique_id.string);
911
	} else {
912
		acpi_os_printf("_UID: \n");
913
	}
914
 
915
	if (info->valid & ACPI_VALID_CID) {
916
		for (i = 0; i < info->compatible_id_list.count; i++) {
917
			acpi_os_printf("_CID: %s\n",
918
				       info->compatible_id_list.ids[i].string);
919
		}
920
	} else {
921
		acpi_os_printf("_CID: \n");
922
	}
923
 
924
	ACPI_FREE(info);
925
	return (AE_OK);
926
}
927
 
928
/*******************************************************************************
929
 *
930
 * FUNCTION:    acpi_db_get_bus_info
931
 *
932
 * PARAMETERS:  None
933
 *
934
 * RETURN:      None
935
 *
936
 * DESCRIPTION: Display info about system busses.
937
 *
938
 ******************************************************************************/
939
 
940
void acpi_db_get_bus_info(void)
941
{
942
	/* Search all nodes in namespace */
943
 
944
	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
945
				  ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL,
946
				  NULL);
947
}