dbnames.c revision 1.11 1 /*******************************************************************************
2 *
3 * Module Name: dbnames - Debugger commands for the acpi namespace
4 *
5 ******************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2018, 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
268 if (((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Parent)
269 {
270 AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
271 ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
272 }
273 else
274 {
275 AcpiOsPrintf ("ACPI Namespace (from %s):\n",
276 ACPI_NAMESPACE_ROOT);
277 }
278
279 /* Display the subtree */
280
281 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
282 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
283 ACPI_OWNER_ID_MAX, SubtreeEntry);
284 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
285 }
286
287
288 /*******************************************************************************
289 *
290 * FUNCTION: AcpiDbDumpNamespacePaths
291 *
292 * PARAMETERS: None
293 *
294 * RETURN: None
295 *
296 * DESCRIPTION: Dump entire namespace with full object pathnames and object
297 * type information. Alternative to "namespace" command.
298 *
299 ******************************************************************************/
300
301 void
302 AcpiDbDumpNamespacePaths (
303 void)
304 {
305
306 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
307 AcpiOsPrintf ("ACPI Namespace (from root):\n");
308
309 /* Display the entire namespace */
310
311 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
312 AcpiNsDumpObjectPaths (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
313 ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX, AcpiGbl_RootNode);
314
315 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
316 }
317
318
319 /*******************************************************************************
320 *
321 * FUNCTION: AcpiDbDumpNamespaceByOwner
322 *
323 * PARAMETERS: OwnerArg - Owner ID whose nodes will be displayed
324 * DepthArg - Maximum tree depth to be dumped
325 *
326 * RETURN: None
327 *
328 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
329 *
330 ******************************************************************************/
331
332 void
333 AcpiDbDumpNamespaceByOwner (
334 char *OwnerArg,
335 char *DepthArg)
336 {
337 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode;
338 UINT32 MaxDepth = ACPI_UINT32_MAX;
339 ACPI_OWNER_ID OwnerId;
340
341
342 OwnerId = (ACPI_OWNER_ID) strtoul (OwnerArg, NULL, 0);
343
344 /* Now we can check for the depth argument */
345
346 if (DepthArg)
347 {
348 MaxDepth = strtoul (DepthArg, NULL, 0);
349 }
350
351 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
352 AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
353
354 /* Display the subtree */
355
356 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
357 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
358 OwnerId, SubtreeEntry);
359 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
360 }
361
362
363 /*******************************************************************************
364 *
365 * FUNCTION: AcpiDbWalkAndMatchName
366 *
367 * PARAMETERS: Callback from WalkNamespace
368 *
369 * RETURN: Status
370 *
371 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
372 * are supported -- '?' matches any character.
373 *
374 ******************************************************************************/
375
376 static ACPI_STATUS
377 AcpiDbWalkAndMatchName (
378 ACPI_HANDLE ObjHandle,
379 UINT32 NestingLevel,
380 void *Context,
381 void **ReturnValue)
382 {
383 ACPI_STATUS Status;
384 char *RequestedName = (char *) Context;
385 UINT32 i;
386 ACPI_BUFFER Buffer;
387 ACPI_WALK_INFO Info;
388
389
390 /* Check for a name match */
391
392 for (i = 0; i < 4; i++)
393 {
394 /* Wildcard support */
395
396 if ((RequestedName[i] != '?') &&
397 (RequestedName[i] != ((ACPI_NAMESPACE_NODE *)
398 ObjHandle)->Name.Ascii[i]))
399 {
400 /* No match, just exit */
401
402 return (AE_OK);
403 }
404 }
405
406 /* Get the full pathname to this object */
407
408 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
409 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
410 if (ACPI_FAILURE (Status))
411 {
412 AcpiOsPrintf ("Could Not get pathname for object %p\n",
413 ObjHandle);
414 }
415 else
416 {
417 Info.Count = 0;
418 Info.OwnerId = ACPI_OWNER_ID_MAX;
419 Info.DebugLevel = ACPI_UINT32_MAX;
420 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
421
422 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
423 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
424 ACPI_FREE (Buffer.Pointer);
425 }
426
427 return (AE_OK);
428 }
429
430
431 /*******************************************************************************
432 *
433 * FUNCTION: AcpiDbFindNameInNamespace
434 *
435 * PARAMETERS: NameArg - The 4-character ACPI name to find.
436 * wildcards are supported.
437 *
438 * RETURN: None
439 *
440 * DESCRIPTION: Search the namespace for a given name (with wildcards)
441 *
442 ******************************************************************************/
443
444 ACPI_STATUS
445 AcpiDbFindNameInNamespace (
446 char *NameArg)
447 {
448 char AcpiName[5] = "____";
449 char *AcpiNamePtr = AcpiName;
450
451
452 if (strlen (NameArg) > ACPI_NAME_SIZE)
453 {
454 AcpiOsPrintf ("Name must be no longer than 4 characters\n");
455 return (AE_OK);
456 }
457
458 /* Pad out name with underscores as necessary to create a 4-char name */
459
460 AcpiUtStrupr (NameArg);
461 while (*NameArg)
462 {
463 *AcpiNamePtr = *NameArg;
464 AcpiNamePtr++;
465 NameArg++;
466 }
467
468 /* Walk the namespace from the root */
469
470 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
471 ACPI_UINT32_MAX, AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
472
473 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
474 return (AE_OK);
475 }
476
477
478 /*******************************************************************************
479 *
480 * FUNCTION: AcpiDbWalkForPredefinedNames
481 *
482 * PARAMETERS: Callback from WalkNamespace
483 *
484 * RETURN: Status
485 *
486 * DESCRIPTION: Detect and display predefined ACPI names (names that start with
487 * an underscore)
488 *
489 ******************************************************************************/
490
491 static ACPI_STATUS
492 AcpiDbWalkForPredefinedNames (
493 ACPI_HANDLE ObjHandle,
494 UINT32 NestingLevel,
495 void *Context,
496 void **ReturnValue)
497 {
498 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
499 UINT32 *Count = (UINT32 *) Context;
500 const ACPI_PREDEFINED_INFO *Predefined;
501 const ACPI_PREDEFINED_INFO *Package = NULL;
502 char *Pathname;
503 char StringBuffer[48];
504
505
506 Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
507 if (!Predefined)
508 {
509 return (AE_OK);
510 }
511
512 Pathname = AcpiNsGetNormalizedPathname (Node, TRUE);
513 if (!Pathname)
514 {
515 return (AE_OK);
516 }
517
518 /* If method returns a package, the info is in the next table entry */
519
520 if (Predefined->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
521 {
522 Package = Predefined + 1;
523 }
524
525 AcpiUtGetExpectedReturnTypes (StringBuffer,
526 Predefined->Info.ExpectedBtypes);
527
528 AcpiOsPrintf ("%-32s Arguments %X, Return Types: %s", Pathname,
529 METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList),
530 StringBuffer);
531
532 if (Package)
533 {
534 AcpiOsPrintf (" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
535 Package->RetInfo.Type, Package->RetInfo.ObjectType1,
536 Package->RetInfo.Count1);
537 }
538
539 AcpiOsPrintf("\n");
540
541 /* Check that the declared argument count matches the ACPI spec */
542
543 AcpiNsCheckAcpiCompliance (Pathname, Node, Predefined);
544
545 ACPI_FREE (Pathname);
546 (*Count)++;
547 return (AE_OK);
548 }
549
550
551 /*******************************************************************************
552 *
553 * FUNCTION: AcpiDbCheckPredefinedNames
554 *
555 * PARAMETERS: None
556 *
557 * RETURN: None
558 *
559 * DESCRIPTION: Validate all predefined names in the namespace
560 *
561 ******************************************************************************/
562
563 void
564 AcpiDbCheckPredefinedNames (
565 void)
566 {
567 UINT32 Count = 0;
568
569
570 /* Search all nodes in namespace */
571
572 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
573 ACPI_UINT32_MAX, AcpiDbWalkForPredefinedNames,
574 NULL, (void *) &Count, NULL);
575
576 AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count);
577 }
578
579
580 /*******************************************************************************
581 *
582 * FUNCTION: AcpiDbWalkForObjectCounts
583 *
584 * PARAMETERS: Callback from WalkNamespace
585 *
586 * RETURN: Status
587 *
588 * DESCRIPTION: Display short info about objects in the namespace
589 *
590 ******************************************************************************/
591
592 static ACPI_STATUS
593 AcpiDbWalkForObjectCounts (
594 ACPI_HANDLE ObjHandle,
595 UINT32 NestingLevel,
596 void *Context,
597 void **ReturnValue)
598 {
599 ACPI_OBJECT_INFO *Info = (ACPI_OBJECT_INFO *) Context;
600 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
601
602
603 if (Node->Type > ACPI_TYPE_NS_NODE_MAX)
604 {
605 AcpiOsPrintf ("[%4.4s]: Unknown object type %X\n",
606 Node->Name.Ascii, Node->Type);
607 }
608 else
609 {
610 Info->Types[Node->Type]++;
611 }
612
613 return (AE_OK);
614 }
615
616
617 /*******************************************************************************
618 *
619 * FUNCTION: AcpiDbWalkForSpecificObjects
620 *
621 * PARAMETERS: Callback from WalkNamespace
622 *
623 * RETURN: Status
624 *
625 * DESCRIPTION: Display short info about objects in the namespace
626 *
627 ******************************************************************************/
628
629 static ACPI_STATUS
630 AcpiDbWalkForSpecificObjects (
631 ACPI_HANDLE ObjHandle,
632 UINT32 NestingLevel,
633 void *Context,
634 void **ReturnValue)
635 {
636 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context;
637 ACPI_BUFFER Buffer;
638 ACPI_STATUS Status;
639
640
641 Info->Count++;
642
643 /* Get and display the full pathname to this object */
644
645 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
646 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
647 if (ACPI_FAILURE (Status))
648 {
649 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
650 return (AE_OK);
651 }
652
653 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
654 ACPI_FREE (Buffer.Pointer);
655
656 /* Dump short info about the object */
657
658 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
659 return (AE_OK);
660 }
661
662
663 /*******************************************************************************
664 *
665 * FUNCTION: AcpiDbDisplayObjects
666 *
667 * PARAMETERS: ObjTypeArg - Type of object to display
668 * DisplayCountArg - Max depth to display
669 *
670 * RETURN: None
671 *
672 * DESCRIPTION: Display objects in the namespace of the requested type
673 *
674 ******************************************************************************/
675
676 ACPI_STATUS
677 AcpiDbDisplayObjects (
678 char *ObjTypeArg,
679 char *DisplayCountArg)
680 {
681 ACPI_WALK_INFO Info;
682 ACPI_OBJECT_TYPE Type;
683 ACPI_OBJECT_INFO *ObjectInfo;
684 UINT32 i;
685 UINT32 TotalObjects = 0;
686
687
688 /* No argument means display summary/count of all object types */
689
690 if (!ObjTypeArg)
691 {
692 ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO));
693
694 /* Walk the namespace from the root */
695
696 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
697 ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL,
698 (void *) ObjectInfo, NULL);
699
700 AcpiOsPrintf ("\nSummary of namespace objects:\n\n");
701
702 for (i = 0; i < ACPI_TOTAL_TYPES; i++)
703 {
704 AcpiOsPrintf ("%8u %s\n", ObjectInfo->Types[i],
705 AcpiUtGetTypeName (i));
706
707 TotalObjects += ObjectInfo->Types[i];
708 }
709
710 AcpiOsPrintf ("\n%8u Total namespace objects\n\n",
711 TotalObjects);
712
713 ACPI_FREE (ObjectInfo);
714 return (AE_OK);
715 }
716
717 /* Get the object type */
718
719 Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
720 if (Type == ACPI_TYPE_NOT_FOUND)
721 {
722 AcpiOsPrintf ("Invalid or unsupported argument\n");
723 return (AE_OK);
724 }
725
726 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
727 AcpiOsPrintf (
728 "Objects of type [%s] defined in the current ACPI Namespace:\n",
729 AcpiUtGetTypeName (Type));
730
731 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
732
733 Info.Count = 0;
734 Info.OwnerId = ACPI_OWNER_ID_MAX;
735 Info.DebugLevel = ACPI_UINT32_MAX;
736 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
737
738 /* Walk the namespace from the root */
739
740 (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
741 AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
742
743 AcpiOsPrintf (
744 "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
745 Info.Count, AcpiUtGetTypeName (Type));
746
747 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
748 return (AE_OK);
749 }
750
751
752 /*******************************************************************************
753 *
754 * FUNCTION: AcpiDbIntegrityWalk
755 *
756 * PARAMETERS: Callback from WalkNamespace
757 *
758 * RETURN: Status
759 *
760 * DESCRIPTION: Examine one NS node for valid values.
761 *
762 ******************************************************************************/
763
764 static ACPI_STATUS
765 AcpiDbIntegrityWalk (
766 ACPI_HANDLE ObjHandle,
767 UINT32 NestingLevel,
768 void *Context,
769 void **ReturnValue)
770 {
771 ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context;
772 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
773 ACPI_OPERAND_OBJECT *Object;
774 BOOLEAN Alias = TRUE;
775
776
777 Info->Nodes++;
778
779 /* Verify the NS node, and dereference aliases */
780
781 while (Alias)
782 {
783 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
784 {
785 AcpiOsPrintf (
786 "Invalid Descriptor Type for Node %p [%s] - "
787 "is %2.2X should be %2.2X\n",
788 Node, AcpiUtGetDescriptorName (Node),
789 ACPI_GET_DESCRIPTOR_TYPE (Node), ACPI_DESC_TYPE_NAMED);
790 return (AE_OK);
791 }
792
793 if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS) ||
794 (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
795 {
796 Node = (ACPI_NAMESPACE_NODE *) Node->Object;
797 }
798 else
799 {
800 Alias = FALSE;
801 }
802 }
803
804 if (Node->Type > ACPI_TYPE_LOCAL_MAX)
805 {
806 AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
807 Node, Node->Type);
808 return (AE_OK);
809 }
810
811 if (!AcpiUtValidNameseg (Node->Name.Ascii))
812 {
813 AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
814 return (AE_OK);
815 }
816
817 Object = AcpiNsGetAttachedObject (Node);
818 if (Object)
819 {
820 Info->Objects++;
821 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
822 {
823 AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
824 Object, AcpiUtGetDescriptorName (Object));
825 }
826 }
827
828 return (AE_OK);
829 }
830
831
832 /*******************************************************************************
833 *
834 * FUNCTION: AcpiDbCheckIntegrity
835 *
836 * PARAMETERS: None
837 *
838 * RETURN: None
839 *
840 * DESCRIPTION: Check entire namespace for data structure integrity
841 *
842 ******************************************************************************/
843
844 void
845 AcpiDbCheckIntegrity (
846 void)
847 {
848 ACPI_INTEGRITY_INFO Info = {0,0};
849
850 /* Search all nodes in namespace */
851
852 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
853 ACPI_UINT32_MAX, AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
854
855 AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
856 Info.Nodes, Info.Objects);
857 }
858
859
860 /*******************************************************************************
861 *
862 * FUNCTION: AcpiDbWalkForReferences
863 *
864 * PARAMETERS: Callback from WalkNamespace
865 *
866 * RETURN: Status
867 *
868 * DESCRIPTION: Check if this namespace object refers to the target object
869 * that is passed in as the context value.
870 *
871 * Note: Currently doesn't check subobjects within the Node's object
872 *
873 ******************************************************************************/
874
875 static ACPI_STATUS
876 AcpiDbWalkForReferences (
877 ACPI_HANDLE ObjHandle,
878 UINT32 NestingLevel,
879 void *Context,
880 void **ReturnValue)
881 {
882 ACPI_OPERAND_OBJECT *ObjDesc = (ACPI_OPERAND_OBJECT *) Context;
883 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
884
885
886 /* Check for match against the namespace node itself */
887
888 if (Node == (void *) ObjDesc)
889 {
890 AcpiOsPrintf ("Object is a Node [%4.4s]\n",
891 AcpiUtGetNodeName (Node));
892 }
893
894 /* Check for match against the object attached to the node */
895
896 if (AcpiNsGetAttachedObject (Node) == ObjDesc)
897 {
898 AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
899 Node, AcpiUtGetNodeName (Node));
900 }
901
902 return (AE_OK);
903 }
904
905
906 /*******************************************************************************
907 *
908 * FUNCTION: AcpiDbFindReferences
909 *
910 * PARAMETERS: ObjectArg - String with hex value of the object
911 *
912 * RETURN: None
913 *
914 * DESCRIPTION: Search namespace for all references to the input object
915 *
916 ******************************************************************************/
917
918 void
919 AcpiDbFindReferences (
920 char *ObjectArg)
921 {
922 ACPI_OPERAND_OBJECT *ObjDesc;
923 ACPI_SIZE Address;
924
925
926 /* Convert string to object pointer */
927
928 Address = strtoul (ObjectArg, NULL, 16);
929 ObjDesc = ACPI_TO_POINTER (Address);
930
931 /* Search all nodes in namespace */
932
933 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
934 ACPI_UINT32_MAX, AcpiDbWalkForReferences, NULL,
935 (void *) ObjDesc, NULL);
936 }
937
938
939 /*******************************************************************************
940 *
941 * FUNCTION: AcpiDbBusWalk
942 *
943 * PARAMETERS: Callback from WalkNamespace
944 *
945 * RETURN: Status
946 *
947 * DESCRIPTION: Display info about device objects that have a corresponding
948 * _PRT method.
949 *
950 ******************************************************************************/
951
952 static ACPI_STATUS
953 AcpiDbBusWalk (
954 ACPI_HANDLE ObjHandle,
955 UINT32 NestingLevel,
956 void *Context,
957 void **ReturnValue)
958 {
959 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
960 ACPI_STATUS Status;
961 ACPI_BUFFER Buffer;
962 ACPI_NAMESPACE_NODE *TempNode;
963 ACPI_DEVICE_INFO *Info;
964 UINT32 i;
965
966
967 if ((Node->Type != ACPI_TYPE_DEVICE) &&
968 (Node->Type != ACPI_TYPE_PROCESSOR))
969 {
970 return (AE_OK);
971 }
972
973 /* Exit if there is no _PRT under this device */
974
975 Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
976 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
977 if (ACPI_FAILURE (Status))
978 {
979 return (AE_OK);
980 }
981
982 /* Get the full path to this device object */
983
984 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
985 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
986 if (ACPI_FAILURE (Status))
987 {
988 AcpiOsPrintf ("Could Not get pathname for object %p\n",
989 ObjHandle);
990 return (AE_OK);
991 }
992
993 Status = AcpiGetObjectInfo (ObjHandle, &Info);
994 if (ACPI_FAILURE (Status))
995 {
996 return (AE_OK);
997 }
998
999 /* Display the full path */
1000
1001 AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
1002 ACPI_FREE (Buffer.Pointer);
1003
1004 if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
1005 {
1006 AcpiOsPrintf (" - Is PCI Root Bridge");
1007 }
1008 AcpiOsPrintf ("\n");
1009
1010 /* _PRT info */
1011
1012 AcpiOsPrintf ("_PRT: %p\n", TempNode);
1013
1014 /* Dump _ADR, _HID, _UID, _CID */
1015
1016 if (Info->Valid & ACPI_VALID_ADR)
1017 {
1018 AcpiOsPrintf ("_ADR: %8.8X%8.8X\n",
1019 ACPI_FORMAT_UINT64 (Info->Address));
1020 }
1021 else
1022 {
1023 AcpiOsPrintf ("_ADR: <Not Present>\n");
1024 }
1025
1026 if (Info->Valid & ACPI_VALID_HID)
1027 {
1028 AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
1029 }
1030 else
1031 {
1032 AcpiOsPrintf ("_HID: <Not Present>\n");
1033 }
1034
1035 if (Info->Valid & ACPI_VALID_UID)
1036 {
1037 AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
1038 }
1039 else
1040 {
1041 AcpiOsPrintf ("_UID: <Not Present>\n");
1042 }
1043
1044 if (Info->Valid & ACPI_VALID_CID)
1045 {
1046 for (i = 0; i < Info->CompatibleIdList.Count; i++)
1047 {
1048 AcpiOsPrintf ("_CID: %s\n",
1049 Info->CompatibleIdList.Ids[i].String);
1050 }
1051 }
1052 else
1053 {
1054 AcpiOsPrintf ("_CID: <Not Present>\n");
1055 }
1056
1057 ACPI_FREE (Info);
1058 return (AE_OK);
1059 }
1060
1061
1062 /*******************************************************************************
1063 *
1064 * FUNCTION: AcpiDbGetBusInfo
1065 *
1066 * PARAMETERS: None
1067 *
1068 * RETURN: None
1069 *
1070 * DESCRIPTION: Display info about system busses.
1071 *
1072 ******************************************************************************/
1073
1074 void
1075 AcpiDbGetBusInfo (
1076 void)
1077 {
1078 /* Search all nodes in namespace */
1079
1080 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1081 ACPI_UINT32_MAX, AcpiDbBusWalk, NULL, NULL, NULL);
1082 }
1083