1/*******************************************************************************
2 *
3 * Module Name: dbcmds - debug commands and output routines
4 * $Revision: 1.132 $
5 *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117
118#include <contrib/dev/acpica/acpi.h>
119#include <contrib/dev/acpica/acdispat.h>
120#include <contrib/dev/acpica/amlcode.h>
121#include <contrib/dev/acpica/acnamesp.h>
122#include <contrib/dev/acpica/acevents.h>
123#include <contrib/dev/acpica/acdebug.h>
124#include <contrib/dev/acpica/acresrc.h>
125#include <contrib/dev/acpica/acdisasm.h>
126
127
128#include <contrib/dev/acpica/acparser.h>
129
130#ifdef ACPI_DEBUGGER
131
132#define _COMPONENT ACPI_CA_DEBUGGER
133 ACPI_MODULE_NAME ("dbcmds")
134
135/* Local prototypes */
136
137static ACPI_STATUS
138AcpiDbIntegrityWalk (
139 ACPI_HANDLE ObjHandle,
140 UINT32 NestingLevel,
141 void *Context,
142 void **ReturnValue);
143
144static ACPI_STATUS
145AcpiDbWalkAndMatchName (
146 ACPI_HANDLE ObjHandle,
147 UINT32 NestingLevel,
148 void *Context,
149 void **ReturnValue);
150
151static ACPI_STATUS
152AcpiDbWalkForReferences (
153 ACPI_HANDLE ObjHandle,
154 UINT32 NestingLevel,
155 void *Context,
156 void **ReturnValue);
157
158static ACPI_STATUS
159AcpiDbWalkForSpecificObjects (
160 ACPI_HANDLE ObjHandle,
161 UINT32 NestingLevel,
162 void *Context,
163 void **ReturnValue);
164
165static ACPI_NAMESPACE_NODE *
166AcpiDbConvertToNode (
167 char *InString);
168
169static void
170AcpiDmCompareAmlResources (
171 UINT8 *Aml1Buffer,
172 ACPI_RSDESC_SIZE Aml1BufferLength,
173 UINT8 *Aml2Buffer,
174 ACPI_RSDESC_SIZE Aml2BufferLength);
175
176static ACPI_STATUS
177AcpiDmTestResourceConversion (
178 ACPI_NAMESPACE_NODE *Node,
179 char *Name);
180
181
182/*
183 * Arguments for the Objects command
184 * These object types map directly to the ACPI_TYPES
185 */
186static ARGUMENT_INFO AcpiDbObjectTypes [] =
187{
188 {"ANY"},
189 {"INTEGERS"},
190 {"STRINGS"},
191 {"BUFFERS"},
192 {"PACKAGES"},
193 {"FIELDS"},
194 {"DEVICES"},
195 {"EVENTS"},
196 {"METHODS"},
197 {"MUTEXES"},
198 {"REGIONS"},
199 {"POWERRESOURCES"},
200 {"PROCESSORS"},
201 {"THERMALZONES"},
202 {"BUFFERFIELDS"},
203 {"DDBHANDLES"},
204 {NULL} /* Must be null terminated */
205};
206
207
208/*******************************************************************************
209 *
210 * FUNCTION: AcpiDbConvertToNode
211 *
212 * PARAMETERS: InString - String to convert
213 *
214 * RETURN: Pointer to a NS node
215 *
216 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
217 * alpha strings.
218 *
219 ******************************************************************************/
220
221static ACPI_NAMESPACE_NODE *
222AcpiDbConvertToNode (
223 char *InString)
224{
225 ACPI_NAMESPACE_NODE *Node;
226
227
228 if ((*InString >= 0x30) && (*InString <= 0x39))
229 {
230 /* Numeric argument, convert */
231
232 Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
233 if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
234 {
235 AcpiOsPrintf ("Address %p is invalid in this address space\n",
236 Node);
237 return (NULL);
238 }
239
240 /* Make sure pointer is valid NS node */
241
242 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
243 {
244 AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
245 Node, AcpiUtGetDescriptorName (Node));
246 return (NULL);
247 }
248 }
249 else
250 {
251 /* Alpha argument */
252 /* The parameter is a name string that must be resolved to a
253 * Named obj
254 */
255 Node = AcpiDbLocalNsLookup (InString);
256 if (!Node)
257 {
258 Node = AcpiGbl_RootNode;
259 }
260 }
261
262 return (Node);
263}
264
265
266/*******************************************************************************
267 *
268 * FUNCTION: AcpiDbSleep
269 *
270 * PARAMETERS: ObjectArg - Desired sleep state (0-5)
271 *
272 * RETURN: Status
273 *
274 * DESCRIPTION: Simulate a sleep/wake sequence
275 *
276 ******************************************************************************/
277
278ACPI_STATUS
279AcpiDbSleep (
280 char *ObjectArg)
281{
282#if ACPI_MACHINE_WIDTH == 16
283 return (AE_OK);
284#else
285 ACPI_STATUS Status;
286 UINT8 SleepState;
287
288
289 SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
290
291 AcpiOsPrintf ("**** Prepare to sleep ****\n");
292 Status = AcpiEnterSleepStatePrep (SleepState);
293 if (ACPI_FAILURE (Status))
294 {
295 return (Status);
296 }
297
298 AcpiOsPrintf ("**** Going to sleep ****\n");
299 Status = AcpiEnterSleepState (SleepState);
300 if (ACPI_FAILURE (Status))
301 {
302 return (Status);
303 }
304
305 AcpiOsPrintf ("**** returning from sleep ****\n");
306 Status = AcpiLeaveSleepState (SleepState);
307
308 return (Status);
309#endif
310}
311
312
313/*******************************************************************************
314 *
315 * FUNCTION: AcpiDbWalkForReferences
316 *
317 * PARAMETERS: Callback from WalkNamespace
318 *
319 * RETURN: Status
320 *
321 * DESCRIPTION: Check if this namespace object refers to the target object
322 * that is passed in as the context value.
323 *
324 * Note: Currently doesn't check subobjects within the Node's object
325 *
326 ******************************************************************************/
327
328static ACPI_STATUS
329AcpiDbWalkForReferences (
330 ACPI_HANDLE ObjHandle,
331 UINT32 NestingLevel,
332 void *Context,
333 void **ReturnValue)
334{
335 ACPI_OPERAND_OBJECT *ObjDesc = (ACPI_OPERAND_OBJECT *) Context;
336 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
337
338
339 /* Check for match against the namespace node itself */
340
341 if (Node == (void *) ObjDesc)
342 {
343 AcpiOsPrintf ("Object is a Node [%4.4s]\n",
344 AcpiUtGetNodeName (Node));
345 }
346
347 /* Check for match against the object attached to the node */
348
349 if (AcpiNsGetAttachedObject (Node) == ObjDesc)
350 {
351 AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
352 Node, AcpiUtGetNodeName (Node));
353 }
354
355 return (AE_OK);
356}
357
358
359/*******************************************************************************
360 *
361 * FUNCTION: AcpiDbFindReferences
362 *
363 * PARAMETERS: ObjectArg - String with hex value of the object
364 *
365 * RETURN: None
366 *
367 * DESCRIPTION: Search namespace for all references to the input object
368 *
369 ******************************************************************************/
370
371void
372AcpiDbFindReferences (
373 char *ObjectArg)
374{
375 ACPI_OPERAND_OBJECT *ObjDesc;
376
377
378 /* Convert string to object pointer */
379
380 ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
381
382 /* Search all nodes in namespace */
383
384 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
385 AcpiDbWalkForReferences, (void *) ObjDesc, NULL);
386}
387
388
389/*******************************************************************************
390 *
391 * FUNCTION: AcpiDbDisplayLocks
392 *
393 * PARAMETERS: None
394 *
395 * RETURN: None
396 *
397 * DESCRIPTION: Display information about internal mutexes.
398 *
399 ******************************************************************************/
400
401void
402AcpiDbDisplayLocks (
403 void)
404{
405 UINT32 i;
406
407
408 for (i = 0; i < MAX_MUTEX; i++)
409 {
410 AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
411 AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
412 ? "Locked" : "Unlocked");
413 }
414}
415
416
417/*******************************************************************************
418 *
419 * FUNCTION: AcpiDbDisplayTableInfo
420 *
421 * PARAMETERS: TableArg - String with name of table to be displayed
422 *
423 * RETURN: None
424 *
425 * DESCRIPTION: Display information about loaded tables. Current
426 * implementation displays all loaded tables.
427 *
428 ******************************************************************************/
429
430void
431AcpiDbDisplayTableInfo (
432 char *TableArg)
433{
434 UINT32 i;
435 ACPI_TABLE_DESC *TableDesc;
436
437
438 for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
439 {
440 TableDesc = AcpiGbl_TableLists[i].Next;
441 while (TableDesc)
442 {
443 AcpiOsPrintf ( "%s at %p length %.5X",
444 AcpiGbl_TableData[i].Name, TableDesc->Pointer,
445 (UINT32) TableDesc->Length);
446
447 if (i != ACPI_TABLE_FACS)
448 {
449 AcpiOsPrintf (" OemID=%6s TableId=%8s OemRevision=%8.8X",
450 TableDesc->Pointer->OemId,
451 TableDesc->Pointer->OemTableId,
452 TableDesc->Pointer->OemRevision);
453 }
454 AcpiOsPrintf ("\n");
455
456 TableDesc = TableDesc->Next;
457 }
458 }
459}
460
461
462/*******************************************************************************
463 *
464 * FUNCTION: AcpiDbUnloadAcpiTable
465 *
466 * PARAMETERS: TableArg - Name of the table to be unloaded
467 * InstanceArg - Which instance of the table to unload (if
468 * there are multiple tables of the same type)
469 *
470 * RETURN: Nonde
471 *
472 * DESCRIPTION: Unload an ACPI table.
473 * Instance is not implemented
474 *
475 ******************************************************************************/
476
477void
478AcpiDbUnloadAcpiTable (
479 char *TableArg,
480 char *InstanceArg)
481{
482 UINT32 i;
483 ACPI_STATUS Status;
484
485
486 /* Search all tables for the target type */
487
488 for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
489 {
490 if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
491 AcpiGbl_TableData[i].SigLength))
492 {
493 /* Found the table, unload it */
494
495 Status = AcpiUnloadTable (i);
496 if (ACPI_SUCCESS (Status))
497 {
498 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
499 }
500 else
501 {
502 AcpiOsPrintf ("%s, while unloading [%s]\n",
503 AcpiFormatException (Status), TableArg);
504 }
505
506 return;
507 }
508 }
509
510 AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
511}
512
513
514/*******************************************************************************
515 *
516 * FUNCTION: AcpiDbSetMethodBreakpoint
517 *
518 * PARAMETERS: Location - AML offset of breakpoint
519 * WalkState - Current walk info
520 * Op - Current Op (from parse walk)
521 *
522 * RETURN: None
523 *
524 * DESCRIPTION: Set a breakpoint in a control method at the specified
525 * AML offset
526 *
527 ******************************************************************************/
528
529void
530AcpiDbSetMethodBreakpoint (
531 char *Location,
532 ACPI_WALK_STATE *WalkState,
533 ACPI_PARSE_OBJECT *Op)
534{
535 UINT32 Address;
536
537
538 if (!Op)
539 {
540 AcpiOsPrintf ("There is no method currently executing\n");
541 return;
542 }
543
544 /* Get and verify the breakpoint address */
545
546 Address = ACPI_STRTOUL (Location, NULL, 16);
547 if (Address <= Op->Common.AmlOffset)
548 {
549 AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
550 Address, Op->Common.AmlOffset);
551 }
552
553 /* Save breakpoint in current walk */
554
555 WalkState->UserBreakpoint = Address;
556 AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
557}
558
559
560/*******************************************************************************
561 *
562 * FUNCTION: AcpiDbSetMethodCallBreakpoint
563 *
564 * PARAMETERS: Op - Current Op (from parse walk)
565 *
566 * RETURN: None
567 *
568 * DESCRIPTION: Set a breakpoint in a control method at the specified
569 * AML offset
570 *
571 ******************************************************************************/
572
573void
574AcpiDbSetMethodCallBreakpoint (
575 ACPI_PARSE_OBJECT *Op)
576{
577
578
579 if (!Op)
580 {
581 AcpiOsPrintf ("There is no method currently executing\n");
582 return;
583 }
584
585 AcpiGbl_StepToNextCall = TRUE;
586}
587
588
589/*******************************************************************************
590 *
591 * FUNCTION: AcpiDbDisassembleAml
592 *
593 * PARAMETERS: Statements - Number of statements to disassemble
594 * Op - Current Op (from parse walk)
595 *
596 * RETURN: None
597 *
598 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
599 * of statements specified.
600 *
601 ******************************************************************************/
602
603void
604AcpiDbDisassembleAml (
605 char *Statements,
606 ACPI_PARSE_OBJECT *Op)
607{
608 UINT32 NumStatements = 8;
609
610
611 if (!Op)
612 {
613 AcpiOsPrintf ("There is no method currently executing\n");
614 return;
615 }
616
617 if (Statements)
618 {
619 NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
620 }
621
622 AcpiDmDisassemble (NULL, Op, NumStatements);
623}
624
625
626/*******************************************************************************
627 *
628 * FUNCTION: AcpiDbDisassembleMethod
629 *
630 * PARAMETERS: Name - Name of control method
631 *
632 * RETURN: None
633 *
634 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
635 * of statements specified.
636 *
637 ******************************************************************************/
638
639ACPI_STATUS
640AcpiDbDisassembleMethod (
641 char *Name)
642{
643 ACPI_STATUS Status;
644 ACPI_PARSE_OBJECT *Op;
645 ACPI_WALK_STATE *WalkState;
646 ACPI_OPERAND_OBJECT *ObjDesc;
647 ACPI_NAMESPACE_NODE *Method;
648
649
650 Method = AcpiDbConvertToNode (Name);
651 if (!Method)
652 {
653 return (AE_BAD_PARAMETER);
654 }
655
656 ObjDesc = Method->Object;
657
658 Op = AcpiPsCreateScopeOp ();
659 if (!Op)
660 {
661 return (AE_NO_MEMORY);
662 }
663
664 /* Create and initialize a new walk state */
665
666 WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
667 if (!WalkState)
668 {
669 return (AE_NO_MEMORY);
670 }
671
672 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
673 ObjDesc->Method.AmlStart,
674 ObjDesc->Method.AmlLength, NULL, 1);
675 if (ACPI_FAILURE (Status))
676 {
677 return (Status);
678 }
679
680 /* Parse the AML */
681
682 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
683 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
684 Status = AcpiPsParseAml (WalkState);
685
686 AcpiDmDisassemble (NULL, Op, 0);
687 AcpiPsDeleteParseTree (Op);
688 return (AE_OK);
689}
690
691
692/*******************************************************************************
693 *
694 * FUNCTION: AcpiDbDumpNamespace
695 *
696 * PARAMETERS: StartArg - Node to begin namespace dump
697 * DepthArg - Maximum tree depth to be dumped
698 *
699 * RETURN: None
700 *
701 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
702 * with type and other information.
703 *
704 ******************************************************************************/
705
706void
707AcpiDbDumpNamespace (
708 char *StartArg,
709 char *DepthArg)
710{
711 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode;
712 UINT32 MaxDepth = ACPI_UINT32_MAX;
713
714
715 /* No argument given, just start at the root and dump entire namespace */
716
717 if (StartArg)
718 {
719 SubtreeEntry = AcpiDbConvertToNode (StartArg);
720 if (!SubtreeEntry)
721 {
722 return;
723 }
724
725 /* Now we can check for the depth argument */
726
727 if (DepthArg)
728 {
729 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
730 }
731 }
732
733 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
734 AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
735 ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
736
737 /* Display the subtree */
738
739 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
740 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
741 ACPI_OWNER_ID_MAX, SubtreeEntry);
742 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
743}
744
745
746/*******************************************************************************
747 *
748 * FUNCTION: AcpiDbDumpNamespaceByOwner
749 *
750 * PARAMETERS: OwnerArg - Owner ID whose nodes will be displayed
751 * DepthArg - Maximum tree depth to be dumped
752 *
753 * RETURN: None
754 *
755 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
756 *
757 ******************************************************************************/
758
759void
760AcpiDbDumpNamespaceByOwner (
761 char *OwnerArg,
762 char *DepthArg)
763{
764 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode;
765 UINT32 MaxDepth = ACPI_UINT32_MAX;
766 ACPI_OWNER_ID OwnerId;
767
768
769 OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
770
771 /* Now we can check for the depth argument */
772
773 if (DepthArg)
774 {
775 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
776 }
777
778 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
779 AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
780
781 /* Display the subtree */
782
783 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
784 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
785 SubtreeEntry);
786 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
787}
788
789
790/*******************************************************************************
791 *
792 * FUNCTION: AcpiDbSendNotify
793 *
794 * PARAMETERS: Name - Name of ACPI object to send the notify to
795 * Value - Value of the notify to send.
796 *
797 * RETURN: None
798 *
799 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
800 * named object as an ACPI notify.
801 *
802 ******************************************************************************/
803
804void
805AcpiDbSendNotify (
806 char *Name,
807 UINT32 Value)
808{
809 ACPI_NAMESPACE_NODE *Node;
810 ACPI_STATUS Status;
811
812
813 /* Translate name to an Named object */
814
815 Node = AcpiDbConvertToNode (Name);
816 if (!Node)
817 {
818 return;
819 }
820
821 /* Decode Named object type */
822
823 switch (Node->Type)
824 {
825 case ACPI_TYPE_DEVICE:
826 case ACPI_TYPE_THERMAL:
827
828 /* Send the notify */
829
830 Status = AcpiEvQueueNotifyRequest (Node, Value);
831 if (ACPI_FAILURE (Status))
832 {
833 AcpiOsPrintf ("Could not queue notify\n");
834 }
835 break;
836
837 default:
838 AcpiOsPrintf ("Named object is not a device or a thermal object\n");
839 break;
840 }
841}
842
843
844/*******************************************************************************
845 *
846 * FUNCTION: AcpiDbSetMethodData
847 *
848 * PARAMETERS: TypeArg - L for local, A for argument
849 * IndexArg - which one
850 * ValueArg - Value to set.
851 *
852 * RETURN: None
853 *
854 * DESCRIPTION: Set a local or argument for the running control method.
855 * NOTE: only object supported is Number.
856 *
857 ******************************************************************************/
858
859void
860AcpiDbSetMethodData (
861 char *TypeArg,
862 char *IndexArg,
863 char *ValueArg)
864{
865 char Type;
866 UINT32 Index;
867 UINT32 Value;
868 ACPI_WALK_STATE *WalkState;
869 ACPI_OPERAND_OBJECT *ObjDesc;
870 ACPI_STATUS Status;
871 ACPI_NAMESPACE_NODE *Node;
872
873
874 /* Validate TypeArg */
875
876 AcpiUtStrupr (TypeArg);
877 Type = TypeArg[0];
878 if ((Type != 'L') &&
879 (Type != 'A') &&
880 (Type != 'N'))
881 {
882 AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
883 return;
884 }
885
886 Value = ACPI_STRTOUL (ValueArg, NULL, 16);
887
888 if (Type == 'N')
889 {
890 Node = AcpiDbConvertToNode (IndexArg);
891 if (Node->Type != ACPI_TYPE_INTEGER)
892 {
893 AcpiOsPrintf ("Can only set Integer nodes\n");
894 return;
895 }
896 ObjDesc = Node->Object;
897 ObjDesc->Integer.Value = Value;
898 return;
899 }
900
901 /* Get the index and value */
902
903 Index = ACPI_STRTOUL (IndexArg, NULL, 16);
904
905 WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
906 if (!WalkState)
907 {
908 AcpiOsPrintf ("There is no method currently executing\n");
909 return;
910 }
911
912 /* Create and initialize the new object */
913
914 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
915 if (!ObjDesc)
916 {
917 AcpiOsPrintf ("Could not create an internal object\n");
918 return;
919 }
920
921 ObjDesc->Integer.Value = Value;
922
923 /* Store the new object into the target */
924
925 switch (Type)
926 {
927 case 'A':
928
929 /* Set a method argument */
930
931 if (Index > ACPI_METHOD_MAX_ARG)
932 {
933 AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
934 return;
935 }
936
937 Status = AcpiDsStoreObjectToLocal (AML_ARG_OP, Index, ObjDesc,
938 WalkState);
939 if (ACPI_FAILURE (Status))
940 {
941 return;
942 }
943
944 ObjDesc = WalkState->Arguments[Index].Object;
945
946 AcpiOsPrintf ("Arg%d: ", Index);
947 AcpiDmDisplayInternalObject (ObjDesc, WalkState);
948 break;
949
950 case 'L':
951
952 /* Set a method local */
953
954 if (Index > ACPI_METHOD_MAX_LOCAL)
955 {
956 AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
957 return;
958 }
959
960 Status = AcpiDsStoreObjectToLocal (AML_LOCAL_OP, Index, ObjDesc,
961 WalkState);
962 if (ACPI_FAILURE (Status))
963 {
964 return;
965 }
966
967 ObjDesc = WalkState->LocalVariables[Index].Object;
968
969 AcpiOsPrintf ("Local%d: ", Index);
970 AcpiDmDisplayInternalObject (ObjDesc, WalkState);
971 break;
972
973 default:
974 break;
975 }
976}
977
978
979/*******************************************************************************
980 *
981 * FUNCTION: AcpiDbWalkForSpecificObjects
982 *
983 * PARAMETERS: Callback from WalkNamespace
984 *
985 * RETURN: Status
986 *
987 * DESCRIPTION: Display short info about objects in the namespace
988 *
989 ******************************************************************************/
990
991static ACPI_STATUS
992AcpiDbWalkForSpecificObjects (
993 ACPI_HANDLE ObjHandle,
994 UINT32 NestingLevel,
995 void *Context,
996 void **ReturnValue)
997{
998 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context;
999 ACPI_BUFFER Buffer;
1000 ACPI_STATUS Status;
1001
1002
1003 Info->Count++;
1004
1005 /* Get and display the full pathname to this object */
1006
1007 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1008 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1009 if (ACPI_FAILURE (Status))
1010 {
1011 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1012 return (AE_OK);
1013 }
1014
1015 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1016 ACPI_MEM_FREE (Buffer.Pointer);
1017
1018 /* Dump short info about the object */
1019
1020 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1021 return (AE_OK);
1022}
1023
1024
1025/*******************************************************************************
1026 *
1027 * FUNCTION: AcpiDbDisplayObjects
1028 *
1029 * PARAMETERS: ObjTypeArg - Type of object to display
1030 * DisplayCountArg - Max depth to display
1031 *
1032 * RETURN: None
1033 *
1034 * DESCRIPTION: Display objects in the namespace of the requested type
1035 *
1036 ******************************************************************************/
1037
1038ACPI_STATUS
1039AcpiDbDisplayObjects (
1040 char *ObjTypeArg,
1041 char *DisplayCountArg)
1042{
1043 ACPI_WALK_INFO Info;
1044 ACPI_OBJECT_TYPE Type;
1045
1046
1047 /* Get the object type */
1048
1049 Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1050 if (Type == ACPI_TYPE_NOT_FOUND)
1051 {
1052 AcpiOsPrintf ("Invalid or unsupported argument\n");
1053 return (AE_OK);
1054 }
1055
1056 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1057 AcpiOsPrintf (
1058 "Objects of type [%s] defined in the current ACPI Namespace:\n",
1059 AcpiUtGetTypeName (Type));
1060
1061 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1062
1063 Info.Count = 0;
1064 Info.OwnerId = ACPI_OWNER_ID_MAX;
1065 Info.DebugLevel = ACPI_UINT32_MAX;
1066 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1067
1068 /* Walk the namespace from the root */
1069
1070 (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1071 AcpiDbWalkForSpecificObjects, (void *) &Info, NULL);
1072
1073 AcpiOsPrintf (
1074 "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1075 Info.Count, AcpiUtGetTypeName (Type));
1076
1077 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1078 return (AE_OK);
1079}
1080
1081
1082/*******************************************************************************
1083 *
1084 * FUNCTION: AcpiDbWalkAndMatchName
1085 *
1086 * PARAMETERS: Callback from WalkNamespace
1087 *
1088 * RETURN: Status
1089 *
1090 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
1091 * are supported -- '?' matches any character.
1092 *
1093 ******************************************************************************/
1094
1095static ACPI_STATUS
1096AcpiDbWalkAndMatchName (
1097 ACPI_HANDLE ObjHandle,
1098 UINT32 NestingLevel,
1099 void *Context,
1100 void **ReturnValue)
1101{
1102 ACPI_STATUS Status;
1103 char *RequestedName = (char *) Context;
1104 UINT32 i;
1105 ACPI_BUFFER Buffer;
1106 ACPI_WALK_INFO Info;
1107
1108
1109 /* Check for a name match */
1110
1111 for (i = 0; i < 4; i++)
1112 {
1113 /* Wildcard support */
1114
1115 if ((RequestedName[i] != '?') &&
1116 (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1117 {
1118 /* No match, just exit */
1119
1120 return (AE_OK);
1121 }
1122 }
1123
1124 /* Get the full pathname to this object */
1125
1126 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1127 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1128 if (ACPI_FAILURE (Status))
1129 {
1130 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1131 }
1132 else
1133 {
1134 Info.OwnerId = ACPI_OWNER_ID_MAX;
1135 Info.DebugLevel = ACPI_UINT32_MAX;
1136 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1137
1138 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1139 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1140 ACPI_MEM_FREE (Buffer.Pointer);
1141 }
1142
1143 return (AE_OK);
1144}
1145
1146
1147/*******************************************************************************
1148 *
1149 * FUNCTION: AcpiDbFindNameInNamespace
1150 *
1151 * PARAMETERS: NameArg - The 4-character ACPI name to find.
1152 * wildcards are supported.
1153 *
1154 * RETURN: None
1155 *
1156 * DESCRIPTION: Search the namespace for a given name (with wildcards)
1157 *
1158 ******************************************************************************/
1159
1160ACPI_STATUS
1161AcpiDbFindNameInNamespace (
1162 char *NameArg)
1163{
1164
1165 if (ACPI_STRLEN (NameArg) > 4)
1166 {
1167 AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1168 return (AE_OK);
1169 }
1170
1171 /* Walk the namespace from the root */
1172
1173 AcpiUtStrupr (NameArg);
1174 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1175 AcpiDbWalkAndMatchName, NameArg, NULL);
1176
1177 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1178 return (AE_OK);
1179}
1180
1181
1182/*******************************************************************************
1183 *
1184 * FUNCTION: AcpiDbSetScope
1185 *
1186 * PARAMETERS: Name - New scope path
1187 *
1188 * RETURN: Status
1189 *
1190 * DESCRIPTION: Set the "current scope" as maintained by this utility.
1191 * The scope is used as a prefix to ACPI paths.
1192 *
1193 ******************************************************************************/
1194
1195void
1196AcpiDbSetScope (
1197 char *Name)
1198{
1199 ACPI_STATUS Status;
1200 ACPI_NAMESPACE_NODE *Node;
1201
1202
1203 if (!Name || Name[0] == 0)
1204 {
1205 AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1206 return;
1207 }
1208
1209 AcpiDbPrepNamestring (Name);
1210
1211 if (Name[0] == '\\')
1212 {
1213 /* Validate new scope from the root */
1214
1215 Status = AcpiNsGetNodeByPath (Name, AcpiGbl_RootNode,
1216 ACPI_NS_NO_UPSEARCH, &Node);
1217 if (ACPI_FAILURE (Status))
1218 {
1219 goto ErrorExit;
1220 }
1221
1222 ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1223 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1224 }
1225 else
1226 {
1227 /* Validate new scope relative to old scope */
1228
1229 Status = AcpiNsGetNodeByPath (Name, AcpiGbl_DbScopeNode,
1230 ACPI_NS_NO_UPSEARCH, &Node);
1231 if (ACPI_FAILURE (Status))
1232 {
1233 goto ErrorExit;
1234 }
1235
1236 ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1237 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1238 }
1239
1240 AcpiGbl_DbScopeNode = Node;
1241 AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1242 return;
1243
1244ErrorExit:
1245
1246 AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1247 Name, AcpiFormatException (Status));
1248}
1249
1250
1251/*******************************************************************************
1252 *
1253 * FUNCTION: AcpiDmCompareAmlResources
1254 *
1255 * PARAMETERS: Aml1Buffer - Contains first resource list
1256 * Aml1BufferLength - Length of first resource list
1257 * Aml2Buffer - Contains second resource list
1258 * Aml2BufferLength - Length of second resource list
1259 *
1260 * RETURN: None
1261 *
1262 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1263 * order to isolate a miscompare to an individual resource)
1264 *
1265 ******************************************************************************/
1266
1267static void
1268AcpiDmCompareAmlResources (
1269 UINT8 *Aml1Buffer,
1270 ACPI_RSDESC_SIZE Aml1BufferLength,
1271 UINT8 *Aml2Buffer,
1272 ACPI_RSDESC_SIZE Aml2BufferLength)
1273{
1274 UINT8 *Aml1;
1275 UINT8 *Aml2;
1276 ACPI_RSDESC_SIZE Aml1Length;
1277 ACPI_RSDESC_SIZE Aml2Length;
1278 ACPI_RSDESC_SIZE Offset = 0;
1279 UINT8 ResourceType;
1280 UINT32 Count = 0;
1281
1282
1283 /* Compare overall buffer sizes (may be different due to size rounding) */
1284
1285 if (Aml1BufferLength != Aml2BufferLength)
1286 {
1287 AcpiOsPrintf (
1288 "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1289 Aml1BufferLength, Aml2BufferLength);
1290 }
1291
1292 Aml1 = Aml1Buffer;
1293 Aml2 = Aml2Buffer;
1294
1295 /* Walk the descriptor lists, comparing each descriptor */
1296
1297 while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1298 {
1299 /* Get the lengths of each descriptor */
1300
1301 Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1302 Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1303 ResourceType = AcpiUtGetResourceType (Aml1);
1304
1305 /* Check for descriptor length match */
1306
1307 if (Aml1Length != Aml2Length)
1308 {
1309 AcpiOsPrintf (
1310 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1311 Count, ResourceType, Offset, Aml1Length, Aml2Length);
1312 return;
1313 }
1314
1315 /* Check for descriptor byte match */
1316
1317 if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1318 {
1319 AcpiOsPrintf (
1320 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1321 Count, ResourceType, Offset);
1322 }
1323
1324 /* Exit on EndTag descriptor */
1325
1326 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1327 {
1328 return;
1329 }
1330
1331 /* Point to next descriptor in each buffer */
1332
1333 Count++;
1334 Offset += Aml1Length;
1335 Aml1 += Aml1Length;
1336 Aml2 += Aml1Length;
1337 }
1338}
1339
1340
1341/*******************************************************************************
1342 *
1343 * FUNCTION: AcpiDmTestResourceConversion
1344 *
1345 * PARAMETERS: Node - Parent device node
1346 * Name - resource method name (_CRS)
1347 *
1348 * RETURN: Status
1349 *
1350 * DESCRIPTION: Compare the original AML with a conversion of the AML to
1351 * internal resource list, then back to AML.
1352 *
1353 ******************************************************************************/
1354
1355static ACPI_STATUS
1356AcpiDmTestResourceConversion (
1357 ACPI_NAMESPACE_NODE *Node,
1358 char *Name)
1359{
1360 ACPI_STATUS Status;
1361 ACPI_BUFFER ReturnObj;
1362 ACPI_BUFFER ResourceObj;
1363 ACPI_BUFFER NewAml;
1364 ACPI_OBJECT *OriginalAml;
1365
1366
1367 AcpiOsPrintf ("Resource Conversion Comparison:\n");
1368
1369 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1370 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1371 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1372
1373 /* Get the original _CRS AML resource template */
1374
1375 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1376 if (ACPI_FAILURE (Status))
1377 {
1378 AcpiOsPrintf ("Could not obtain %s: %s\n",
1379 Name, AcpiFormatException (Status));
1380 return (Status);
1381 }
1382
1383 /* Get the AML resource template, converted to internal resource structs */
1384
1385 Status = AcpiGetCurrentResources (Node, &ResourceObj);
1386 if (ACPI_FAILURE (Status))
1387 {
1388 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1389 AcpiFormatException (Status));
1390 goto Exit1;
1391 }
1392
1393 /* Convert internal resource list to external AML resource template */
1394
1395 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1396 if (ACPI_FAILURE (Status))
1397 {
1398 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1399 AcpiFormatException (Status));
1400 goto Exit2;
1401 }
1402
1403 /* Compare original AML to the newly created AML resource list */
1404
1405 OriginalAml = ReturnObj.Pointer;
1406
1407 AcpiDmCompareAmlResources (
1408 OriginalAml->Buffer.Pointer, OriginalAml->Buffer.Length,
1409 NewAml.Pointer, NewAml.Length);
1410
1411 /* Cleanup and exit */
1412
1413 ACPI_MEM_FREE (NewAml.Pointer);
1414Exit2:
1415 ACPI_MEM_FREE (ResourceObj.Pointer);
1416Exit1:
1417 ACPI_MEM_FREE (ReturnObj.Pointer);
1418 return (Status);
1419}
1420
1421
1422/*******************************************************************************
1423 *
1424 * FUNCTION: AcpiDbDisplayResources
1425 *
1426 * PARAMETERS: ObjectArg - String with hex value of the object
1427 *
1428 * RETURN: None
1429 *
1430 * DESCRIPTION: Display the resource objects associated with a device.
1431 *
1432 ******************************************************************************/
1433
1434void
1435AcpiDbDisplayResources (
1436 char *ObjectArg)
1437{
1438#if ACPI_MACHINE_WIDTH != 16
1439
1440 ACPI_NAMESPACE_NODE *Node;
1441 ACPI_STATUS Status;
1442 ACPI_BUFFER ReturnObj;
1443
1444
1445 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1446 AcpiDbgLevel |= ACPI_LV_RESOURCES;
1447
1448 /* Convert string to object pointer */
1449
1450 Node = AcpiDbConvertToNode (ObjectArg);
1451 if (!Node)
1452 {
1453 return;
1454 }
1455
1456 /* Prepare for a return object of arbitrary size */
1457
1458 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1459 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1460
1461 /* _PRT */
1462
1463 AcpiOsPrintf ("Evaluating _PRT\n");
1464
1465 /* Check if _PRT exists */
1466
1467 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1468 if (ACPI_FAILURE (Status))
1469 {
1470 AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1471 AcpiFormatException (Status));
1472 goto GetCrs;
1473 }
1474
1475 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1476 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1477
1478 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1479 if (ACPI_FAILURE (Status))
1480 {
1481 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1482 AcpiFormatException (Status));
1483 goto GetCrs;
1484 }
1485
1486 AcpiRsDumpIrqList ((UINT8 *) AcpiGbl_DbBuffer);
1487
1488
1489 /* _CRS */
1490
1491GetCrs:
1492 AcpiOsPrintf ("Evaluating _CRS\n");
1493
1494 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1495 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1496
1497 /* Check if _CRS exists */
1498
1499 Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1500 if (ACPI_FAILURE (Status))
1501 {
1502 AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1503 AcpiFormatException (Status));
1504 goto GetPrs;
1505 }
1506
1507 /* Get the _CRS resource list */
1508
1509 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1510 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1511
1512 Status = AcpiGetCurrentResources (Node, &ReturnObj);
1513 if (ACPI_FAILURE (Status))
1514 {
1515 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1516 AcpiFormatException (Status));
1517 goto GetPrs;
1518 }
1519
1520 /* Dump the _CRS resource list */
1521
1522 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1523 ReturnObj.Pointer));
1524
1525 /*
1526 * Perform comparison of original AML to newly created AML. This tests both
1527 * the AML->Resource conversion and the Resource->Aml conversion.
1528 */
1529 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1530
1531 /* Execute _SRS with the resource list */
1532
1533 Status = AcpiSetCurrentResources (Node, &ReturnObj);
1534 if (ACPI_FAILURE (Status))
1535 {
1536 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1537 AcpiFormatException (Status));
1538 goto GetPrs;
1539 }
1540
1541
1542 /* _PRS */
1543
1544GetPrs:
1545 AcpiOsPrintf ("Evaluating _PRS\n");
1546
1547 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1548 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1549
1550 /* Check if _PRS exists */
1551
1552 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1553 if (ACPI_FAILURE (Status))
1554 {
1555 AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1556 AcpiFormatException (Status));
1557 goto Cleanup;
1558 }
1559
1560 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1561 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1562
1563 Status = AcpiGetPossibleResources (Node, &ReturnObj);
1564 if (ACPI_FAILURE (Status))
1565 {
1566 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1567 AcpiFormatException (Status));
1568 goto Cleanup;
1569 }
1570
1571 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1572
1573Cleanup:
1574
1575 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1576 return;
1577#endif
1578}
1579
1580
1581/*******************************************************************************
1582 *
1583 * FUNCTION: AcpiDbIntegrityWalk
1584 *
1585 * PARAMETERS: Callback from WalkNamespace
1586 *
1587 * RETURN: Status
1588 *
1589 * DESCRIPTION: Examine one NS node for valid values.
1590 *
1591 ******************************************************************************/
1592
1593static ACPI_STATUS
1594AcpiDbIntegrityWalk (
1595 ACPI_HANDLE ObjHandle,
1596 UINT32 NestingLevel,
1597 void *Context,
1598 void **ReturnValue)
1599{
1600 ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context;
1601 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1602 ACPI_OPERAND_OBJECT *Object;
1603
1604
1605 Info->Nodes++;
1606 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1607 {
1608 AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s]\n",
1609 Node, AcpiUtGetDescriptorName (Node));
1610 }
1611
1612 if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1613 {
1614 AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1615 Node, Node->Type);
1616 }
1617
1618 if (!AcpiUtValidAcpiName (Node->Name.Integer))
1619 {
1620 AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1621 }
1622
1623 Object = AcpiNsGetAttachedObject (Node);
1624 if (Object)
1625 {
1626 Info->Objects++;
1627 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1628 {
1629 AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1630 Object, AcpiUtGetDescriptorName (Object));
1631 }
1632 }
1633
1634 return (AE_OK);
1635}
1636
1637
1638/*******************************************************************************
1639 *
1640 * FUNCTION: AcpiDbCheckIntegrity
1641 *
1642 * PARAMETERS: None
1643 *
1644 * RETURN: None
1645 *
1646 * DESCRIPTION: Check entire namespace for data structure integrity
1647 *
1648 ******************************************************************************/
1649
1650void
1651AcpiDbCheckIntegrity (
1652 void)
1653{
1654 ACPI_INTEGRITY_INFO Info = {0,0};
1655
1656 /* Search all nodes in namespace */
1657
1658 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1659 AcpiDbIntegrityWalk, (void *) &Info, NULL);
1660
1661 AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1662 Info.Nodes, Info.Objects);
1663}
1664
1665
1666/*******************************************************************************
1667 *
1668 * FUNCTION: AcpiDbGenerateGpe
1669 *
1670 * PARAMETERS: GpeArg - Raw GPE number, ascii string
1671 * BlockArg - GPE block number, ascii string
1672 * 0 or 1 for FADT GPE blocks
1673 *
1674 * RETURN: None
1675 *
1676 * DESCRIPTION: Generate a GPE
1677 *
1678 ******************************************************************************/
1679
1680void
1681AcpiDbGenerateGpe (
1682 char *GpeArg,
1683 char *BlockArg)
1684{
1685 UINT32 BlockNumber;
1686 UINT32 GpeNumber;
1687 ACPI_GPE_EVENT_INFO *GpeEventInfo;
1688
1689
1690 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0);
1691 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1692
1693
1694 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1695 GpeNumber);
1696 if (!GpeEventInfo)
1697 {
1698 AcpiOsPrintf ("Invalid GPE\n");
1699 return;
1700 }
1701
1702 (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1703}
1704
1705
1706/*******************************************************************************
1707 *
1708 * FUNCTION: AcpiDbBusWalk
1709 *
1710 * PARAMETERS: Callback from WalkNamespace
1711 *
1712 * RETURN: Status
1713 *
1714 * DESCRIPTION: Display info about device objects that have a corresponding
1715 * _PRT method.
1716 *
1717 ******************************************************************************/
1718
1719static ACPI_STATUS
1720AcpiDbBusWalk (
1721 ACPI_HANDLE ObjHandle,
1722 UINT32 NestingLevel,
1723 void *Context,
1724 void **ReturnValue)
1725{
1726 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1727 ACPI_STATUS Status;
1728 ACPI_BUFFER Buffer;
1729 ACPI_INTEGER ADR;
1730 ACPI_DEVICE_ID Id;
1731 ACPI_COMPATIBLE_ID_LIST *Cid;
1732 ACPI_NAMESPACE_NODE *TempNode;
1733
1734
1735 /* Exit if there is no _PRT under this device */
1736
1737 Status = AcpiGetHandle (Node, METHOD_NAME__PRT, &TempNode);
1738 if (ACPI_FAILURE (Status))
1739 {
1740 return (AE_OK);
1741 }
1742
1743 /* Get the full path to this device object */
1744
1745 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1746 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1747 if (ACPI_FAILURE (Status))
1748 {
1749 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1750 return (AE_OK);
1751 }
1752
1753 /* Display the full path */
1754
1755 AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer);
1756 ACPI_MEM_FREE (Buffer.Pointer);
1757
1758 /* _PRT info */
1759
1760 AcpiOsPrintf ("_PRT=%p", TempNode);
1761
1762 /* Get the _ADR value */
1763
1764 Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR);
1765 if (ACPI_FAILURE (Status))
1766 {
1767 AcpiOsPrintf (" No _ADR ");
1768 }
1769 else
1770 {
1771 AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR);
1772 }
1773
1774 /* Get the _HID if present */
1775
1776 Status = AcpiUtExecute_HID (Node, &Id);
1777 if (ACPI_SUCCESS (Status))
1778 {
1779 AcpiOsPrintf (" _HID=%s", Id.Value);
1780 }
1781 else
1782 {
1783 AcpiOsPrintf (" ");
1784 }
1785
1786 /* Get the _UID if present */
1787
1788 Status = AcpiUtExecute_UID (Node, &Id);
1789 if (ACPI_SUCCESS (Status))
1790 {
1791 AcpiOsPrintf (" _UID=%s", Id.Value);
1792 }
1793
1794 /* Get the _CID if present */
1795
1796 Status = AcpiUtExecute_CID (Node, &Cid);
1797 if (ACPI_SUCCESS (Status))
1798 {
1799 AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value);
1800 ACPI_MEM_FREE (Cid);
1801 }
1802
1803 AcpiOsPrintf ("\n");
1804 return (AE_OK);
1805}
1806
1807
1808/*******************************************************************************
1809 *
1810 * FUNCTION: AcpiDbGetBusInfo
1811 *
1812 * PARAMETERS: None
1813 *
1814 * RETURN: None
1815 *
1816 * DESCRIPTION: Display info about system busses.
1817 *
1818 ******************************************************************************/
1819
1820void
1821AcpiDbGetBusInfo (
1822 void)
1823{
1824 /* Search all nodes in namespace */
1825
1826 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1827 AcpiDbBusWalk, NULL, NULL);
1828}
1829
1830#endif /* ACPI_DEBUGGER */
2 *
3 * Module Name: dbcmds - debug commands and output routines
4 * $Revision: 1.132 $
5 *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117
118#include <contrib/dev/acpica/acpi.h>
119#include <contrib/dev/acpica/acdispat.h>
120#include <contrib/dev/acpica/amlcode.h>
121#include <contrib/dev/acpica/acnamesp.h>
122#include <contrib/dev/acpica/acevents.h>
123#include <contrib/dev/acpica/acdebug.h>
124#include <contrib/dev/acpica/acresrc.h>
125#include <contrib/dev/acpica/acdisasm.h>
126
127
128#include <contrib/dev/acpica/acparser.h>
129
130#ifdef ACPI_DEBUGGER
131
132#define _COMPONENT ACPI_CA_DEBUGGER
133 ACPI_MODULE_NAME ("dbcmds")
134
135/* Local prototypes */
136
137static ACPI_STATUS
138AcpiDbIntegrityWalk (
139 ACPI_HANDLE ObjHandle,
140 UINT32 NestingLevel,
141 void *Context,
142 void **ReturnValue);
143
144static ACPI_STATUS
145AcpiDbWalkAndMatchName (
146 ACPI_HANDLE ObjHandle,
147 UINT32 NestingLevel,
148 void *Context,
149 void **ReturnValue);
150
151static ACPI_STATUS
152AcpiDbWalkForReferences (
153 ACPI_HANDLE ObjHandle,
154 UINT32 NestingLevel,
155 void *Context,
156 void **ReturnValue);
157
158static ACPI_STATUS
159AcpiDbWalkForSpecificObjects (
160 ACPI_HANDLE ObjHandle,
161 UINT32 NestingLevel,
162 void *Context,
163 void **ReturnValue);
164
165static ACPI_NAMESPACE_NODE *
166AcpiDbConvertToNode (
167 char *InString);
168
169static void
170AcpiDmCompareAmlResources (
171 UINT8 *Aml1Buffer,
172 ACPI_RSDESC_SIZE Aml1BufferLength,
173 UINT8 *Aml2Buffer,
174 ACPI_RSDESC_SIZE Aml2BufferLength);
175
176static ACPI_STATUS
177AcpiDmTestResourceConversion (
178 ACPI_NAMESPACE_NODE *Node,
179 char *Name);
180
181
182/*
183 * Arguments for the Objects command
184 * These object types map directly to the ACPI_TYPES
185 */
186static ARGUMENT_INFO AcpiDbObjectTypes [] =
187{
188 {"ANY"},
189 {"INTEGERS"},
190 {"STRINGS"},
191 {"BUFFERS"},
192 {"PACKAGES"},
193 {"FIELDS"},
194 {"DEVICES"},
195 {"EVENTS"},
196 {"METHODS"},
197 {"MUTEXES"},
198 {"REGIONS"},
199 {"POWERRESOURCES"},
200 {"PROCESSORS"},
201 {"THERMALZONES"},
202 {"BUFFERFIELDS"},
203 {"DDBHANDLES"},
204 {NULL} /* Must be null terminated */
205};
206
207
208/*******************************************************************************
209 *
210 * FUNCTION: AcpiDbConvertToNode
211 *
212 * PARAMETERS: InString - String to convert
213 *
214 * RETURN: Pointer to a NS node
215 *
216 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
217 * alpha strings.
218 *
219 ******************************************************************************/
220
221static ACPI_NAMESPACE_NODE *
222AcpiDbConvertToNode (
223 char *InString)
224{
225 ACPI_NAMESPACE_NODE *Node;
226
227
228 if ((*InString >= 0x30) && (*InString <= 0x39))
229 {
230 /* Numeric argument, convert */
231
232 Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
233 if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
234 {
235 AcpiOsPrintf ("Address %p is invalid in this address space\n",
236 Node);
237 return (NULL);
238 }
239
240 /* Make sure pointer is valid NS node */
241
242 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
243 {
244 AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
245 Node, AcpiUtGetDescriptorName (Node));
246 return (NULL);
247 }
248 }
249 else
250 {
251 /* Alpha argument */
252 /* The parameter is a name string that must be resolved to a
253 * Named obj
254 */
255 Node = AcpiDbLocalNsLookup (InString);
256 if (!Node)
257 {
258 Node = AcpiGbl_RootNode;
259 }
260 }
261
262 return (Node);
263}
264
265
266/*******************************************************************************
267 *
268 * FUNCTION: AcpiDbSleep
269 *
270 * PARAMETERS: ObjectArg - Desired sleep state (0-5)
271 *
272 * RETURN: Status
273 *
274 * DESCRIPTION: Simulate a sleep/wake sequence
275 *
276 ******************************************************************************/
277
278ACPI_STATUS
279AcpiDbSleep (
280 char *ObjectArg)
281{
282#if ACPI_MACHINE_WIDTH == 16
283 return (AE_OK);
284#else
285 ACPI_STATUS Status;
286 UINT8 SleepState;
287
288
289 SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
290
291 AcpiOsPrintf ("**** Prepare to sleep ****\n");
292 Status = AcpiEnterSleepStatePrep (SleepState);
293 if (ACPI_FAILURE (Status))
294 {
295 return (Status);
296 }
297
298 AcpiOsPrintf ("**** Going to sleep ****\n");
299 Status = AcpiEnterSleepState (SleepState);
300 if (ACPI_FAILURE (Status))
301 {
302 return (Status);
303 }
304
305 AcpiOsPrintf ("**** returning from sleep ****\n");
306 Status = AcpiLeaveSleepState (SleepState);
307
308 return (Status);
309#endif
310}
311
312
313/*******************************************************************************
314 *
315 * FUNCTION: AcpiDbWalkForReferences
316 *
317 * PARAMETERS: Callback from WalkNamespace
318 *
319 * RETURN: Status
320 *
321 * DESCRIPTION: Check if this namespace object refers to the target object
322 * that is passed in as the context value.
323 *
324 * Note: Currently doesn't check subobjects within the Node's object
325 *
326 ******************************************************************************/
327
328static ACPI_STATUS
329AcpiDbWalkForReferences (
330 ACPI_HANDLE ObjHandle,
331 UINT32 NestingLevel,
332 void *Context,
333 void **ReturnValue)
334{
335 ACPI_OPERAND_OBJECT *ObjDesc = (ACPI_OPERAND_OBJECT *) Context;
336 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
337
338
339 /* Check for match against the namespace node itself */
340
341 if (Node == (void *) ObjDesc)
342 {
343 AcpiOsPrintf ("Object is a Node [%4.4s]\n",
344 AcpiUtGetNodeName (Node));
345 }
346
347 /* Check for match against the object attached to the node */
348
349 if (AcpiNsGetAttachedObject (Node) == ObjDesc)
350 {
351 AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
352 Node, AcpiUtGetNodeName (Node));
353 }
354
355 return (AE_OK);
356}
357
358
359/*******************************************************************************
360 *
361 * FUNCTION: AcpiDbFindReferences
362 *
363 * PARAMETERS: ObjectArg - String with hex value of the object
364 *
365 * RETURN: None
366 *
367 * DESCRIPTION: Search namespace for all references to the input object
368 *
369 ******************************************************************************/
370
371void
372AcpiDbFindReferences (
373 char *ObjectArg)
374{
375 ACPI_OPERAND_OBJECT *ObjDesc;
376
377
378 /* Convert string to object pointer */
379
380 ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
381
382 /* Search all nodes in namespace */
383
384 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
385 AcpiDbWalkForReferences, (void *) ObjDesc, NULL);
386}
387
388
389/*******************************************************************************
390 *
391 * FUNCTION: AcpiDbDisplayLocks
392 *
393 * PARAMETERS: None
394 *
395 * RETURN: None
396 *
397 * DESCRIPTION: Display information about internal mutexes.
398 *
399 ******************************************************************************/
400
401void
402AcpiDbDisplayLocks (
403 void)
404{
405 UINT32 i;
406
407
408 for (i = 0; i < MAX_MUTEX; i++)
409 {
410 AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
411 AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
412 ? "Locked" : "Unlocked");
413 }
414}
415
416
417/*******************************************************************************
418 *
419 * FUNCTION: AcpiDbDisplayTableInfo
420 *
421 * PARAMETERS: TableArg - String with name of table to be displayed
422 *
423 * RETURN: None
424 *
425 * DESCRIPTION: Display information about loaded tables. Current
426 * implementation displays all loaded tables.
427 *
428 ******************************************************************************/
429
430void
431AcpiDbDisplayTableInfo (
432 char *TableArg)
433{
434 UINT32 i;
435 ACPI_TABLE_DESC *TableDesc;
436
437
438 for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
439 {
440 TableDesc = AcpiGbl_TableLists[i].Next;
441 while (TableDesc)
442 {
443 AcpiOsPrintf ( "%s at %p length %.5X",
444 AcpiGbl_TableData[i].Name, TableDesc->Pointer,
445 (UINT32) TableDesc->Length);
446
447 if (i != ACPI_TABLE_FACS)
448 {
449 AcpiOsPrintf (" OemID=%6s TableId=%8s OemRevision=%8.8X",
450 TableDesc->Pointer->OemId,
451 TableDesc->Pointer->OemTableId,
452 TableDesc->Pointer->OemRevision);
453 }
454 AcpiOsPrintf ("\n");
455
456 TableDesc = TableDesc->Next;
457 }
458 }
459}
460
461
462/*******************************************************************************
463 *
464 * FUNCTION: AcpiDbUnloadAcpiTable
465 *
466 * PARAMETERS: TableArg - Name of the table to be unloaded
467 * InstanceArg - Which instance of the table to unload (if
468 * there are multiple tables of the same type)
469 *
470 * RETURN: Nonde
471 *
472 * DESCRIPTION: Unload an ACPI table.
473 * Instance is not implemented
474 *
475 ******************************************************************************/
476
477void
478AcpiDbUnloadAcpiTable (
479 char *TableArg,
480 char *InstanceArg)
481{
482 UINT32 i;
483 ACPI_STATUS Status;
484
485
486 /* Search all tables for the target type */
487
488 for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
489 {
490 if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
491 AcpiGbl_TableData[i].SigLength))
492 {
493 /* Found the table, unload it */
494
495 Status = AcpiUnloadTable (i);
496 if (ACPI_SUCCESS (Status))
497 {
498 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
499 }
500 else
501 {
502 AcpiOsPrintf ("%s, while unloading [%s]\n",
503 AcpiFormatException (Status), TableArg);
504 }
505
506 return;
507 }
508 }
509
510 AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
511}
512
513
514/*******************************************************************************
515 *
516 * FUNCTION: AcpiDbSetMethodBreakpoint
517 *
518 * PARAMETERS: Location - AML offset of breakpoint
519 * WalkState - Current walk info
520 * Op - Current Op (from parse walk)
521 *
522 * RETURN: None
523 *
524 * DESCRIPTION: Set a breakpoint in a control method at the specified
525 * AML offset
526 *
527 ******************************************************************************/
528
529void
530AcpiDbSetMethodBreakpoint (
531 char *Location,
532 ACPI_WALK_STATE *WalkState,
533 ACPI_PARSE_OBJECT *Op)
534{
535 UINT32 Address;
536
537
538 if (!Op)
539 {
540 AcpiOsPrintf ("There is no method currently executing\n");
541 return;
542 }
543
544 /* Get and verify the breakpoint address */
545
546 Address = ACPI_STRTOUL (Location, NULL, 16);
547 if (Address <= Op->Common.AmlOffset)
548 {
549 AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
550 Address, Op->Common.AmlOffset);
551 }
552
553 /* Save breakpoint in current walk */
554
555 WalkState->UserBreakpoint = Address;
556 AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
557}
558
559
560/*******************************************************************************
561 *
562 * FUNCTION: AcpiDbSetMethodCallBreakpoint
563 *
564 * PARAMETERS: Op - Current Op (from parse walk)
565 *
566 * RETURN: None
567 *
568 * DESCRIPTION: Set a breakpoint in a control method at the specified
569 * AML offset
570 *
571 ******************************************************************************/
572
573void
574AcpiDbSetMethodCallBreakpoint (
575 ACPI_PARSE_OBJECT *Op)
576{
577
578
579 if (!Op)
580 {
581 AcpiOsPrintf ("There is no method currently executing\n");
582 return;
583 }
584
585 AcpiGbl_StepToNextCall = TRUE;
586}
587
588
589/*******************************************************************************
590 *
591 * FUNCTION: AcpiDbDisassembleAml
592 *
593 * PARAMETERS: Statements - Number of statements to disassemble
594 * Op - Current Op (from parse walk)
595 *
596 * RETURN: None
597 *
598 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
599 * of statements specified.
600 *
601 ******************************************************************************/
602
603void
604AcpiDbDisassembleAml (
605 char *Statements,
606 ACPI_PARSE_OBJECT *Op)
607{
608 UINT32 NumStatements = 8;
609
610
611 if (!Op)
612 {
613 AcpiOsPrintf ("There is no method currently executing\n");
614 return;
615 }
616
617 if (Statements)
618 {
619 NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
620 }
621
622 AcpiDmDisassemble (NULL, Op, NumStatements);
623}
624
625
626/*******************************************************************************
627 *
628 * FUNCTION: AcpiDbDisassembleMethod
629 *
630 * PARAMETERS: Name - Name of control method
631 *
632 * RETURN: None
633 *
634 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
635 * of statements specified.
636 *
637 ******************************************************************************/
638
639ACPI_STATUS
640AcpiDbDisassembleMethod (
641 char *Name)
642{
643 ACPI_STATUS Status;
644 ACPI_PARSE_OBJECT *Op;
645 ACPI_WALK_STATE *WalkState;
646 ACPI_OPERAND_OBJECT *ObjDesc;
647 ACPI_NAMESPACE_NODE *Method;
648
649
650 Method = AcpiDbConvertToNode (Name);
651 if (!Method)
652 {
653 return (AE_BAD_PARAMETER);
654 }
655
656 ObjDesc = Method->Object;
657
658 Op = AcpiPsCreateScopeOp ();
659 if (!Op)
660 {
661 return (AE_NO_MEMORY);
662 }
663
664 /* Create and initialize a new walk state */
665
666 WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
667 if (!WalkState)
668 {
669 return (AE_NO_MEMORY);
670 }
671
672 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
673 ObjDesc->Method.AmlStart,
674 ObjDesc->Method.AmlLength, NULL, 1);
675 if (ACPI_FAILURE (Status))
676 {
677 return (Status);
678 }
679
680 /* Parse the AML */
681
682 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
683 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
684 Status = AcpiPsParseAml (WalkState);
685
686 AcpiDmDisassemble (NULL, Op, 0);
687 AcpiPsDeleteParseTree (Op);
688 return (AE_OK);
689}
690
691
692/*******************************************************************************
693 *
694 * FUNCTION: AcpiDbDumpNamespace
695 *
696 * PARAMETERS: StartArg - Node to begin namespace dump
697 * DepthArg - Maximum tree depth to be dumped
698 *
699 * RETURN: None
700 *
701 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
702 * with type and other information.
703 *
704 ******************************************************************************/
705
706void
707AcpiDbDumpNamespace (
708 char *StartArg,
709 char *DepthArg)
710{
711 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode;
712 UINT32 MaxDepth = ACPI_UINT32_MAX;
713
714
715 /* No argument given, just start at the root and dump entire namespace */
716
717 if (StartArg)
718 {
719 SubtreeEntry = AcpiDbConvertToNode (StartArg);
720 if (!SubtreeEntry)
721 {
722 return;
723 }
724
725 /* Now we can check for the depth argument */
726
727 if (DepthArg)
728 {
729 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
730 }
731 }
732
733 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
734 AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
735 ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
736
737 /* Display the subtree */
738
739 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
740 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
741 ACPI_OWNER_ID_MAX, SubtreeEntry);
742 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
743}
744
745
746/*******************************************************************************
747 *
748 * FUNCTION: AcpiDbDumpNamespaceByOwner
749 *
750 * PARAMETERS: OwnerArg - Owner ID whose nodes will be displayed
751 * DepthArg - Maximum tree depth to be dumped
752 *
753 * RETURN: None
754 *
755 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
756 *
757 ******************************************************************************/
758
759void
760AcpiDbDumpNamespaceByOwner (
761 char *OwnerArg,
762 char *DepthArg)
763{
764 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode;
765 UINT32 MaxDepth = ACPI_UINT32_MAX;
766 ACPI_OWNER_ID OwnerId;
767
768
769 OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
770
771 /* Now we can check for the depth argument */
772
773 if (DepthArg)
774 {
775 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
776 }
777
778 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
779 AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
780
781 /* Display the subtree */
782
783 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
784 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
785 SubtreeEntry);
786 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
787}
788
789
790/*******************************************************************************
791 *
792 * FUNCTION: AcpiDbSendNotify
793 *
794 * PARAMETERS: Name - Name of ACPI object to send the notify to
795 * Value - Value of the notify to send.
796 *
797 * RETURN: None
798 *
799 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
800 * named object as an ACPI notify.
801 *
802 ******************************************************************************/
803
804void
805AcpiDbSendNotify (
806 char *Name,
807 UINT32 Value)
808{
809 ACPI_NAMESPACE_NODE *Node;
810 ACPI_STATUS Status;
811
812
813 /* Translate name to an Named object */
814
815 Node = AcpiDbConvertToNode (Name);
816 if (!Node)
817 {
818 return;
819 }
820
821 /* Decode Named object type */
822
823 switch (Node->Type)
824 {
825 case ACPI_TYPE_DEVICE:
826 case ACPI_TYPE_THERMAL:
827
828 /* Send the notify */
829
830 Status = AcpiEvQueueNotifyRequest (Node, Value);
831 if (ACPI_FAILURE (Status))
832 {
833 AcpiOsPrintf ("Could not queue notify\n");
834 }
835 break;
836
837 default:
838 AcpiOsPrintf ("Named object is not a device or a thermal object\n");
839 break;
840 }
841}
842
843
844/*******************************************************************************
845 *
846 * FUNCTION: AcpiDbSetMethodData
847 *
848 * PARAMETERS: TypeArg - L for local, A for argument
849 * IndexArg - which one
850 * ValueArg - Value to set.
851 *
852 * RETURN: None
853 *
854 * DESCRIPTION: Set a local or argument for the running control method.
855 * NOTE: only object supported is Number.
856 *
857 ******************************************************************************/
858
859void
860AcpiDbSetMethodData (
861 char *TypeArg,
862 char *IndexArg,
863 char *ValueArg)
864{
865 char Type;
866 UINT32 Index;
867 UINT32 Value;
868 ACPI_WALK_STATE *WalkState;
869 ACPI_OPERAND_OBJECT *ObjDesc;
870 ACPI_STATUS Status;
871 ACPI_NAMESPACE_NODE *Node;
872
873
874 /* Validate TypeArg */
875
876 AcpiUtStrupr (TypeArg);
877 Type = TypeArg[0];
878 if ((Type != 'L') &&
879 (Type != 'A') &&
880 (Type != 'N'))
881 {
882 AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
883 return;
884 }
885
886 Value = ACPI_STRTOUL (ValueArg, NULL, 16);
887
888 if (Type == 'N')
889 {
890 Node = AcpiDbConvertToNode (IndexArg);
891 if (Node->Type != ACPI_TYPE_INTEGER)
892 {
893 AcpiOsPrintf ("Can only set Integer nodes\n");
894 return;
895 }
896 ObjDesc = Node->Object;
897 ObjDesc->Integer.Value = Value;
898 return;
899 }
900
901 /* Get the index and value */
902
903 Index = ACPI_STRTOUL (IndexArg, NULL, 16);
904
905 WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
906 if (!WalkState)
907 {
908 AcpiOsPrintf ("There is no method currently executing\n");
909 return;
910 }
911
912 /* Create and initialize the new object */
913
914 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
915 if (!ObjDesc)
916 {
917 AcpiOsPrintf ("Could not create an internal object\n");
918 return;
919 }
920
921 ObjDesc->Integer.Value = Value;
922
923 /* Store the new object into the target */
924
925 switch (Type)
926 {
927 case 'A':
928
929 /* Set a method argument */
930
931 if (Index > ACPI_METHOD_MAX_ARG)
932 {
933 AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
934 return;
935 }
936
937 Status = AcpiDsStoreObjectToLocal (AML_ARG_OP, Index, ObjDesc,
938 WalkState);
939 if (ACPI_FAILURE (Status))
940 {
941 return;
942 }
943
944 ObjDesc = WalkState->Arguments[Index].Object;
945
946 AcpiOsPrintf ("Arg%d: ", Index);
947 AcpiDmDisplayInternalObject (ObjDesc, WalkState);
948 break;
949
950 case 'L':
951
952 /* Set a method local */
953
954 if (Index > ACPI_METHOD_MAX_LOCAL)
955 {
956 AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
957 return;
958 }
959
960 Status = AcpiDsStoreObjectToLocal (AML_LOCAL_OP, Index, ObjDesc,
961 WalkState);
962 if (ACPI_FAILURE (Status))
963 {
964 return;
965 }
966
967 ObjDesc = WalkState->LocalVariables[Index].Object;
968
969 AcpiOsPrintf ("Local%d: ", Index);
970 AcpiDmDisplayInternalObject (ObjDesc, WalkState);
971 break;
972
973 default:
974 break;
975 }
976}
977
978
979/*******************************************************************************
980 *
981 * FUNCTION: AcpiDbWalkForSpecificObjects
982 *
983 * PARAMETERS: Callback from WalkNamespace
984 *
985 * RETURN: Status
986 *
987 * DESCRIPTION: Display short info about objects in the namespace
988 *
989 ******************************************************************************/
990
991static ACPI_STATUS
992AcpiDbWalkForSpecificObjects (
993 ACPI_HANDLE ObjHandle,
994 UINT32 NestingLevel,
995 void *Context,
996 void **ReturnValue)
997{
998 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context;
999 ACPI_BUFFER Buffer;
1000 ACPI_STATUS Status;
1001
1002
1003 Info->Count++;
1004
1005 /* Get and display the full pathname to this object */
1006
1007 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1008 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1009 if (ACPI_FAILURE (Status))
1010 {
1011 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1012 return (AE_OK);
1013 }
1014
1015 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1016 ACPI_MEM_FREE (Buffer.Pointer);
1017
1018 /* Dump short info about the object */
1019
1020 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1021 return (AE_OK);
1022}
1023
1024
1025/*******************************************************************************
1026 *
1027 * FUNCTION: AcpiDbDisplayObjects
1028 *
1029 * PARAMETERS: ObjTypeArg - Type of object to display
1030 * DisplayCountArg - Max depth to display
1031 *
1032 * RETURN: None
1033 *
1034 * DESCRIPTION: Display objects in the namespace of the requested type
1035 *
1036 ******************************************************************************/
1037
1038ACPI_STATUS
1039AcpiDbDisplayObjects (
1040 char *ObjTypeArg,
1041 char *DisplayCountArg)
1042{
1043 ACPI_WALK_INFO Info;
1044 ACPI_OBJECT_TYPE Type;
1045
1046
1047 /* Get the object type */
1048
1049 Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1050 if (Type == ACPI_TYPE_NOT_FOUND)
1051 {
1052 AcpiOsPrintf ("Invalid or unsupported argument\n");
1053 return (AE_OK);
1054 }
1055
1056 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1057 AcpiOsPrintf (
1058 "Objects of type [%s] defined in the current ACPI Namespace:\n",
1059 AcpiUtGetTypeName (Type));
1060
1061 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1062
1063 Info.Count = 0;
1064 Info.OwnerId = ACPI_OWNER_ID_MAX;
1065 Info.DebugLevel = ACPI_UINT32_MAX;
1066 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1067
1068 /* Walk the namespace from the root */
1069
1070 (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1071 AcpiDbWalkForSpecificObjects, (void *) &Info, NULL);
1072
1073 AcpiOsPrintf (
1074 "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1075 Info.Count, AcpiUtGetTypeName (Type));
1076
1077 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1078 return (AE_OK);
1079}
1080
1081
1082/*******************************************************************************
1083 *
1084 * FUNCTION: AcpiDbWalkAndMatchName
1085 *
1086 * PARAMETERS: Callback from WalkNamespace
1087 *
1088 * RETURN: Status
1089 *
1090 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
1091 * are supported -- '?' matches any character.
1092 *
1093 ******************************************************************************/
1094
1095static ACPI_STATUS
1096AcpiDbWalkAndMatchName (
1097 ACPI_HANDLE ObjHandle,
1098 UINT32 NestingLevel,
1099 void *Context,
1100 void **ReturnValue)
1101{
1102 ACPI_STATUS Status;
1103 char *RequestedName = (char *) Context;
1104 UINT32 i;
1105 ACPI_BUFFER Buffer;
1106 ACPI_WALK_INFO Info;
1107
1108
1109 /* Check for a name match */
1110
1111 for (i = 0; i < 4; i++)
1112 {
1113 /* Wildcard support */
1114
1115 if ((RequestedName[i] != '?') &&
1116 (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1117 {
1118 /* No match, just exit */
1119
1120 return (AE_OK);
1121 }
1122 }
1123
1124 /* Get the full pathname to this object */
1125
1126 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1127 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1128 if (ACPI_FAILURE (Status))
1129 {
1130 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1131 }
1132 else
1133 {
1134 Info.OwnerId = ACPI_OWNER_ID_MAX;
1135 Info.DebugLevel = ACPI_UINT32_MAX;
1136 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1137
1138 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1139 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1140 ACPI_MEM_FREE (Buffer.Pointer);
1141 }
1142
1143 return (AE_OK);
1144}
1145
1146
1147/*******************************************************************************
1148 *
1149 * FUNCTION: AcpiDbFindNameInNamespace
1150 *
1151 * PARAMETERS: NameArg - The 4-character ACPI name to find.
1152 * wildcards are supported.
1153 *
1154 * RETURN: None
1155 *
1156 * DESCRIPTION: Search the namespace for a given name (with wildcards)
1157 *
1158 ******************************************************************************/
1159
1160ACPI_STATUS
1161AcpiDbFindNameInNamespace (
1162 char *NameArg)
1163{
1164
1165 if (ACPI_STRLEN (NameArg) > 4)
1166 {
1167 AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1168 return (AE_OK);
1169 }
1170
1171 /* Walk the namespace from the root */
1172
1173 AcpiUtStrupr (NameArg);
1174 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1175 AcpiDbWalkAndMatchName, NameArg, NULL);
1176
1177 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1178 return (AE_OK);
1179}
1180
1181
1182/*******************************************************************************
1183 *
1184 * FUNCTION: AcpiDbSetScope
1185 *
1186 * PARAMETERS: Name - New scope path
1187 *
1188 * RETURN: Status
1189 *
1190 * DESCRIPTION: Set the "current scope" as maintained by this utility.
1191 * The scope is used as a prefix to ACPI paths.
1192 *
1193 ******************************************************************************/
1194
1195void
1196AcpiDbSetScope (
1197 char *Name)
1198{
1199 ACPI_STATUS Status;
1200 ACPI_NAMESPACE_NODE *Node;
1201
1202
1203 if (!Name || Name[0] == 0)
1204 {
1205 AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1206 return;
1207 }
1208
1209 AcpiDbPrepNamestring (Name);
1210
1211 if (Name[0] == '\\')
1212 {
1213 /* Validate new scope from the root */
1214
1215 Status = AcpiNsGetNodeByPath (Name, AcpiGbl_RootNode,
1216 ACPI_NS_NO_UPSEARCH, &Node);
1217 if (ACPI_FAILURE (Status))
1218 {
1219 goto ErrorExit;
1220 }
1221
1222 ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1223 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1224 }
1225 else
1226 {
1227 /* Validate new scope relative to old scope */
1228
1229 Status = AcpiNsGetNodeByPath (Name, AcpiGbl_DbScopeNode,
1230 ACPI_NS_NO_UPSEARCH, &Node);
1231 if (ACPI_FAILURE (Status))
1232 {
1233 goto ErrorExit;
1234 }
1235
1236 ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1237 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1238 }
1239
1240 AcpiGbl_DbScopeNode = Node;
1241 AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1242 return;
1243
1244ErrorExit:
1245
1246 AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1247 Name, AcpiFormatException (Status));
1248}
1249
1250
1251/*******************************************************************************
1252 *
1253 * FUNCTION: AcpiDmCompareAmlResources
1254 *
1255 * PARAMETERS: Aml1Buffer - Contains first resource list
1256 * Aml1BufferLength - Length of first resource list
1257 * Aml2Buffer - Contains second resource list
1258 * Aml2BufferLength - Length of second resource list
1259 *
1260 * RETURN: None
1261 *
1262 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1263 * order to isolate a miscompare to an individual resource)
1264 *
1265 ******************************************************************************/
1266
1267static void
1268AcpiDmCompareAmlResources (
1269 UINT8 *Aml1Buffer,
1270 ACPI_RSDESC_SIZE Aml1BufferLength,
1271 UINT8 *Aml2Buffer,
1272 ACPI_RSDESC_SIZE Aml2BufferLength)
1273{
1274 UINT8 *Aml1;
1275 UINT8 *Aml2;
1276 ACPI_RSDESC_SIZE Aml1Length;
1277 ACPI_RSDESC_SIZE Aml2Length;
1278 ACPI_RSDESC_SIZE Offset = 0;
1279 UINT8 ResourceType;
1280 UINT32 Count = 0;
1281
1282
1283 /* Compare overall buffer sizes (may be different due to size rounding) */
1284
1285 if (Aml1BufferLength != Aml2BufferLength)
1286 {
1287 AcpiOsPrintf (
1288 "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1289 Aml1BufferLength, Aml2BufferLength);
1290 }
1291
1292 Aml1 = Aml1Buffer;
1293 Aml2 = Aml2Buffer;
1294
1295 /* Walk the descriptor lists, comparing each descriptor */
1296
1297 while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1298 {
1299 /* Get the lengths of each descriptor */
1300
1301 Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1302 Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1303 ResourceType = AcpiUtGetResourceType (Aml1);
1304
1305 /* Check for descriptor length match */
1306
1307 if (Aml1Length != Aml2Length)
1308 {
1309 AcpiOsPrintf (
1310 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1311 Count, ResourceType, Offset, Aml1Length, Aml2Length);
1312 return;
1313 }
1314
1315 /* Check for descriptor byte match */
1316
1317 if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1318 {
1319 AcpiOsPrintf (
1320 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1321 Count, ResourceType, Offset);
1322 }
1323
1324 /* Exit on EndTag descriptor */
1325
1326 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1327 {
1328 return;
1329 }
1330
1331 /* Point to next descriptor in each buffer */
1332
1333 Count++;
1334 Offset += Aml1Length;
1335 Aml1 += Aml1Length;
1336 Aml2 += Aml1Length;
1337 }
1338}
1339
1340
1341/*******************************************************************************
1342 *
1343 * FUNCTION: AcpiDmTestResourceConversion
1344 *
1345 * PARAMETERS: Node - Parent device node
1346 * Name - resource method name (_CRS)
1347 *
1348 * RETURN: Status
1349 *
1350 * DESCRIPTION: Compare the original AML with a conversion of the AML to
1351 * internal resource list, then back to AML.
1352 *
1353 ******************************************************************************/
1354
1355static ACPI_STATUS
1356AcpiDmTestResourceConversion (
1357 ACPI_NAMESPACE_NODE *Node,
1358 char *Name)
1359{
1360 ACPI_STATUS Status;
1361 ACPI_BUFFER ReturnObj;
1362 ACPI_BUFFER ResourceObj;
1363 ACPI_BUFFER NewAml;
1364 ACPI_OBJECT *OriginalAml;
1365
1366
1367 AcpiOsPrintf ("Resource Conversion Comparison:\n");
1368
1369 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1370 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1371 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1372
1373 /* Get the original _CRS AML resource template */
1374
1375 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1376 if (ACPI_FAILURE (Status))
1377 {
1378 AcpiOsPrintf ("Could not obtain %s: %s\n",
1379 Name, AcpiFormatException (Status));
1380 return (Status);
1381 }
1382
1383 /* Get the AML resource template, converted to internal resource structs */
1384
1385 Status = AcpiGetCurrentResources (Node, &ResourceObj);
1386 if (ACPI_FAILURE (Status))
1387 {
1388 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1389 AcpiFormatException (Status));
1390 goto Exit1;
1391 }
1392
1393 /* Convert internal resource list to external AML resource template */
1394
1395 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1396 if (ACPI_FAILURE (Status))
1397 {
1398 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1399 AcpiFormatException (Status));
1400 goto Exit2;
1401 }
1402
1403 /* Compare original AML to the newly created AML resource list */
1404
1405 OriginalAml = ReturnObj.Pointer;
1406
1407 AcpiDmCompareAmlResources (
1408 OriginalAml->Buffer.Pointer, OriginalAml->Buffer.Length,
1409 NewAml.Pointer, NewAml.Length);
1410
1411 /* Cleanup and exit */
1412
1413 ACPI_MEM_FREE (NewAml.Pointer);
1414Exit2:
1415 ACPI_MEM_FREE (ResourceObj.Pointer);
1416Exit1:
1417 ACPI_MEM_FREE (ReturnObj.Pointer);
1418 return (Status);
1419}
1420
1421
1422/*******************************************************************************
1423 *
1424 * FUNCTION: AcpiDbDisplayResources
1425 *
1426 * PARAMETERS: ObjectArg - String with hex value of the object
1427 *
1428 * RETURN: None
1429 *
1430 * DESCRIPTION: Display the resource objects associated with a device.
1431 *
1432 ******************************************************************************/
1433
1434void
1435AcpiDbDisplayResources (
1436 char *ObjectArg)
1437{
1438#if ACPI_MACHINE_WIDTH != 16
1439
1440 ACPI_NAMESPACE_NODE *Node;
1441 ACPI_STATUS Status;
1442 ACPI_BUFFER ReturnObj;
1443
1444
1445 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1446 AcpiDbgLevel |= ACPI_LV_RESOURCES;
1447
1448 /* Convert string to object pointer */
1449
1450 Node = AcpiDbConvertToNode (ObjectArg);
1451 if (!Node)
1452 {
1453 return;
1454 }
1455
1456 /* Prepare for a return object of arbitrary size */
1457
1458 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1459 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1460
1461 /* _PRT */
1462
1463 AcpiOsPrintf ("Evaluating _PRT\n");
1464
1465 /* Check if _PRT exists */
1466
1467 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1468 if (ACPI_FAILURE (Status))
1469 {
1470 AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1471 AcpiFormatException (Status));
1472 goto GetCrs;
1473 }
1474
1475 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1476 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1477
1478 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1479 if (ACPI_FAILURE (Status))
1480 {
1481 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1482 AcpiFormatException (Status));
1483 goto GetCrs;
1484 }
1485
1486 AcpiRsDumpIrqList ((UINT8 *) AcpiGbl_DbBuffer);
1487
1488
1489 /* _CRS */
1490
1491GetCrs:
1492 AcpiOsPrintf ("Evaluating _CRS\n");
1493
1494 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1495 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1496
1497 /* Check if _CRS exists */
1498
1499 Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1500 if (ACPI_FAILURE (Status))
1501 {
1502 AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1503 AcpiFormatException (Status));
1504 goto GetPrs;
1505 }
1506
1507 /* Get the _CRS resource list */
1508
1509 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1510 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1511
1512 Status = AcpiGetCurrentResources (Node, &ReturnObj);
1513 if (ACPI_FAILURE (Status))
1514 {
1515 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1516 AcpiFormatException (Status));
1517 goto GetPrs;
1518 }
1519
1520 /* Dump the _CRS resource list */
1521
1522 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1523 ReturnObj.Pointer));
1524
1525 /*
1526 * Perform comparison of original AML to newly created AML. This tests both
1527 * the AML->Resource conversion and the Resource->Aml conversion.
1528 */
1529 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1530
1531 /* Execute _SRS with the resource list */
1532
1533 Status = AcpiSetCurrentResources (Node, &ReturnObj);
1534 if (ACPI_FAILURE (Status))
1535 {
1536 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1537 AcpiFormatException (Status));
1538 goto GetPrs;
1539 }
1540
1541
1542 /* _PRS */
1543
1544GetPrs:
1545 AcpiOsPrintf ("Evaluating _PRS\n");
1546
1547 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1548 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1549
1550 /* Check if _PRS exists */
1551
1552 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1553 if (ACPI_FAILURE (Status))
1554 {
1555 AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1556 AcpiFormatException (Status));
1557 goto Cleanup;
1558 }
1559
1560 ReturnObj.Pointer = AcpiGbl_DbBuffer;
1561 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
1562
1563 Status = AcpiGetPossibleResources (Node, &ReturnObj);
1564 if (ACPI_FAILURE (Status))
1565 {
1566 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1567 AcpiFormatException (Status));
1568 goto Cleanup;
1569 }
1570
1571 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1572
1573Cleanup:
1574
1575 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1576 return;
1577#endif
1578}
1579
1580
1581/*******************************************************************************
1582 *
1583 * FUNCTION: AcpiDbIntegrityWalk
1584 *
1585 * PARAMETERS: Callback from WalkNamespace
1586 *
1587 * RETURN: Status
1588 *
1589 * DESCRIPTION: Examine one NS node for valid values.
1590 *
1591 ******************************************************************************/
1592
1593static ACPI_STATUS
1594AcpiDbIntegrityWalk (
1595 ACPI_HANDLE ObjHandle,
1596 UINT32 NestingLevel,
1597 void *Context,
1598 void **ReturnValue)
1599{
1600 ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context;
1601 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1602 ACPI_OPERAND_OBJECT *Object;
1603
1604
1605 Info->Nodes++;
1606 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1607 {
1608 AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s]\n",
1609 Node, AcpiUtGetDescriptorName (Node));
1610 }
1611
1612 if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1613 {
1614 AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1615 Node, Node->Type);
1616 }
1617
1618 if (!AcpiUtValidAcpiName (Node->Name.Integer))
1619 {
1620 AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1621 }
1622
1623 Object = AcpiNsGetAttachedObject (Node);
1624 if (Object)
1625 {
1626 Info->Objects++;
1627 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1628 {
1629 AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1630 Object, AcpiUtGetDescriptorName (Object));
1631 }
1632 }
1633
1634 return (AE_OK);
1635}
1636
1637
1638/*******************************************************************************
1639 *
1640 * FUNCTION: AcpiDbCheckIntegrity
1641 *
1642 * PARAMETERS: None
1643 *
1644 * RETURN: None
1645 *
1646 * DESCRIPTION: Check entire namespace for data structure integrity
1647 *
1648 ******************************************************************************/
1649
1650void
1651AcpiDbCheckIntegrity (
1652 void)
1653{
1654 ACPI_INTEGRITY_INFO Info = {0,0};
1655
1656 /* Search all nodes in namespace */
1657
1658 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1659 AcpiDbIntegrityWalk, (void *) &Info, NULL);
1660
1661 AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1662 Info.Nodes, Info.Objects);
1663}
1664
1665
1666/*******************************************************************************
1667 *
1668 * FUNCTION: AcpiDbGenerateGpe
1669 *
1670 * PARAMETERS: GpeArg - Raw GPE number, ascii string
1671 * BlockArg - GPE block number, ascii string
1672 * 0 or 1 for FADT GPE blocks
1673 *
1674 * RETURN: None
1675 *
1676 * DESCRIPTION: Generate a GPE
1677 *
1678 ******************************************************************************/
1679
1680void
1681AcpiDbGenerateGpe (
1682 char *GpeArg,
1683 char *BlockArg)
1684{
1685 UINT32 BlockNumber;
1686 UINT32 GpeNumber;
1687 ACPI_GPE_EVENT_INFO *GpeEventInfo;
1688
1689
1690 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0);
1691 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1692
1693
1694 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1695 GpeNumber);
1696 if (!GpeEventInfo)
1697 {
1698 AcpiOsPrintf ("Invalid GPE\n");
1699 return;
1700 }
1701
1702 (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1703}
1704
1705
1706/*******************************************************************************
1707 *
1708 * FUNCTION: AcpiDbBusWalk
1709 *
1710 * PARAMETERS: Callback from WalkNamespace
1711 *
1712 * RETURN: Status
1713 *
1714 * DESCRIPTION: Display info about device objects that have a corresponding
1715 * _PRT method.
1716 *
1717 ******************************************************************************/
1718
1719static ACPI_STATUS
1720AcpiDbBusWalk (
1721 ACPI_HANDLE ObjHandle,
1722 UINT32 NestingLevel,
1723 void *Context,
1724 void **ReturnValue)
1725{
1726 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1727 ACPI_STATUS Status;
1728 ACPI_BUFFER Buffer;
1729 ACPI_INTEGER ADR;
1730 ACPI_DEVICE_ID Id;
1731 ACPI_COMPATIBLE_ID_LIST *Cid;
1732 ACPI_NAMESPACE_NODE *TempNode;
1733
1734
1735 /* Exit if there is no _PRT under this device */
1736
1737 Status = AcpiGetHandle (Node, METHOD_NAME__PRT, &TempNode);
1738 if (ACPI_FAILURE (Status))
1739 {
1740 return (AE_OK);
1741 }
1742
1743 /* Get the full path to this device object */
1744
1745 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1746 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1747 if (ACPI_FAILURE (Status))
1748 {
1749 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1750 return (AE_OK);
1751 }
1752
1753 /* Display the full path */
1754
1755 AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer);
1756 ACPI_MEM_FREE (Buffer.Pointer);
1757
1758 /* _PRT info */
1759
1760 AcpiOsPrintf ("_PRT=%p", TempNode);
1761
1762 /* Get the _ADR value */
1763
1764 Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR);
1765 if (ACPI_FAILURE (Status))
1766 {
1767 AcpiOsPrintf (" No _ADR ");
1768 }
1769 else
1770 {
1771 AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR);
1772 }
1773
1774 /* Get the _HID if present */
1775
1776 Status = AcpiUtExecute_HID (Node, &Id);
1777 if (ACPI_SUCCESS (Status))
1778 {
1779 AcpiOsPrintf (" _HID=%s", Id.Value);
1780 }
1781 else
1782 {
1783 AcpiOsPrintf (" ");
1784 }
1785
1786 /* Get the _UID if present */
1787
1788 Status = AcpiUtExecute_UID (Node, &Id);
1789 if (ACPI_SUCCESS (Status))
1790 {
1791 AcpiOsPrintf (" _UID=%s", Id.Value);
1792 }
1793
1794 /* Get the _CID if present */
1795
1796 Status = AcpiUtExecute_CID (Node, &Cid);
1797 if (ACPI_SUCCESS (Status))
1798 {
1799 AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value);
1800 ACPI_MEM_FREE (Cid);
1801 }
1802
1803 AcpiOsPrintf ("\n");
1804 return (AE_OK);
1805}
1806
1807
1808/*******************************************************************************
1809 *
1810 * FUNCTION: AcpiDbGetBusInfo
1811 *
1812 * PARAMETERS: None
1813 *
1814 * RETURN: None
1815 *
1816 * DESCRIPTION: Display info about system busses.
1817 *
1818 ******************************************************************************/
1819
1820void
1821AcpiDbGetBusInfo (
1822 void)
1823{
1824 /* Search all nodes in namespace */
1825
1826 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1827 AcpiDbBusWalk, NULL, NULL);
1828}
1829
1830#endif /* ACPI_DEBUGGER */