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