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