dbnames.c revision 1.15 1 /*******************************************************************************
2 *
3 * Module Name: dbnames - Debugger commands for the acpi namespace
4 *
5 ******************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2021, 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 AcpiEvaluateObject (ObjHandle, NULL, NULL, &Buffer);
670
671 /*
672 * Since this is a field unit, surround the output in braces
673 */
674 AcpiOsPrintf ("{");
675
676 RetValue = (ACPI_OBJECT *) Buffer.Pointer;
677 switch (RetValue->Type)
678 {
679 case ACPI_TYPE_INTEGER:
680
681 AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (RetValue->Integer.Value));
682 break;
683
684 case ACPI_TYPE_BUFFER:
685
686 AcpiUtDumpBuffer (RetValue->Buffer.Pointer,
687 RetValue->Buffer.Length, DB_DISPLAY_DATA_ONLY | DB_BYTE_DISPLAY, 0);
688 break;
689
690 default:
691
692 break;
693 }
694
695 AcpiOsPrintf ("}\n");
696
697 ACPI_FREE (Buffer.Pointer);
698 return (AE_OK);
699 }
700
701
702 /*******************************************************************************
703 *
704 * FUNCTION: AcpiDbWalkForSpecificObjects
705 *
706 * PARAMETERS: Callback from WalkNamespace
707 *
708 * RETURN: Status
709 *
710 * DESCRIPTION: Display short info about objects in the namespace
711 *
712 ******************************************************************************/
713
714 static ACPI_STATUS
715 AcpiDbWalkForSpecificObjects (
716 ACPI_HANDLE ObjHandle,
717 UINT32 NestingLevel,
718 void *Context,
719 void **ReturnValue)
720 {
721 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context;
722 ACPI_BUFFER Buffer;
723 ACPI_STATUS Status;
724
725
726 Info->Count++;
727
728 /* Get and display the full pathname to this object */
729
730 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
731 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
732 if (ACPI_FAILURE (Status))
733 {
734 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
735 return (AE_OK);
736 }
737
738 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
739 ACPI_FREE (Buffer.Pointer);
740
741 /* Dump short info about the object */
742
743 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
744 return (AE_OK);
745 }
746
747
748 /*******************************************************************************
749 *
750 * FUNCTION: AcpiDbDisplayObjects
751 *
752 * PARAMETERS: ObjTypeArg - Type of object to display
753 * DisplayCountArg - Max depth to display
754 *
755 * RETURN: None
756 *
757 * DESCRIPTION: Display objects in the namespace of the requested type
758 *
759 ******************************************************************************/
760
761 ACPI_STATUS
762 AcpiDbDisplayObjects (
763 char *ObjTypeArg,
764 char *DisplayCountArg)
765 {
766 ACPI_WALK_INFO Info;
767 ACPI_OBJECT_TYPE Type;
768 ACPI_OBJECT_INFO *ObjectInfo;
769 UINT32 i;
770 UINT32 TotalObjects = 0;
771
772
773 /* No argument means display summary/count of all object types */
774
775 if (!ObjTypeArg)
776 {
777 ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO));
778
779 /* Walk the namespace from the root */
780
781 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
782 ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL,
783 (void *) ObjectInfo, NULL);
784
785 AcpiOsPrintf ("\nSummary of namespace objects:\n\n");
786
787 for (i = 0; i < ACPI_TOTAL_TYPES; i++)
788 {
789 AcpiOsPrintf ("%8u %s\n", ObjectInfo->Types[i],
790 AcpiUtGetTypeName (i));
791
792 TotalObjects += ObjectInfo->Types[i];
793 }
794
795 AcpiOsPrintf ("\n%8u Total namespace objects\n\n",
796 TotalObjects);
797
798 ACPI_FREE (ObjectInfo);
799 return (AE_OK);
800 }
801
802 /* Get the object type */
803
804 Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
805 if (Type == ACPI_TYPE_NOT_FOUND)
806 {
807 AcpiOsPrintf ("Invalid or unsupported argument\n");
808 return (AE_OK);
809 }
810
811 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
812 AcpiOsPrintf (
813 "Objects of type [%s] defined in the current ACPI Namespace:\n",
814 AcpiUtGetTypeName (Type));
815
816 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
817
818 Info.Count = 0;
819 Info.OwnerId = ACPI_OWNER_ID_MAX;
820 Info.DebugLevel = ACPI_UINT32_MAX;
821 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
822
823 /* Walk the namespace from the root */
824
825 (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
826 AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
827
828 AcpiOsPrintf (
829 "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
830 Info.Count, AcpiUtGetTypeName (Type));
831
832 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
833 return (AE_OK);
834 }
835
836
837 /*******************************************************************************
838 *
839 * FUNCTION: AcpiDbDisplayFields
840 *
841 * PARAMETERS: ObjTypeArg - Type of object to display
842 * DisplayCountArg - Max depth to display
843 *
844 * RETURN: None
845 *
846 * DESCRIPTION: Display objects in the namespace of the requested type
847 *
848 ******************************************************************************/
849
850 ACPI_STATUS
851 AcpiDbDisplayFields (
852 UINT32 AddressSpaceId)
853 {
854 ACPI_REGION_WALK_INFO Info;
855
856
857 Info.Count = 0;
858 Info.OwnerId = ACPI_OWNER_ID_MAX;
859 Info.DebugLevel = ACPI_UINT32_MAX;
860 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
861 Info.AddressSpaceId = AddressSpaceId;
862
863 /* Walk the namespace from the root */
864
865 (void) AcpiWalkNamespace (ACPI_TYPE_LOCAL_REGION_FIELD, ACPI_ROOT_OBJECT,
866 ACPI_UINT32_MAX, AcpiDbWalkForFields, NULL,
867 (void *) &Info, NULL);
868
869 return (AE_OK);
870 }
871
872
873 /*******************************************************************************
874 *
875 * FUNCTION: AcpiDbIntegrityWalk
876 *
877 * PARAMETERS: Callback from WalkNamespace
878 *
879 * RETURN: Status
880 *
881 * DESCRIPTION: Examine one NS node for valid values.
882 *
883 ******************************************************************************/
884
885 static ACPI_STATUS
886 AcpiDbIntegrityWalk (
887 ACPI_HANDLE ObjHandle,
888 UINT32 NestingLevel,
889 void *Context,
890 void **ReturnValue)
891 {
892 ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context;
893 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
894 ACPI_OPERAND_OBJECT *Object;
895 BOOLEAN Alias = TRUE;
896
897
898 Info->Nodes++;
899
900 /* Verify the NS node, and dereference aliases */
901
902 while (Alias)
903 {
904 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
905 {
906 AcpiOsPrintf (
907 "Invalid Descriptor Type for Node %p [%s] - "
908 "is %2.2X should be %2.2X\n",
909 Node, AcpiUtGetDescriptorName (Node),
910 ACPI_GET_DESCRIPTOR_TYPE (Node), ACPI_DESC_TYPE_NAMED);
911 return (AE_OK);
912 }
913
914 if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS) ||
915 (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
916 {
917 Node = (ACPI_NAMESPACE_NODE *) Node->Object;
918 }
919 else
920 {
921 Alias = FALSE;
922 }
923 }
924
925 if (Node->Type > ACPI_TYPE_LOCAL_MAX)
926 {
927 AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
928 Node, Node->Type);
929 return (AE_OK);
930 }
931
932 if (!AcpiUtValidNameseg (Node->Name.Ascii))
933 {
934 AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
935 return (AE_OK);
936 }
937
938 Object = AcpiNsGetAttachedObject (Node);
939 if (Object)
940 {
941 Info->Objects++;
942 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
943 {
944 AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
945 Object, AcpiUtGetDescriptorName (Object));
946 }
947 }
948
949 return (AE_OK);
950 }
951
952
953 /*******************************************************************************
954 *
955 * FUNCTION: AcpiDbCheckIntegrity
956 *
957 * PARAMETERS: None
958 *
959 * RETURN: None
960 *
961 * DESCRIPTION: Check entire namespace for data structure integrity
962 *
963 ******************************************************************************/
964
965 void
966 AcpiDbCheckIntegrity (
967 void)
968 {
969 ACPI_INTEGRITY_INFO Info = {0,0};
970
971 /* Search all nodes in namespace */
972
973 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
974 ACPI_UINT32_MAX, AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
975
976 AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
977 Info.Nodes, Info.Objects);
978 }
979
980
981 /*******************************************************************************
982 *
983 * FUNCTION: AcpiDbWalkForReferences
984 *
985 * PARAMETERS: Callback from WalkNamespace
986 *
987 * RETURN: Status
988 *
989 * DESCRIPTION: Check if this namespace object refers to the target object
990 * that is passed in as the context value.
991 *
992 * Note: Currently doesn't check subobjects within the Node's object
993 *
994 ******************************************************************************/
995
996 static ACPI_STATUS
997 AcpiDbWalkForReferences (
998 ACPI_HANDLE ObjHandle,
999 UINT32 NestingLevel,
1000 void *Context,
1001 void **ReturnValue)
1002 {
1003 ACPI_OPERAND_OBJECT *ObjDesc = (ACPI_OPERAND_OBJECT *) Context;
1004 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1005
1006
1007 /* Check for match against the namespace node itself */
1008
1009 if (Node == (void *) ObjDesc)
1010 {
1011 AcpiOsPrintf ("Object is a Node [%4.4s]\n",
1012 AcpiUtGetNodeName (Node));
1013 }
1014
1015 /* Check for match against the object attached to the node */
1016
1017 if (AcpiNsGetAttachedObject (Node) == ObjDesc)
1018 {
1019 AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
1020 Node, AcpiUtGetNodeName (Node));
1021 }
1022
1023 return (AE_OK);
1024 }
1025
1026
1027 /*******************************************************************************
1028 *
1029 * FUNCTION: AcpiDbFindReferences
1030 *
1031 * PARAMETERS: ObjectArg - String with hex value of the object
1032 *
1033 * RETURN: None
1034 *
1035 * DESCRIPTION: Search namespace for all references to the input object
1036 *
1037 ******************************************************************************/
1038
1039 void
1040 AcpiDbFindReferences (
1041 char *ObjectArg)
1042 {
1043 ACPI_OPERAND_OBJECT *ObjDesc;
1044 ACPI_SIZE Address;
1045
1046
1047 /* Convert string to object pointer */
1048
1049 Address = strtoul (ObjectArg, NULL, 16);
1050 ObjDesc = ACPI_TO_POINTER (Address);
1051
1052 /* Search all nodes in namespace */
1053
1054 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1055 ACPI_UINT32_MAX, AcpiDbWalkForReferences, NULL,
1056 (void *) ObjDesc, NULL);
1057 }
1058
1059
1060 /*******************************************************************************
1061 *
1062 * FUNCTION: AcpiDbBusWalk
1063 *
1064 * PARAMETERS: Callback from WalkNamespace
1065 *
1066 * RETURN: Status
1067 *
1068 * DESCRIPTION: Display info about device objects that have a corresponding
1069 * _PRT method.
1070 *
1071 ******************************************************************************/
1072
1073 static ACPI_STATUS
1074 AcpiDbBusWalk (
1075 ACPI_HANDLE ObjHandle,
1076 UINT32 NestingLevel,
1077 void *Context,
1078 void **ReturnValue)
1079 {
1080 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1081 ACPI_STATUS Status;
1082 ACPI_BUFFER Buffer;
1083 ACPI_NAMESPACE_NODE *TempNode;
1084 ACPI_DEVICE_INFO *Info;
1085 UINT32 i;
1086
1087
1088 if ((Node->Type != ACPI_TYPE_DEVICE) &&
1089 (Node->Type != ACPI_TYPE_PROCESSOR))
1090 {
1091 return (AE_OK);
1092 }
1093
1094 /* Exit if there is no _PRT under this device */
1095
1096 Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
1097 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
1098 if (ACPI_FAILURE (Status))
1099 {
1100 return (AE_OK);
1101 }
1102
1103 /* Get the full path to this device object */
1104
1105 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1106 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
1107 if (ACPI_FAILURE (Status))
1108 {
1109 AcpiOsPrintf ("Could Not get pathname for object %p\n",
1110 ObjHandle);
1111 return (AE_OK);
1112 }
1113
1114 Status = AcpiGetObjectInfo (ObjHandle, &Info);
1115 if (ACPI_FAILURE (Status))
1116 {
1117 return (AE_OK);
1118 }
1119
1120 /* Display the full path */
1121
1122 AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
1123 ACPI_FREE (Buffer.Pointer);
1124
1125 if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
1126 {
1127 AcpiOsPrintf (" - Is PCI Root Bridge");
1128 }
1129 AcpiOsPrintf ("\n");
1130
1131 /* _PRT info */
1132
1133 AcpiOsPrintf ("_PRT: %p\n", TempNode);
1134
1135 /* Dump _ADR, _HID, _UID, _CID */
1136
1137 if (Info->Valid & ACPI_VALID_ADR)
1138 {
1139 AcpiOsPrintf ("_ADR: %8.8X%8.8X\n",
1140 ACPI_FORMAT_UINT64 (Info->Address));
1141 }
1142 else
1143 {
1144 AcpiOsPrintf ("_ADR: <Not Present>\n");
1145 }
1146
1147 if (Info->Valid & ACPI_VALID_HID)
1148 {
1149 AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
1150 }
1151 else
1152 {
1153 AcpiOsPrintf ("_HID: <Not Present>\n");
1154 }
1155
1156 if (Info->Valid & ACPI_VALID_UID)
1157 {
1158 AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
1159 }
1160 else
1161 {
1162 AcpiOsPrintf ("_UID: <Not Present>\n");
1163 }
1164
1165 if (Info->Valid & ACPI_VALID_CID)
1166 {
1167 for (i = 0; i < Info->CompatibleIdList.Count; i++)
1168 {
1169 AcpiOsPrintf ("_CID: %s\n",
1170 Info->CompatibleIdList.Ids[i].String);
1171 }
1172 }
1173 else
1174 {
1175 AcpiOsPrintf ("_CID: <Not Present>\n");
1176 }
1177
1178 ACPI_FREE (Info);
1179 return (AE_OK);
1180 }
1181
1182
1183 /*******************************************************************************
1184 *
1185 * FUNCTION: AcpiDbGetBusInfo
1186 *
1187 * PARAMETERS: None
1188 *
1189 * RETURN: None
1190 *
1191 * DESCRIPTION: Display info about system buses.
1192 *
1193 ******************************************************************************/
1194
1195 void
1196 AcpiDbGetBusInfo (
1197 void)
1198 {
1199 /* Search all nodes in namespace */
1200
1201 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1202 ACPI_UINT32_MAX, AcpiDbBusWalk, NULL, NULL, NULL);
1203 }
1204