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