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