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