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