xref: /freebsd/sys/contrib/dev/acpica/components/debugger/dbcmds.c (revision d2ce15bd43b3a1dcce08eecbff8d5d359946d972)
1 /*******************************************************************************
2  *
3  * Module Name: dbcmds - Miscellaneous debug commands and output routines
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2013, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 
45 #include <contrib/dev/acpica/include/acpi.h>
46 #include <contrib/dev/acpica/include/accommon.h>
47 #include <contrib/dev/acpica/include/acevents.h>
48 #include <contrib/dev/acpica/include/acdebug.h>
49 #include <contrib/dev/acpica/include/acnamesp.h>
50 #include <contrib/dev/acpica/include/acresrc.h>
51 #include <contrib/dev/acpica/include/actables.h>
52 
53 #ifdef ACPI_DEBUGGER
54 
55 #define _COMPONENT          ACPI_CA_DEBUGGER
56         ACPI_MODULE_NAME    ("dbcmds")
57 
58 
59 /* Local prototypes */
60 
61 static void
62 AcpiDmCompareAmlResources (
63     UINT8                   *Aml1Buffer,
64     ACPI_RSDESC_SIZE        Aml1BufferLength,
65     UINT8                   *Aml2Buffer,
66     ACPI_RSDESC_SIZE        Aml2BufferLength);
67 
68 static ACPI_STATUS
69 AcpiDmTestResourceConversion (
70     ACPI_NAMESPACE_NODE     *Node,
71     char                    *Name);
72 
73 static ACPI_STATUS
74 AcpiDbResourceCallback (
75     ACPI_RESOURCE           *Resource,
76     void                    *Context);
77 
78 static ACPI_STATUS
79 AcpiDbDeviceResources (
80     ACPI_HANDLE             ObjHandle,
81     UINT32                  NestingLevel,
82     void                    *Context,
83     void                    **ReturnValue);
84 
85 static void
86 AcpiDbDoOneSleepState (
87     UINT8                   SleepState);
88 
89 
90 /*******************************************************************************
91  *
92  * FUNCTION:    AcpiDbConvertToNode
93  *
94  * PARAMETERS:  InString            - String to convert
95  *
96  * RETURN:      Pointer to a NS node
97  *
98  * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
99  *              alphanumeric strings.
100  *
101  ******************************************************************************/
102 
103 ACPI_NAMESPACE_NODE *
104 AcpiDbConvertToNode (
105     char                    *InString)
106 {
107     ACPI_NAMESPACE_NODE     *Node;
108 
109 
110     if ((*InString >= 0x30) && (*InString <= 0x39))
111     {
112         /* Numeric argument, convert */
113 
114         Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
115         if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
116         {
117             AcpiOsPrintf ("Address %p is invalid in this address space\n",
118                 Node);
119             return (NULL);
120         }
121 
122         /* Make sure pointer is valid NS node */
123 
124         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
125         {
126             AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
127                     Node, AcpiUtGetDescriptorName (Node));
128             return (NULL);
129         }
130     }
131     else
132     {
133         /*
134          * Alpha argument: The parameter is a name string that must be
135          * resolved to a Namespace object.
136          */
137         Node = AcpiDbLocalNsLookup (InString);
138         if (!Node)
139         {
140             Node = AcpiGbl_RootNode;
141         }
142     }
143 
144     return (Node);
145 }
146 
147 
148 /*******************************************************************************
149  *
150  * FUNCTION:    AcpiDbSleep
151  *
152  * PARAMETERS:  ObjectArg           - Desired sleep state (0-5). NULL means
153  *                                    invoke all possible sleep states.
154  *
155  * RETURN:      Status
156  *
157  * DESCRIPTION: Simulate sleep/wake sequences
158  *
159  ******************************************************************************/
160 
161 ACPI_STATUS
162 AcpiDbSleep (
163     char                    *ObjectArg)
164 {
165     UINT8                   SleepState;
166     UINT32                  i;
167 
168 
169     ACPI_FUNCTION_TRACE (AcpiDbSleep);
170 
171 
172     /* Null input (no arguments) means to invoke all sleep states */
173 
174     if (!ObjectArg)
175     {
176         AcpiOsPrintf ("Invoking all possible sleep states, 0-%d\n",
177             ACPI_S_STATES_MAX);
178 
179         for (i = 0; i <= ACPI_S_STATES_MAX; i++)
180         {
181             AcpiDbDoOneSleepState ((UINT8) i);
182         }
183 
184         return_ACPI_STATUS (AE_OK);
185     }
186 
187     /* Convert argument to binary and invoke the sleep state */
188 
189     SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
190     AcpiDbDoOneSleepState (SleepState);
191     return_ACPI_STATUS (AE_OK);
192 }
193 
194 
195 /*******************************************************************************
196  *
197  * FUNCTION:    AcpiDbDoOneSleepState
198  *
199  * PARAMETERS:  SleepState          - Desired sleep state (0-5)
200  *
201  * RETURN:      Status
202  *
203  * DESCRIPTION: Simulate a sleep/wake sequence
204  *
205  ******************************************************************************/
206 
207 static void
208 AcpiDbDoOneSleepState (
209     UINT8                   SleepState)
210 {
211     ACPI_STATUS             Status;
212     UINT8                   SleepTypeA;
213     UINT8                   SleepTypeB;
214 
215 
216     /* Validate parameter */
217 
218     if (SleepState > ACPI_S_STATES_MAX)
219     {
220         AcpiOsPrintf ("Sleep state %d out of range (%d max)\n",
221             SleepState, ACPI_S_STATES_MAX);
222         return;
223     }
224 
225     AcpiOsPrintf ("\n---- Invoking sleep state S%d (%s):\n",
226         SleepState, AcpiGbl_SleepStateNames[SleepState]);
227 
228     /* Get the values for the sleep type registers (for display only) */
229 
230     Status = AcpiGetSleepTypeData (SleepState, &SleepTypeA, &SleepTypeB);
231     if (ACPI_FAILURE (Status))
232     {
233         AcpiOsPrintf ("Could not evaluate [%s] method, %s\n",
234             AcpiGbl_SleepStateNames[SleepState],
235             AcpiFormatException (Status));
236         return;
237     }
238 
239     AcpiOsPrintf (
240         "Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
241         SleepState, SleepTypeA, SleepTypeB);
242 
243     /* Invoke the various sleep/wake interfaces */
244 
245     AcpiOsPrintf ("**** Sleep: Prepare to sleep (S%d) ****\n",
246         SleepState);
247     Status = AcpiEnterSleepStatePrep (SleepState);
248     if (ACPI_FAILURE (Status))
249     {
250         goto ErrorExit;
251     }
252 
253     AcpiOsPrintf ("**** Sleep: Going to sleep (S%d) ****\n",
254         SleepState);
255     Status = AcpiEnterSleepState (SleepState);
256     if (ACPI_FAILURE (Status))
257     {
258         goto ErrorExit;
259     }
260 
261     AcpiOsPrintf ("**** Wake: Prepare to return from sleep (S%d) ****\n",
262         SleepState);
263     Status = AcpiLeaveSleepStatePrep (SleepState);
264     if (ACPI_FAILURE (Status))
265     {
266         goto ErrorExit;
267     }
268 
269     AcpiOsPrintf ("**** Wake: Return from sleep (S%d) ****\n",
270         SleepState);
271     Status = AcpiLeaveSleepState (SleepState);
272     if (ACPI_FAILURE (Status))
273     {
274         goto ErrorExit;
275     }
276 
277     return;
278 
279 
280 ErrorExit:
281     ACPI_EXCEPTION ((AE_INFO, Status, "During invocation of sleep state S%d",
282         SleepState));
283 }
284 
285 
286 /*******************************************************************************
287  *
288  * FUNCTION:    AcpiDbDisplayLocks
289  *
290  * PARAMETERS:  None
291  *
292  * RETURN:      None
293  *
294  * DESCRIPTION: Display information about internal mutexes.
295  *
296  ******************************************************************************/
297 
298 void
299 AcpiDbDisplayLocks (
300     void)
301 {
302     UINT32                  i;
303 
304 
305     for (i = 0; i < ACPI_MAX_MUTEX; i++)
306     {
307         AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
308             AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
309                 ? "Locked" : "Unlocked");
310     }
311 }
312 
313 
314 /*******************************************************************************
315  *
316  * FUNCTION:    AcpiDbDisplayTableInfo
317  *
318  * PARAMETERS:  TableArg            - Name of table to be displayed
319  *
320  * RETURN:      None
321  *
322  * DESCRIPTION: Display information about loaded tables. Current
323  *              implementation displays all loaded tables.
324  *
325  ******************************************************************************/
326 
327 void
328 AcpiDbDisplayTableInfo (
329     char                    *TableArg)
330 {
331     UINT32                  i;
332     ACPI_TABLE_DESC         *TableDesc;
333     ACPI_STATUS             Status;
334 
335 
336     /* Header */
337 
338     AcpiOsPrintf ("Idx ID Status    Type            Sig  Address  Len   Header\n");
339 
340     /* Walk the entire root table list */
341 
342     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
343     {
344         TableDesc = &AcpiGbl_RootTableList.Tables[i];
345 
346         /* Index and Table ID */
347 
348         AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId);
349 
350         /* Decode the table flags */
351 
352         if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED))
353         {
354             AcpiOsPrintf ("NotLoaded ");
355         }
356         else
357         {
358             AcpiOsPrintf ("   Loaded ");
359         }
360 
361         switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
362         {
363         case ACPI_TABLE_ORIGIN_UNKNOWN:
364             AcpiOsPrintf ("Unknown   ");
365             break;
366 
367         case ACPI_TABLE_ORIGIN_MAPPED:
368             AcpiOsPrintf ("Mapped    ");
369             break;
370 
371         case ACPI_TABLE_ORIGIN_ALLOCATED:
372             AcpiOsPrintf ("Allocated ");
373             break;
374 
375         case ACPI_TABLE_ORIGIN_OVERRIDE:
376             AcpiOsPrintf ("Override  ");
377             break;
378 
379         default:
380             AcpiOsPrintf ("INVALID   ");
381             break;
382         }
383 
384         /* Make sure that the table is mapped */
385 
386         Status = AcpiTbVerifyTable (TableDesc);
387         if (ACPI_FAILURE (Status))
388         {
389             return;
390         }
391 
392         /* Dump the table header */
393 
394         if (TableDesc->Pointer)
395         {
396             AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
397         }
398         else
399         {
400             /* If the pointer is null, the table has been unloaded */
401 
402             ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
403                 TableDesc->Signature.Ascii));
404         }
405     }
406 }
407 
408 
409 /*******************************************************************************
410  *
411  * FUNCTION:    AcpiDbUnloadAcpiTable
412  *
413  * PARAMETERS:  ObjectName          - Namespace pathname for an object that
414  *                                    is owned by the table to be unloaded
415  *
416  * RETURN:      None
417  *
418  * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
419  *              by the table.
420  *
421  ******************************************************************************/
422 
423 void
424 AcpiDbUnloadAcpiTable (
425     char                    *ObjectName)
426 {
427     ACPI_NAMESPACE_NODE     *Node;
428     ACPI_STATUS             Status;
429 
430 
431     /* Translate name to an Named object */
432 
433     Node = AcpiDbConvertToNode (ObjectName);
434     if (!Node)
435     {
436         AcpiOsPrintf ("Could not find [%s] in namespace\n",
437             ObjectName);
438         return;
439     }
440 
441     Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node));
442     if (ACPI_SUCCESS (Status))
443     {
444         AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n",
445             ObjectName, Node);
446     }
447     else
448     {
449         AcpiOsPrintf ("%s, while unloading parent table of [%s]\n",
450             AcpiFormatException (Status), ObjectName);
451     }
452 }
453 
454 
455 /*******************************************************************************
456  *
457  * FUNCTION:    AcpiDbSendNotify
458  *
459  * PARAMETERS:  Name                - Name of ACPI object where to send notify
460  *              Value               - Value of the notify to send.
461  *
462  * RETURN:      None
463  *
464  * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
465  *              named object as an ACPI notify.
466  *
467  ******************************************************************************/
468 
469 void
470 AcpiDbSendNotify (
471     char                    *Name,
472     UINT32                  Value)
473 {
474     ACPI_NAMESPACE_NODE     *Node;
475     ACPI_STATUS             Status;
476 
477 
478     /* Translate name to an Named object */
479 
480     Node = AcpiDbConvertToNode (Name);
481     if (!Node)
482     {
483         return;
484     }
485 
486     /* Dispatch the notify if legal */
487 
488     if (AcpiEvIsNotifyObject (Node))
489     {
490         Status = AcpiEvQueueNotifyRequest (Node, Value);
491         if (ACPI_FAILURE (Status))
492         {
493             AcpiOsPrintf ("Could not queue notify\n");
494         }
495     }
496     else
497     {
498         AcpiOsPrintf (
499             "Named object [%4.4s] Type %s, must be Device/Thermal/Processor type\n",
500             AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type));
501     }
502 }
503 
504 
505 /*******************************************************************************
506  *
507  * FUNCTION:    AcpiDbDisplayInterfaces
508  *
509  * PARAMETERS:  ActionArg           - Null, "install", or "remove"
510  *              InterfaceNameArg    - Name for install/remove options
511  *
512  * RETURN:      None
513  *
514  * DESCRIPTION: Display or modify the global _OSI interface list
515  *
516  ******************************************************************************/
517 
518 void
519 AcpiDbDisplayInterfaces (
520     char                    *ActionArg,
521     char                    *InterfaceNameArg)
522 {
523     ACPI_INTERFACE_INFO     *NextInterface;
524     char                    *SubString;
525     ACPI_STATUS             Status;
526 
527 
528     /* If no arguments, just display current interface list */
529 
530     if (!ActionArg)
531     {
532         (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex,
533                     ACPI_WAIT_FOREVER);
534 
535         NextInterface = AcpiGbl_SupportedInterfaces;
536         while (NextInterface)
537         {
538             if (!(NextInterface->Flags & ACPI_OSI_INVALID))
539             {
540                 AcpiOsPrintf ("%s\n", NextInterface->Name);
541             }
542             NextInterface = NextInterface->Next;
543         }
544 
545         AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
546         return;
547     }
548 
549     /* If ActionArg exists, so must InterfaceNameArg */
550 
551     if (!InterfaceNameArg)
552     {
553         AcpiOsPrintf ("Missing Interface Name argument\n");
554         return;
555     }
556 
557     /* Uppercase the action for match below */
558 
559     AcpiUtStrupr (ActionArg);
560 
561     /* Install - install an interface */
562 
563     SubString = ACPI_STRSTR ("INSTALL", ActionArg);
564     if (SubString)
565     {
566         Status = AcpiInstallInterface (InterfaceNameArg);
567         if (ACPI_FAILURE (Status))
568         {
569             AcpiOsPrintf ("%s, while installing \"%s\"\n",
570                 AcpiFormatException (Status), InterfaceNameArg);
571         }
572         return;
573     }
574 
575     /* Remove - remove an interface */
576 
577     SubString = ACPI_STRSTR ("REMOVE", ActionArg);
578     if (SubString)
579     {
580         Status = AcpiRemoveInterface (InterfaceNameArg);
581         if (ACPI_FAILURE (Status))
582         {
583             AcpiOsPrintf ("%s, while removing \"%s\"\n",
584                 AcpiFormatException (Status), InterfaceNameArg);
585         }
586         return;
587     }
588 
589     /* Invalid ActionArg */
590 
591     AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg);
592     return;
593 }
594 
595 
596 /*******************************************************************************
597  *
598  * FUNCTION:    AcpiDbDisplayTemplate
599  *
600  * PARAMETERS:  BufferArg           - Buffer name or address
601  *
602  * RETURN:      None
603  *
604  * DESCRIPTION: Dump a buffer that contains a resource template
605  *
606  ******************************************************************************/
607 
608 void
609 AcpiDbDisplayTemplate (
610     char                    *BufferArg)
611 {
612     ACPI_NAMESPACE_NODE     *Node;
613     ACPI_STATUS             Status;
614     ACPI_BUFFER             ReturnBuffer;
615 
616 
617     /* Translate BufferArg to an Named object */
618 
619     Node = AcpiDbConvertToNode (BufferArg);
620     if (!Node || (Node == AcpiGbl_RootNode))
621     {
622         AcpiOsPrintf ("Invalid argument: %s\n", BufferArg);
623         return;
624     }
625 
626     /* We must have a buffer object */
627 
628     if (Node->Type != ACPI_TYPE_BUFFER)
629     {
630         AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n",
631             BufferArg);
632         return;
633     }
634 
635     ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
636     ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
637 
638     /* Attempt to convert the raw buffer to a resource list */
639 
640     Status = AcpiRsCreateResourceList (Node->Object, &ReturnBuffer);
641 
642     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
643     AcpiDbgLevel |= ACPI_LV_RESOURCES;
644 
645     if (ACPI_FAILURE (Status))
646     {
647         AcpiOsPrintf ("Could not convert Buffer to a resource list: %s, %s\n",
648             BufferArg, AcpiFormatException (Status));
649         goto DumpBuffer;
650     }
651 
652     /* Now we can dump the resource list */
653 
654     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
655         ReturnBuffer.Pointer));
656 
657 DumpBuffer:
658     AcpiOsPrintf ("\nRaw data buffer:\n");
659     AcpiUtDebugDumpBuffer ((UINT8 *) Node->Object->Buffer.Pointer,
660         Node->Object->Buffer.Length,
661         DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
662 
663     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
664     return;
665 }
666 
667 
668 /*******************************************************************************
669  *
670  * FUNCTION:    AcpiDmCompareAmlResources
671  *
672  * PARAMETERS:  Aml1Buffer          - Contains first resource list
673  *              Aml1BufferLength    - Length of first resource list
674  *              Aml2Buffer          - Contains second resource list
675  *              Aml2BufferLength    - Length of second resource list
676  *
677  * RETURN:      None
678  *
679  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
680  *              order to isolate a miscompare to an individual resource)
681  *
682  ******************************************************************************/
683 
684 static void
685 AcpiDmCompareAmlResources (
686     UINT8                   *Aml1Buffer,
687     ACPI_RSDESC_SIZE        Aml1BufferLength,
688     UINT8                   *Aml2Buffer,
689     ACPI_RSDESC_SIZE        Aml2BufferLength)
690 {
691     UINT8                   *Aml1;
692     UINT8                   *Aml2;
693     UINT8                   *Aml1End;
694     UINT8                   *Aml2End;
695     ACPI_RSDESC_SIZE        Aml1Length;
696     ACPI_RSDESC_SIZE        Aml2Length;
697     ACPI_RSDESC_SIZE        Offset = 0;
698     UINT8                   ResourceType;
699     UINT32                  Count = 0;
700     UINT32                  i;
701 
702 
703     /* Compare overall buffer sizes (may be different due to size rounding) */
704 
705     if (Aml1BufferLength != Aml2BufferLength)
706     {
707         AcpiOsPrintf (
708             "**** Buffer length mismatch in converted AML: Original %X, New %X ****\n",
709             Aml1BufferLength, Aml2BufferLength);
710     }
711 
712     Aml1 = Aml1Buffer;
713     Aml2 = Aml2Buffer;
714     Aml1End = Aml1Buffer + Aml1BufferLength;
715     Aml2End = Aml2Buffer + Aml2BufferLength;
716 
717     /* Walk the descriptor lists, comparing each descriptor */
718 
719     while ((Aml1 < Aml1End) && (Aml2 < Aml2End))
720     {
721         /* Get the lengths of each descriptor */
722 
723         Aml1Length = AcpiUtGetDescriptorLength (Aml1);
724         Aml2Length = AcpiUtGetDescriptorLength (Aml2);
725         ResourceType = AcpiUtGetResourceType (Aml1);
726 
727         /* Check for descriptor length match */
728 
729         if (Aml1Length != Aml2Length)
730         {
731             AcpiOsPrintf (
732                 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X Len1 %X, Len2 %X ****\n",
733                 Count, ResourceType, Offset, Aml1Length, Aml2Length);
734         }
735 
736         /* Check for descriptor byte match */
737 
738         else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
739         {
740             AcpiOsPrintf (
741                 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
742                 Count, ResourceType, Offset);
743 
744             for (i = 0; i < Aml1Length; i++)
745             {
746                 if (Aml1[i] != Aml2[i])
747                 {
748                     AcpiOsPrintf (
749                         "Mismatch at byte offset %.2X: is %2.2X, should be %2.2X\n",
750                         i, Aml2[i], Aml1[i]);
751                 }
752             }
753         }
754 
755         /* Exit on EndTag descriptor */
756 
757         if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
758         {
759             return;
760         }
761 
762         /* Point to next descriptor in each buffer */
763 
764         Count++;
765         Offset += Aml1Length;
766         Aml1 += Aml1Length;
767         Aml2 += Aml2Length;
768     }
769 }
770 
771 
772 /*******************************************************************************
773  *
774  * FUNCTION:    AcpiDmTestResourceConversion
775  *
776  * PARAMETERS:  Node                - Parent device node
777  *              Name                - resource method name (_CRS)
778  *
779  * RETURN:      Status
780  *
781  * DESCRIPTION: Compare the original AML with a conversion of the AML to
782  *              internal resource list, then back to AML.
783  *
784  ******************************************************************************/
785 
786 static ACPI_STATUS
787 AcpiDmTestResourceConversion (
788     ACPI_NAMESPACE_NODE     *Node,
789     char                    *Name)
790 {
791     ACPI_STATUS             Status;
792     ACPI_BUFFER             ReturnBuffer;
793     ACPI_BUFFER             ResourceBuffer;
794     ACPI_BUFFER             NewAml;
795     ACPI_OBJECT             *OriginalAml;
796 
797 
798     AcpiOsPrintf ("Resource Conversion Comparison:\n");
799 
800     NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
801     ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
802     ResourceBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
803 
804     /* Get the original _CRS AML resource template */
805 
806     Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnBuffer);
807     if (ACPI_FAILURE (Status))
808     {
809         AcpiOsPrintf ("Could not obtain %s: %s\n",
810             Name, AcpiFormatException (Status));
811         return (Status);
812     }
813 
814     /* Get the AML resource template, converted to internal resource structs */
815 
816     Status = AcpiGetCurrentResources (Node, &ResourceBuffer);
817     if (ACPI_FAILURE (Status))
818     {
819         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
820             AcpiFormatException (Status));
821         goto Exit1;
822     }
823 
824     /* Convert internal resource list to external AML resource template */
825 
826     Status = AcpiRsCreateAmlResources (ResourceBuffer.Pointer, &NewAml);
827     if (ACPI_FAILURE (Status))
828     {
829         AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
830             AcpiFormatException (Status));
831         goto Exit2;
832     }
833 
834     /* Compare original AML to the newly created AML resource list */
835 
836     OriginalAml = ReturnBuffer.Pointer;
837 
838     AcpiDmCompareAmlResources (
839         OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
840         NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
841 
842     /* Cleanup and exit */
843 
844     ACPI_FREE (NewAml.Pointer);
845 Exit2:
846     ACPI_FREE (ResourceBuffer.Pointer);
847 Exit1:
848     ACPI_FREE (ReturnBuffer.Pointer);
849     return (Status);
850 }
851 
852 
853 /*******************************************************************************
854  *
855  * FUNCTION:    AcpiDbResourceCallback
856  *
857  * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
858  *
859  * RETURN:      Status
860  *
861  * DESCRIPTION: Simple callback to exercise AcpiWalkResources and
862  *              AcpiWalkResourceBuffer.
863  *
864  ******************************************************************************/
865 
866 static ACPI_STATUS
867 AcpiDbResourceCallback (
868     ACPI_RESOURCE           *Resource,
869     void                    *Context)
870 {
871 
872     return (AE_OK);
873 }
874 
875 
876 /*******************************************************************************
877  *
878  * FUNCTION:    AcpiDbDeviceResources
879  *
880  * PARAMETERS:  ACPI_WALK_CALLBACK
881  *
882  * RETURN:      Status
883  *
884  * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
885  *
886  ******************************************************************************/
887 
888 static ACPI_STATUS
889 AcpiDbDeviceResources (
890     ACPI_HANDLE             ObjHandle,
891     UINT32                  NestingLevel,
892     void                    *Context,
893     void                    **ReturnValue)
894 {
895     ACPI_NAMESPACE_NODE     *Node;
896     ACPI_NAMESPACE_NODE     *PrtNode = NULL;
897     ACPI_NAMESPACE_NODE     *CrsNode = NULL;
898     ACPI_NAMESPACE_NODE     *PrsNode = NULL;
899     ACPI_NAMESPACE_NODE     *AeiNode = NULL;
900     char                    *ParentPath;
901     ACPI_BUFFER             ReturnBuffer;
902     ACPI_STATUS             Status;
903 
904 
905     Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
906     ParentPath = AcpiNsGetExternalPathname (Node);
907     if (!ParentPath)
908     {
909         return (AE_NO_MEMORY);
910     }
911 
912     /* Get handles to the resource methods for this device */
913 
914     (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode));
915     (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode));
916     (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode));
917     (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode));
918     if (!PrtNode && !CrsNode && !PrsNode && !AeiNode)
919     {
920         goto Cleanup;   /* Nothing to do */
921     }
922 
923     AcpiOsPrintf ("\nDevice: %s\n", ParentPath);
924 
925     /* Prepare for a return object of arbitrary size */
926 
927     ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
928     ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
929 
930 
931     /* _PRT */
932 
933     if (PrtNode)
934     {
935         AcpiOsPrintf ("Evaluating _PRT\n");
936 
937         Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnBuffer);
938         if (ACPI_FAILURE (Status))
939         {
940             AcpiOsPrintf ("Could not evaluate _PRT: %s\n",
941                 AcpiFormatException (Status));
942             goto GetCrs;
943         }
944 
945         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
946         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
947 
948         Status = AcpiGetIrqRoutingTable (Node, &ReturnBuffer);
949         if (ACPI_FAILURE (Status))
950         {
951             AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
952                 AcpiFormatException (Status));
953             goto GetCrs;
954         }
955 
956         AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
957     }
958 
959 
960     /* _CRS */
961 
962 GetCrs:
963     if (CrsNode)
964     {
965         AcpiOsPrintf ("Evaluating _CRS\n");
966 
967         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
968         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
969 
970         Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnBuffer);
971         if (ACPI_FAILURE (Status))
972         {
973             AcpiOsPrintf ("Could not evaluate _CRS: %s\n",
974                 AcpiFormatException (Status));
975             goto GetPrs;
976         }
977 
978         /* This code exercises the AcpiWalkResources interface */
979 
980         Status = AcpiWalkResources (Node, METHOD_NAME__CRS,
981             AcpiDbResourceCallback, NULL);
982         if (ACPI_FAILURE (Status))
983         {
984             AcpiOsPrintf ("AcpiWalkResources failed: %s\n",
985                 AcpiFormatException (Status));
986             goto GetPrs;
987         }
988 
989         /* Get the _CRS resource list (test ALLOCATE buffer) */
990 
991         ReturnBuffer.Pointer = NULL;
992         ReturnBuffer.Length  = ACPI_ALLOCATE_LOCAL_BUFFER;
993 
994         Status = AcpiGetCurrentResources (Node, &ReturnBuffer);
995         if (ACPI_FAILURE (Status))
996         {
997             AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
998                 AcpiFormatException (Status));
999             goto GetPrs;
1000         }
1001 
1002         /* This code exercises the AcpiWalkResourceBuffer interface */
1003 
1004         Status = AcpiWalkResourceBuffer (&ReturnBuffer,
1005             AcpiDbResourceCallback, NULL);
1006         if (ACPI_FAILURE (Status))
1007         {
1008             AcpiOsPrintf ("AcpiWalkResourceBuffer failed: %s\n",
1009                 AcpiFormatException (Status));
1010             goto EndCrs;
1011         }
1012 
1013         /* Dump the _CRS resource list */
1014 
1015         AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1016             ReturnBuffer.Pointer));
1017 
1018         /*
1019          * Perform comparison of original AML to newly created AML. This
1020          * tests both the AML->Resource conversion and the Resource->AML
1021          * conversion.
1022          */
1023         (void) AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1024 
1025         /* Execute _SRS with the resource list */
1026 
1027         AcpiOsPrintf ("Evaluating _SRS\n");
1028 
1029         Status = AcpiSetCurrentResources (Node, &ReturnBuffer);
1030         if (ACPI_FAILURE (Status))
1031         {
1032             AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1033                 AcpiFormatException (Status));
1034             goto EndCrs;
1035         }
1036 
1037 EndCrs:
1038         ACPI_FREE_BUFFER (ReturnBuffer);
1039     }
1040 
1041 
1042     /* _PRS */
1043 
1044 GetPrs:
1045     if (PrsNode)
1046     {
1047         AcpiOsPrintf ("Evaluating _PRS\n");
1048 
1049         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1050         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1051 
1052         Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnBuffer);
1053         if (ACPI_FAILURE (Status))
1054         {
1055             AcpiOsPrintf ("Could not evaluate _PRS: %s\n",
1056                 AcpiFormatException (Status));
1057             goto GetAei;
1058         }
1059 
1060         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1061         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1062 
1063         Status = AcpiGetPossibleResources (Node, &ReturnBuffer);
1064         if (ACPI_FAILURE (Status))
1065         {
1066             AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1067                 AcpiFormatException (Status));
1068             goto GetAei;
1069         }
1070 
1071         AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1072     }
1073 
1074 
1075     /* _AEI */
1076 
1077 GetAei:
1078     if (AeiNode)
1079     {
1080         AcpiOsPrintf ("Evaluating _AEI\n");
1081 
1082         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1083         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1084 
1085         Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnBuffer);
1086         if (ACPI_FAILURE (Status))
1087         {
1088             AcpiOsPrintf ("Could not evaluate _AEI: %s\n",
1089                 AcpiFormatException (Status));
1090             goto Cleanup;
1091         }
1092 
1093         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1094         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1095 
1096         Status = AcpiGetEventResources (Node, &ReturnBuffer);
1097         if (ACPI_FAILURE (Status))
1098         {
1099             AcpiOsPrintf ("AcpiGetEventResources failed: %s\n",
1100                 AcpiFormatException (Status));
1101             goto Cleanup;
1102         }
1103 
1104         AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1105     }
1106 
1107 
1108 Cleanup:
1109     ACPI_FREE (ParentPath);
1110     return (AE_OK);
1111 }
1112 
1113 
1114 /*******************************************************************************
1115  *
1116  * FUNCTION:    AcpiDbDisplayResources
1117  *
1118  * PARAMETERS:  ObjectArg           - String object name or object pointer.
1119  *                                    NULL or "*" means "display resources for
1120  *                                    all devices"
1121  *
1122  * RETURN:      None
1123  *
1124  * DESCRIPTION: Display the resource objects associated with a device.
1125  *
1126  ******************************************************************************/
1127 
1128 void
1129 AcpiDbDisplayResources (
1130     char                    *ObjectArg)
1131 {
1132     ACPI_NAMESPACE_NODE     *Node;
1133 
1134 
1135     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1136     AcpiDbgLevel |= ACPI_LV_RESOURCES;
1137 
1138     /* Asterisk means "display resources for all devices" */
1139 
1140     if (!ObjectArg || (!ACPI_STRCMP (ObjectArg, "*")))
1141     {
1142         (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1143                     ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL);
1144     }
1145     else
1146     {
1147         /* Convert string to object pointer */
1148 
1149         Node = AcpiDbConvertToNode (ObjectArg);
1150         if (Node)
1151         {
1152             if (Node->Type != ACPI_TYPE_DEVICE)
1153             {
1154                 AcpiOsPrintf ("%4.4s: Name is not a device object (%s)\n",
1155                     Node->Name.Ascii, AcpiUtGetTypeName (Node->Type));
1156             }
1157             else
1158             {
1159                 (void) AcpiDbDeviceResources (Node, 0, NULL, NULL);
1160             }
1161         }
1162     }
1163 
1164     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1165 }
1166 
1167 
1168 #if (!ACPI_REDUCED_HARDWARE)
1169 /*******************************************************************************
1170  *
1171  * FUNCTION:    AcpiDbGenerateGpe
1172  *
1173  * PARAMETERS:  GpeArg              - Raw GPE number, ascii string
1174  *              BlockArg            - GPE block number, ascii string
1175  *                                    0 or 1 for FADT GPE blocks
1176  *
1177  * RETURN:      None
1178  *
1179  * DESCRIPTION: Simulate firing of a GPE
1180  *
1181  ******************************************************************************/
1182 
1183 void
1184 AcpiDbGenerateGpe (
1185     char                    *GpeArg,
1186     char                    *BlockArg)
1187 {
1188     UINT32                  BlockNumber;
1189     UINT32                  GpeNumber;
1190     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1191 
1192 
1193     GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1194     BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1195 
1196 
1197     GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1198         GpeNumber);
1199     if (!GpeEventInfo)
1200     {
1201         AcpiOsPrintf ("Invalid GPE\n");
1202         return;
1203     }
1204 
1205     (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
1206 }
1207 #endif /* !ACPI_REDUCED_HARDWARE */
1208 
1209 #endif /* ACPI_DEBUGGER */
1210