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