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