GNU Linux-libre 6.7.9-gnu
[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         acpi_evaluate_object(obj_handle, NULL, NULL, &buffer);
554
555         /*
556          * Since this is a field unit, surround the output in braces
557          */
558         acpi_os_printf("{");
559
560         ret_value = (union acpi_object *)buffer.pointer;
561         switch (ret_value->type) {
562         case ACPI_TYPE_INTEGER:
563
564                 acpi_os_printf("%8.8X%8.8X",
565                                ACPI_FORMAT_UINT64(ret_value->integer.value));
566                 break;
567
568         case ACPI_TYPE_BUFFER:
569
570                 acpi_ut_dump_buffer(ret_value->buffer.pointer,
571                                     ret_value->buffer.length,
572                                     DB_DISPLAY_DATA_ONLY | DB_BYTE_DISPLAY, 0);
573                 break;
574
575         default:
576
577                 break;
578         }
579         acpi_os_printf("}\n");
580
581         ACPI_FREE(buffer.pointer);
582
583         return (AE_OK);
584 }
585
586 /*******************************************************************************
587  *
588  * FUNCTION:    acpi_db_walk_for_specific_objects
589  *
590  * PARAMETERS:  Callback from walk_namespace
591  *
592  * RETURN:      Status
593  *
594  * DESCRIPTION: Display short info about objects in the namespace
595  *
596  ******************************************************************************/
597
598 static acpi_status
599 acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
600                                   u32 nesting_level,
601                                   void *context, void **return_value)
602 {
603         struct acpi_walk_info *info = (struct acpi_walk_info *)context;
604         struct acpi_buffer buffer;
605         acpi_status status;
606
607         info->count++;
608
609         /* Get and display the full pathname to this object */
610
611         buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
612         status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
613         if (ACPI_FAILURE(status)) {
614                 acpi_os_printf("Could Not get pathname for object %p\n",
615                                obj_handle);
616                 return (AE_OK);
617         }
618
619         acpi_os_printf("%32s", (char *)buffer.pointer);
620         ACPI_FREE(buffer.pointer);
621
622         /* Dump short info about the object */
623
624         (void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL);
625         return (AE_OK);
626 }
627
628 /*******************************************************************************
629  *
630  * FUNCTION:    acpi_db_display_objects
631  *
632  * PARAMETERS:  obj_type_arg        - Type of object to display
633  *              display_count_arg   - Max depth to display
634  *
635  * RETURN:      None
636  *
637  * DESCRIPTION: Display objects in the namespace of the requested type
638  *
639  ******************************************************************************/
640
641 acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
642 {
643         struct acpi_walk_info info;
644         acpi_object_type type;
645         struct acpi_object_info *object_info;
646         u32 i;
647         u32 total_objects = 0;
648
649         /* No argument means display summary/count of all object types */
650
651         if (!obj_type_arg) {
652                 object_info =
653                     ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
654
655                 if (!object_info)
656                         return (AE_NO_MEMORY);
657
658                 /* Walk the namespace from the root */
659
660                 (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
661                                           ACPI_UINT32_MAX,
662                                           acpi_db_walk_for_object_counts, NULL,
663                                           (void *)object_info, NULL);
664
665                 acpi_os_printf("\nSummary of namespace objects:\n\n");
666
667                 for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
668                         acpi_os_printf("%8u %s\n", object_info->types[i],
669                                        acpi_ut_get_type_name(i));
670
671                         total_objects += object_info->types[i];
672                 }
673
674                 acpi_os_printf("\n%8u Total namespace objects\n\n",
675                                total_objects);
676
677                 ACPI_FREE(object_info);
678                 return (AE_OK);
679         }
680
681         /* Get the object type */
682
683         type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
684         if (type == ACPI_TYPE_NOT_FOUND) {
685                 acpi_os_printf("Invalid or unsupported argument\n");
686                 return (AE_OK);
687         }
688
689         acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
690         acpi_os_printf
691             ("Objects of type [%s] defined in the current ACPI Namespace:\n",
692              acpi_ut_get_type_name(type));
693
694         acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
695
696         info.count = 0;
697         info.owner_id = ACPI_OWNER_ID_MAX;
698         info.debug_level = ACPI_UINT32_MAX;
699         info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
700
701         /* Walk the namespace from the root */
702
703         (void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
704                                   acpi_db_walk_for_specific_objects, NULL,
705                                   (void *)&info, NULL);
706
707         acpi_os_printf
708             ("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
709              info.count, acpi_ut_get_type_name(type));
710
711         acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
712         return (AE_OK);
713 }
714
715 /*******************************************************************************
716  *
717  * FUNCTION:    acpi_db_display_fields
718  *
719  * PARAMETERS:  obj_type_arg        - Type of object to display
720  *              display_count_arg   - Max depth to display
721  *
722  * RETURN:      None
723  *
724  * DESCRIPTION: Display objects in the namespace of the requested type
725  *
726  ******************************************************************************/
727
728 acpi_status acpi_db_display_fields(u32 address_space_id)
729 {
730         struct acpi_region_walk_info info;
731
732         info.count = 0;
733         info.owner_id = ACPI_OWNER_ID_MAX;
734         info.debug_level = ACPI_UINT32_MAX;
735         info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
736         info.address_space_id = address_space_id;
737
738         /* Walk the namespace from the root */
739
740         (void)acpi_walk_namespace(ACPI_TYPE_LOCAL_REGION_FIELD,
741                                   ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
742                                   acpi_db_walk_for_fields, NULL, (void *)&info,
743                                   NULL);
744
745         return (AE_OK);
746 }
747
748 /*******************************************************************************
749  *
750  * FUNCTION:    acpi_db_integrity_walk
751  *
752  * PARAMETERS:  Callback from walk_namespace
753  *
754  * RETURN:      Status
755  *
756  * DESCRIPTION: Examine one NS node for valid values.
757  *
758  ******************************************************************************/
759
760 static acpi_status
761 acpi_db_integrity_walk(acpi_handle obj_handle,
762                        u32 nesting_level, void *context, void **return_value)
763 {
764         struct acpi_integrity_info *info =
765             (struct acpi_integrity_info *)context;
766         struct acpi_namespace_node *node =
767             (struct acpi_namespace_node *)obj_handle;
768         union acpi_operand_object *object;
769         u8 alias = TRUE;
770
771         info->nodes++;
772
773         /* Verify the NS node, and dereference aliases */
774
775         while (alias) {
776                 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
777                         acpi_os_printf
778                             ("Invalid Descriptor Type for Node %p [%s] - "
779                              "is %2.2X should be %2.2X\n", node,
780                              acpi_ut_get_descriptor_name(node),
781                              ACPI_GET_DESCRIPTOR_TYPE(node),
782                              ACPI_DESC_TYPE_NAMED);
783                         return (AE_OK);
784                 }
785
786                 if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
787                     (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
788                         node = (struct acpi_namespace_node *)node->object;
789                 } else {
790                         alias = FALSE;
791                 }
792         }
793
794         if (node->type > ACPI_TYPE_LOCAL_MAX) {
795                 acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
796                                node, node->type);
797                 return (AE_OK);
798         }
799
800         if (!acpi_ut_valid_nameseg(node->name.ascii)) {
801                 acpi_os_printf("Invalid AcpiName for Node %p\n", node);
802                 return (AE_OK);
803         }
804
805         object = acpi_ns_get_attached_object(node);
806         if (object) {
807                 info->objects++;
808                 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
809                         acpi_os_printf
810                             ("Invalid Descriptor Type for Object %p [%s]\n",
811                              object, acpi_ut_get_descriptor_name(object));
812                 }
813         }
814
815         return (AE_OK);
816 }
817
818 /*******************************************************************************
819  *
820  * FUNCTION:    acpi_db_check_integrity
821  *
822  * PARAMETERS:  None
823  *
824  * RETURN:      None
825  *
826  * DESCRIPTION: Check entire namespace for data structure integrity
827  *
828  ******************************************************************************/
829
830 void acpi_db_check_integrity(void)
831 {
832         struct acpi_integrity_info info = { 0, 0 };
833
834         /* Search all nodes in namespace */
835
836         (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
837                                   ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
838                                   (void *)&info, NULL);
839
840         acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
841                        info.nodes, info.objects);
842 }
843
844 /*******************************************************************************
845  *
846  * FUNCTION:    acpi_db_walk_for_references
847  *
848  * PARAMETERS:  Callback from walk_namespace
849  *
850  * RETURN:      Status
851  *
852  * DESCRIPTION: Check if this namespace object refers to the target object
853  *              that is passed in as the context value.
854  *
855  * Note: Currently doesn't check subobjects within the Node's object
856  *
857  ******************************************************************************/
858
859 static acpi_status
860 acpi_db_walk_for_references(acpi_handle obj_handle,
861                             u32 nesting_level,
862                             void *context, void **return_value)
863 {
864         union acpi_operand_object *obj_desc =
865             (union acpi_operand_object *)context;
866         struct acpi_namespace_node *node =
867             (struct acpi_namespace_node *)obj_handle;
868
869         /* Check for match against the namespace node itself */
870
871         if (node == (void *)obj_desc) {
872                 acpi_os_printf("Object is a Node [%4.4s]\n",
873                                acpi_ut_get_node_name(node));
874         }
875
876         /* Check for match against the object attached to the node */
877
878         if (acpi_ns_get_attached_object(node) == obj_desc) {
879                 acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
880                                node, acpi_ut_get_node_name(node));
881         }
882
883         return (AE_OK);
884 }
885
886 /*******************************************************************************
887  *
888  * FUNCTION:    acpi_db_find_references
889  *
890  * PARAMETERS:  object_arg      - String with hex value of the object
891  *
892  * RETURN:      None
893  *
894  * DESCRIPTION: Search namespace for all references to the input object
895  *
896  ******************************************************************************/
897
898 void acpi_db_find_references(char *object_arg)
899 {
900         union acpi_operand_object *obj_desc;
901         acpi_size address;
902
903         /* Convert string to object pointer */
904
905         address = strtoul(object_arg, NULL, 16);
906         obj_desc = ACPI_TO_POINTER(address);
907
908         /* Search all nodes in namespace */
909
910         (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
911                                   ACPI_UINT32_MAX, acpi_db_walk_for_references,
912                                   NULL, (void *)obj_desc, NULL);
913 }
914
915 /*******************************************************************************
916  *
917  * FUNCTION:    acpi_db_bus_walk
918  *
919  * PARAMETERS:  Callback from walk_namespace
920  *
921  * RETURN:      Status
922  *
923  * DESCRIPTION: Display info about device objects that have a corresponding
924  *              _PRT method.
925  *
926  ******************************************************************************/
927
928 static acpi_status
929 acpi_db_bus_walk(acpi_handle obj_handle,
930                  u32 nesting_level, void *context, void **return_value)
931 {
932         struct acpi_namespace_node *node =
933             (struct acpi_namespace_node *)obj_handle;
934         acpi_status status;
935         struct acpi_buffer buffer;
936         struct acpi_namespace_node *temp_node;
937         struct acpi_device_info *info;
938         u32 i;
939
940         if ((node->type != ACPI_TYPE_DEVICE) &&
941             (node->type != ACPI_TYPE_PROCESSOR)) {
942                 return (AE_OK);
943         }
944
945         /* Exit if there is no _PRT under this device */
946
947         status = acpi_get_handle(node, METHOD_NAME__PRT,
948                                  ACPI_CAST_PTR(acpi_handle, &temp_node));
949         if (ACPI_FAILURE(status)) {
950                 return (AE_OK);
951         }
952
953         /* Get the full path to this device object */
954
955         buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
956         status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
957         if (ACPI_FAILURE(status)) {
958                 acpi_os_printf("Could Not get pathname for object %p\n",
959                                obj_handle);
960                 return (AE_OK);
961         }
962
963         status = acpi_get_object_info(obj_handle, &info);
964         if (ACPI_FAILURE(status)) {
965                 return (AE_OK);
966         }
967
968         /* Display the full path */
969
970         acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
971         ACPI_FREE(buffer.pointer);
972
973         if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
974                 acpi_os_printf(" - Is PCI Root Bridge");
975         }
976         acpi_os_printf("\n");
977
978         /* _PRT info */
979
980         acpi_os_printf("_PRT: %p\n", temp_node);
981
982         /* Dump _ADR, _HID, _UID, _CID */
983
984         if (info->valid & ACPI_VALID_ADR) {
985                 acpi_os_printf("_ADR: %8.8X%8.8X\n",
986                                ACPI_FORMAT_UINT64(info->address));
987         } else {
988                 acpi_os_printf("_ADR: <Not Present>\n");
989         }
990
991         if (info->valid & ACPI_VALID_HID) {
992                 acpi_os_printf("_HID: %s\n", info->hardware_id.string);
993         } else {
994                 acpi_os_printf("_HID: <Not Present>\n");
995         }
996
997         if (info->valid & ACPI_VALID_UID) {
998                 acpi_os_printf("_UID: %s\n", info->unique_id.string);
999         } else {
1000                 acpi_os_printf("_UID: <Not Present>\n");
1001         }
1002
1003         if (info->valid & ACPI_VALID_CID) {
1004                 for (i = 0; i < info->compatible_id_list.count; i++) {
1005                         acpi_os_printf("_CID: %s\n",
1006                                        info->compatible_id_list.ids[i].string);
1007                 }
1008         } else {
1009                 acpi_os_printf("_CID: <Not Present>\n");
1010         }
1011
1012         ACPI_FREE(info);
1013         return (AE_OK);
1014 }
1015
1016 /*******************************************************************************
1017  *
1018  * FUNCTION:    acpi_db_get_bus_info
1019  *
1020  * PARAMETERS:  None
1021  *
1022  * RETURN:      None
1023  *
1024  * DESCRIPTION: Display info about system buses.
1025  *
1026  ******************************************************************************/
1027
1028 void acpi_db_get_bus_info(void)
1029 {
1030         /* Search all nodes in namespace */
1031
1032         (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1033                                   ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL,
1034                                   NULL);
1035 }