Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/acpi/acpica/dbnames.c
26292 views
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
}
1040
1041