1 /*******************************************************************************
2  *
3  * Module Name: dbcmds - Miscellaneous debug commands and output routines
4  *
5  ******************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/include/acpi.h>
153 #include <contrib/dev/acpica/include/accommon.h>
154 #include <contrib/dev/acpica/include/acevents.h>
155 #include <contrib/dev/acpica/include/acdebug.h>
156 #include <contrib/dev/acpica/include/acnamesp.h>
157 #include <contrib/dev/acpica/include/acresrc.h>
158 #include <contrib/dev/acpica/include/actables.h>
159 
160 
161 #define _COMPONENT          ACPI_CA_DEBUGGER
162         ACPI_MODULE_NAME    ("dbcmds")
163 
164 
165 /* Local prototypes */
166 
167 static void
168 AcpiDmCompareAmlResources (
169     UINT8                   *Aml1Buffer,
170     ACPI_RSDESC_SIZE        Aml1BufferLength,
171     UINT8                   *Aml2Buffer,
172     ACPI_RSDESC_SIZE        Aml2BufferLength);
173 
174 static ACPI_STATUS
175 AcpiDmTestResourceConversion (
176     ACPI_NAMESPACE_NODE     *Node,
177     char                    *Name);
178 
179 static ACPI_STATUS
180 AcpiDbResourceCallback (
181     ACPI_RESOURCE           *Resource,
182     void                    *Context);
183 
184 static ACPI_STATUS
185 AcpiDbDeviceResources (
186     ACPI_HANDLE             ObjHandle,
187     UINT32                  NestingLevel,
188     void                    *Context,
189     void                    **ReturnValue);
190 
191 static void
192 AcpiDbDoOneSleepState (
193     UINT8                   SleepState);
194 
195 
196 static char                 *AcpiDbTraceMethodName = NULL;
197 
198 
199 /*******************************************************************************
200  *
201  * FUNCTION:    AcpiDbConvertToNode
202  *
203  * PARAMETERS:  InString            - String to convert
204  *
205  * RETURN:      Pointer to a NS node
206  *
207  * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
208  *              alphanumeric strings.
209  *
210  ******************************************************************************/
211 
212 ACPI_NAMESPACE_NODE *
213 AcpiDbConvertToNode (
214     char                    *InString)
215 {
216     ACPI_NAMESPACE_NODE     *Node;
217     ACPI_SIZE               Address;
218 
219 
220     if ((*InString >= 0x30) && (*InString <= 0x39))
221     {
222         /* Numeric argument, convert */
223 
224         Address = strtoul (InString, NULL, 16);
225         Node = ACPI_TO_POINTER (Address);
226         if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
227         {
228             AcpiOsPrintf ("Address %p is invalid", Node);
229             return (NULL);
230         }
231 
232         /* Make sure pointer is valid NS node */
233 
234         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
235         {
236             AcpiOsPrintf ("Address %p is not a valid namespace node [%s]\n",
237                 Node, AcpiUtGetDescriptorName (Node));
238             return (NULL);
239         }
240     }
241     else
242     {
243         /*
244          * Alpha argument: The parameter is a name string that must be
245          * resolved to a Namespace object.
246          */
247         Node = AcpiDbLocalNsLookup (InString);
248         if (!Node)
249         {
250             AcpiOsPrintf (
251                 "Could not find [%s] in namespace, defaulting to root node\n",
252                 InString);
253             Node = AcpiGbl_RootNode;
254         }
255     }
256 
257     return (Node);
258 }
259 
260 
261 /*******************************************************************************
262  *
263  * FUNCTION:    AcpiDbSleep
264  *
265  * PARAMETERS:  ObjectArg           - Desired sleep state (0-5). NULL means
266  *                                    invoke all possible sleep states.
267  *
268  * RETURN:      Status
269  *
270  * DESCRIPTION: Simulate sleep/wake sequences
271  *
272  ******************************************************************************/
273 
274 ACPI_STATUS
275 AcpiDbSleep (
276     char                    *ObjectArg)
277 {
278     UINT8                   SleepState;
279     UINT32                  i;
280 
281 
282     ACPI_FUNCTION_TRACE (AcpiDbSleep);
283 
284 
285     /* Null input (no arguments) means to invoke all sleep states */
286 
287     if (!ObjectArg)
288     {
289         AcpiOsPrintf ("Invoking all possible sleep states, 0-%d\n",
290             ACPI_S_STATES_MAX);
291 
292         for (i = 0; i <= ACPI_S_STATES_MAX; i++)
293         {
294             AcpiDbDoOneSleepState ((UINT8) i);
295         }
296 
297         return_ACPI_STATUS (AE_OK);
298     }
299 
300     /* Convert argument to binary and invoke the sleep state */
301 
302     SleepState = (UINT8) strtoul (ObjectArg, NULL, 0);
303     AcpiDbDoOneSleepState (SleepState);
304     return_ACPI_STATUS (AE_OK);
305 }
306 
307 
308 /*******************************************************************************
309  *
310  * FUNCTION:    AcpiDbDoOneSleepState
311  *
312  * PARAMETERS:  SleepState          - Desired sleep state (0-5)
313  *
314  * RETURN:      None
315  *
316  * DESCRIPTION: Simulate a sleep/wake sequence
317  *
318  ******************************************************************************/
319 
320 static void
321 AcpiDbDoOneSleepState (
322     UINT8                   SleepState)
323 {
324     ACPI_STATUS             Status;
325     UINT8                   SleepTypeA;
326     UINT8                   SleepTypeB;
327 
328 
329     /* Validate parameter */
330 
331     if (SleepState > ACPI_S_STATES_MAX)
332     {
333         AcpiOsPrintf ("Sleep state %d out of range (%d max)\n",
334             SleepState, ACPI_S_STATES_MAX);
335         return;
336     }
337 
338     AcpiOsPrintf ("\n---- Invoking sleep state S%d (%s):\n",
339         SleepState, AcpiGbl_SleepStateNames[SleepState]);
340 
341     /* Get the values for the sleep type registers (for display only) */
342 
343     Status = AcpiGetSleepTypeData (SleepState, &SleepTypeA, &SleepTypeB);
344     if (ACPI_FAILURE (Status))
345     {
346         AcpiOsPrintf ("Could not evaluate [%s] method, %s\n",
347             AcpiGbl_SleepStateNames[SleepState],
348             AcpiFormatException (Status));
349         return;
350     }
351 
352     AcpiOsPrintf (
353         "Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
354         SleepState, SleepTypeA, SleepTypeB);
355 
356     /* Invoke the various sleep/wake interfaces */
357 
358     AcpiOsPrintf ("**** Sleep: Prepare to sleep (S%d) ****\n",
359         SleepState);
360     Status = AcpiEnterSleepStatePrep (SleepState);
361     if (ACPI_FAILURE (Status))
362     {
363         goto ErrorExit;
364     }
365 
366     AcpiOsPrintf ("**** Sleep: Going to sleep (S%d) ****\n",
367         SleepState);
368     Status = AcpiEnterSleepState (SleepState);
369     if (ACPI_FAILURE (Status))
370     {
371         goto ErrorExit;
372     }
373 
374     AcpiOsPrintf ("**** Wake: Prepare to return from sleep (S%d) ****\n",
375         SleepState);
376     Status = AcpiLeaveSleepStatePrep (SleepState);
377     if (ACPI_FAILURE (Status))
378     {
379         goto ErrorExit;
380     }
381 
382     AcpiOsPrintf ("**** Wake: Return from sleep (S%d) ****\n",
383         SleepState);
384     Status = AcpiLeaveSleepState (SleepState);
385     if (ACPI_FAILURE (Status))
386     {
387         goto ErrorExit;
388     }
389 
390     return;
391 
392 
393 ErrorExit:
394     ACPI_EXCEPTION ((AE_INFO, Status, "During invocation of sleep state S%d",
395         SleepState));
396 }
397 
398 
399 /*******************************************************************************
400  *
401  * FUNCTION:    AcpiDbDisplayLocks
402  *
403  * PARAMETERS:  None
404  *
405  * RETURN:      None
406  *
407  * DESCRIPTION: Display information about internal mutexes.
408  *
409  ******************************************************************************/
410 
411 void
412 AcpiDbDisplayLocks (
413     void)
414 {
415     UINT32                  i;
416 
417 
418     for (i = 0; i < ACPI_MAX_MUTEX; i++)
419     {
420         AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
421             AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
422                 ? "Locked" : "Unlocked");
423     }
424 }
425 
426 
427 /*******************************************************************************
428  *
429  * FUNCTION:    AcpiDbDisplayTableInfo
430  *
431  * PARAMETERS:  TableArg            - Name of table to be displayed
432  *
433  * RETURN:      None
434  *
435  * DESCRIPTION: Display information about loaded tables. Current
436  *              implementation displays all loaded tables.
437  *
438  ******************************************************************************/
439 
440 void
441 AcpiDbDisplayTableInfo (
442     char                    *TableArg)
443 {
444     UINT32                  i;
445     ACPI_TABLE_DESC         *TableDesc;
446     ACPI_STATUS             Status;
447 
448 
449     /* Header */
450 
451     AcpiOsPrintf ("Idx ID    Status Type                    "
452         "TableHeader (Sig, Address, Length, Misc)\n");
453 
454     /* Walk the entire root table list */
455 
456     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
457     {
458         TableDesc = &AcpiGbl_RootTableList.Tables[i];
459 
460         /* Index and Table ID */
461 
462         AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId);
463 
464         /* Decode the table flags */
465 
466         if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED))
467         {
468             AcpiOsPrintf ("NotLoaded ");
469         }
470         else
471         {
472             AcpiOsPrintf ("   Loaded ");
473         }
474 
475         switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
476         {
477         case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
478 
479             AcpiOsPrintf ("External/virtual  ");
480             break;
481 
482         case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
483 
484             AcpiOsPrintf ("Internal/physical ");
485             break;
486 
487         case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
488 
489             AcpiOsPrintf ("Internal/virtual  ");
490             break;
491 
492         default:
493 
494             AcpiOsPrintf ("INVALID TYPE      ");
495             break;
496         }
497 
498         /* Make sure that the table is mapped */
499 
500         Status = AcpiTbValidateTable (TableDesc);
501         if (ACPI_FAILURE (Status))
502         {
503             return;
504         }
505 
506         /* Dump the table header */
507 
508         if (TableDesc->Pointer)
509         {
510             AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
511         }
512         else
513         {
514             /* If the pointer is null, the table has been unloaded */
515 
516             ACPI_INFO (("%4.4s - Table has been unloaded",
517                 TableDesc->Signature.Ascii));
518         }
519     }
520 }
521 
522 
523 /*******************************************************************************
524  *
525  * FUNCTION:    AcpiDbUnloadAcpiTable
526  *
527  * PARAMETERS:  ObjectName          - Namespace pathname for an object that
528  *                                    is owned by the table to be unloaded
529  *
530  * RETURN:      None
531  *
532  * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
533  *              by the table.
534  *
535  ******************************************************************************/
536 
537 void
538 AcpiDbUnloadAcpiTable (
539     char                    *ObjectName)
540 {
541     ACPI_NAMESPACE_NODE     *Node;
542     ACPI_STATUS             Status;
543 
544 
545     /* Translate name to an Named object */
546 
547     Node = AcpiDbConvertToNode (ObjectName);
548     if (!Node)
549     {
550         return;
551     }
552 
553     Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node));
554     if (ACPI_SUCCESS (Status))
555     {
556         AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n",
557             ObjectName, Node);
558     }
559     else
560     {
561         AcpiOsPrintf ("%s, while unloading parent table of [%s]\n",
562             AcpiFormatException (Status), ObjectName);
563     }
564 }
565 
566 
567 /*******************************************************************************
568  *
569  * FUNCTION:    AcpiDbSendNotify
570  *
571  * PARAMETERS:  Name                - Name of ACPI object where to send notify
572  *              Value               - Value of the notify to send.
573  *
574  * RETURN:      None
575  *
576  * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
577  *              named object as an ACPI notify.
578  *
579  ******************************************************************************/
580 
581 void
582 AcpiDbSendNotify (
583     char                    *Name,
584     UINT32                  Value)
585 {
586     ACPI_NAMESPACE_NODE     *Node;
587     ACPI_STATUS             Status;
588 
589 
590     /* Translate name to an Named object */
591 
592     Node = AcpiDbConvertToNode (Name);
593     if (!Node)
594     {
595         return;
596     }
597 
598     /* Dispatch the notify if legal */
599 
600     if (AcpiEvIsNotifyObject (Node))
601     {
602         Status = AcpiEvQueueNotifyRequest (Node, Value);
603         if (ACPI_FAILURE (Status))
604         {
605             AcpiOsPrintf ("Could not queue notify\n");
606         }
607     }
608     else
609     {
610         AcpiOsPrintf (
611             "Named object [%4.4s] Type %s, "
612             "must be Device/Thermal/Processor type\n",
613             AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type));
614     }
615 }
616 
617 
618 /*******************************************************************************
619  *
620  * FUNCTION:    AcpiDbDisplayInterfaces
621  *
622  * PARAMETERS:  ActionArg           - Null, "install", or "remove"
623  *              InterfaceNameArg    - Name for install/remove options
624  *
625  * RETURN:      None
626  *
627  * DESCRIPTION: Display or modify the global _OSI interface list
628  *
629  ******************************************************************************/
630 
631 void
632 AcpiDbDisplayInterfaces (
633     char                    *ActionArg,
634     char                    *InterfaceNameArg)
635 {
636     ACPI_INTERFACE_INFO     *NextInterface;
637     char                    *SubString;
638     ACPI_STATUS             Status;
639 
640 
641     /* If no arguments, just display current interface list */
642 
643     if (!ActionArg)
644     {
645         (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
646 
647         NextInterface = AcpiGbl_SupportedInterfaces;
648         while (NextInterface)
649         {
650             if (!(NextInterface->Flags & ACPI_OSI_INVALID))
651             {
652                 AcpiOsPrintf ("%s\n", NextInterface->Name);
653             }
654 
655             NextInterface = NextInterface->Next;
656         }
657 
658         AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
659         return;
660     }
661 
662     /* If ActionArg exists, so must InterfaceNameArg */
663 
664     if (!InterfaceNameArg)
665     {
666         AcpiOsPrintf ("Missing Interface Name argument\n");
667         return;
668     }
669 
670     /* Uppercase the action for match below */
671 
672     AcpiUtStrupr (ActionArg);
673 
674     /* Install - install an interface */
675 
676     SubString = strstr ("INSTALL", ActionArg);
677     if (SubString)
678     {
679         Status = AcpiInstallInterface (InterfaceNameArg);
680         if (ACPI_FAILURE (Status))
681         {
682             AcpiOsPrintf ("%s, while installing \"%s\"\n",
683                 AcpiFormatException (Status), InterfaceNameArg);
684         }
685         return;
686     }
687 
688     /* Remove - remove an interface */
689 
690     SubString = strstr ("REMOVE", ActionArg);
691     if (SubString)
692     {
693         Status = AcpiRemoveInterface (InterfaceNameArg);
694         if (ACPI_FAILURE (Status))
695         {
696             AcpiOsPrintf ("%s, while removing \"%s\"\n",
697                 AcpiFormatException (Status), InterfaceNameArg);
698         }
699         return;
700     }
701 
702     /* Invalid ActionArg */
703 
704     AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg);
705     return;
706 }
707 
708 
709 /*******************************************************************************
710  *
711  * FUNCTION:    AcpiDbDisplayTemplate
712  *
713  * PARAMETERS:  BufferArg           - Buffer name or address
714  *
715  * RETURN:      None
716  *
717  * DESCRIPTION: Dump a buffer that contains a resource template
718  *
719  ******************************************************************************/
720 
721 void
722 AcpiDbDisplayTemplate (
723     char                    *BufferArg)
724 {
725     ACPI_NAMESPACE_NODE     *Node;
726     ACPI_STATUS             Status;
727     ACPI_BUFFER             ReturnBuffer;
728 
729 
730     /* Translate BufferArg to an Named object */
731 
732     Node = AcpiDbConvertToNode (BufferArg);
733     if (!Node || (Node == AcpiGbl_RootNode))
734     {
735         AcpiOsPrintf ("Invalid argument: %s\n", BufferArg);
736         return;
737     }
738 
739     /* We must have a buffer object */
740 
741     if (Node->Type != ACPI_TYPE_BUFFER)
742     {
743         AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n",
744             BufferArg);
745         return;
746     }
747 
748     ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
749     ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
750 
751     /* Attempt to convert the raw buffer to a resource list */
752 
753     Status = AcpiRsCreateResourceList (Node->Object, &ReturnBuffer);
754 
755     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
756     AcpiDbgLevel |= ACPI_LV_RESOURCES;
757 
758     if (ACPI_FAILURE (Status))
759     {
760         AcpiOsPrintf (
761             "Could not convert Buffer to a resource list: %s, %s\n",
762             BufferArg, AcpiFormatException (Status));
763         goto DumpBuffer;
764     }
765 
766     /* Now we can dump the resource list */
767 
768     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
769         ReturnBuffer.Pointer));
770 
771 DumpBuffer:
772     AcpiOsPrintf ("\nRaw data buffer:\n");
773     AcpiUtDebugDumpBuffer ((UINT8 *) Node->Object->Buffer.Pointer,
774         Node->Object->Buffer.Length,
775         DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
776 
777     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
778     return;
779 }
780 
781 
782 /*******************************************************************************
783  *
784  * FUNCTION:    AcpiDmCompareAmlResources
785  *
786  * PARAMETERS:  Aml1Buffer          - Contains first resource list
787  *              Aml1BufferLength    - Length of first resource list
788  *              Aml2Buffer          - Contains second resource list
789  *              Aml2BufferLength    - Length of second resource list
790  *
791  * RETURN:      None
792  *
793  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
794  *              order to isolate a miscompare to an individual resource)
795  *
796  ******************************************************************************/
797 
798 static void
799 AcpiDmCompareAmlResources (
800     UINT8                   *Aml1Buffer,
801     ACPI_RSDESC_SIZE        Aml1BufferLength,
802     UINT8                   *Aml2Buffer,
803     ACPI_RSDESC_SIZE        Aml2BufferLength)
804 {
805     UINT8                   *Aml1;
806     UINT8                   *Aml2;
807     UINT8                   *Aml1End;
808     UINT8                   *Aml2End;
809     ACPI_RSDESC_SIZE        Aml1Length;
810     ACPI_RSDESC_SIZE        Aml2Length;
811     ACPI_RSDESC_SIZE        Offset = 0;
812     UINT8                   ResourceType;
813     UINT32                  Count = 0;
814     UINT32                  i;
815 
816 
817     /* Compare overall buffer sizes (may be different due to size rounding) */
818 
819     if (Aml1BufferLength != Aml2BufferLength)
820     {
821         AcpiOsPrintf (
822             "**** Buffer length mismatch in converted "
823             "AML: Original %X, New %X ****\n",
824             Aml1BufferLength, Aml2BufferLength);
825     }
826 
827     Aml1 = Aml1Buffer;
828     Aml2 = Aml2Buffer;
829     Aml1End = Aml1Buffer + Aml1BufferLength;
830     Aml2End = Aml2Buffer + Aml2BufferLength;
831 
832     /* Walk the descriptor lists, comparing each descriptor */
833 
834     while ((Aml1 < Aml1End) && (Aml2 < Aml2End))
835     {
836         /* Get the lengths of each descriptor */
837 
838         Aml1Length = AcpiUtGetDescriptorLength (Aml1);
839         Aml2Length = AcpiUtGetDescriptorLength (Aml2);
840         ResourceType = AcpiUtGetResourceType (Aml1);
841 
842         /* Check for descriptor length match */
843 
844         if (Aml1Length != Aml2Length)
845         {
846             AcpiOsPrintf (
847                 "**** Length mismatch in descriptor [%.2X] type %2.2X, "
848                 "Offset %8.8X Len1 %X, Len2 %X ****\n",
849                 Count, ResourceType, Offset, Aml1Length, Aml2Length);
850         }
851 
852         /* Check for descriptor byte match */
853 
854         else if (memcmp (Aml1, Aml2, Aml1Length))
855         {
856             AcpiOsPrintf (
857                 "**** Data mismatch in descriptor [%.2X] type %2.2X, "
858                 "Offset %8.8X ****\n",
859                 Count, ResourceType, Offset);
860 
861             for (i = 0; i < Aml1Length; i++)
862             {
863                 if (Aml1[i] != Aml2[i])
864                 {
865                     AcpiOsPrintf (
866                         "Mismatch at byte offset %.2X: is %2.2X, "
867                         "should be %2.2X\n",
868                         i, Aml2[i], Aml1[i]);
869                 }
870             }
871         }
872 
873         /* Exit on EndTag descriptor */
874 
875         if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
876         {
877             return;
878         }
879 
880         /* Point to next descriptor in each buffer */
881 
882         Count++;
883         Offset += Aml1Length;
884         Aml1 += Aml1Length;
885         Aml2 += Aml2Length;
886     }
887 }
888 
889 
890 /*******************************************************************************
891  *
892  * FUNCTION:    AcpiDmTestResourceConversion
893  *
894  * PARAMETERS:  Node                - Parent device node
895  *              Name                - resource method name (_CRS)
896  *
897  * RETURN:      Status
898  *
899  * DESCRIPTION: Compare the original AML with a conversion of the AML to
900  *              internal resource list, then back to AML.
901  *
902  ******************************************************************************/
903 
904 static ACPI_STATUS
905 AcpiDmTestResourceConversion (
906     ACPI_NAMESPACE_NODE     *Node,
907     char                    *Name)
908 {
909     ACPI_STATUS             Status;
910     ACPI_BUFFER             ReturnBuffer;
911     ACPI_BUFFER             ResourceBuffer;
912     ACPI_BUFFER             NewAml;
913     ACPI_OBJECT             *OriginalAml;
914 
915 
916     AcpiOsPrintf ("Resource Conversion Comparison:\n");
917 
918     NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
919     ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
920     ResourceBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
921 
922     /* Get the original _CRS AML resource template */
923 
924     Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnBuffer);
925     if (ACPI_FAILURE (Status))
926     {
927         AcpiOsPrintf ("Could not obtain %s: %s\n",
928             Name, AcpiFormatException (Status));
929         return (Status);
930     }
931 
932     /* Get the AML resource template, converted to internal resource structs */
933 
934     Status = AcpiGetCurrentResources (Node, &ResourceBuffer);
935     if (ACPI_FAILURE (Status))
936     {
937         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
938             AcpiFormatException (Status));
939         goto Exit1;
940     }
941 
942     /* Convert internal resource list to external AML resource template */
943 
944     Status = AcpiRsCreateAmlResources (&ResourceBuffer, &NewAml);
945     if (ACPI_FAILURE (Status))
946     {
947         AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
948             AcpiFormatException (Status));
949         goto Exit2;
950     }
951 
952     /* Compare original AML to the newly created AML resource list */
953 
954     OriginalAml = ReturnBuffer.Pointer;
955 
956     AcpiDmCompareAmlResources (OriginalAml->Buffer.Pointer,
957         (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
958         NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
959 
960     /* Cleanup and exit */
961 
962     ACPI_FREE (NewAml.Pointer);
963 Exit2:
964     ACPI_FREE (ResourceBuffer.Pointer);
965 Exit1:
966     ACPI_FREE (ReturnBuffer.Pointer);
967     return (Status);
968 }
969 
970 
971 /*******************************************************************************
972  *
973  * FUNCTION:    AcpiDbResourceCallback
974  *
975  * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
976  *
977  * RETURN:      Status
978  *
979  * DESCRIPTION: Simple callback to exercise AcpiWalkResources and
980  *              AcpiWalkResourceBuffer.
981  *
982  ******************************************************************************/
983 
984 static ACPI_STATUS
985 AcpiDbResourceCallback (
986     ACPI_RESOURCE           *Resource,
987     void                    *Context)
988 {
989 
990     return (AE_OK);
991 }
992 
993 
994 /*******************************************************************************
995  *
996  * FUNCTION:    AcpiDbDeviceResources
997  *
998  * PARAMETERS:  ACPI_WALK_CALLBACK
999  *
1000  * RETURN:      Status
1001  *
1002  * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
1003  *
1004  ******************************************************************************/
1005 
1006 static ACPI_STATUS
1007 AcpiDbDeviceResources (
1008     ACPI_HANDLE             ObjHandle,
1009     UINT32                  NestingLevel,
1010     void                    *Context,
1011     void                    **ReturnValue)
1012 {
1013     ACPI_NAMESPACE_NODE     *Node;
1014     ACPI_NAMESPACE_NODE     *PrtNode = NULL;
1015     ACPI_NAMESPACE_NODE     *CrsNode = NULL;
1016     ACPI_NAMESPACE_NODE     *PrsNode = NULL;
1017     ACPI_NAMESPACE_NODE     *AeiNode = NULL;
1018     char                    *ParentPath;
1019     ACPI_BUFFER             ReturnBuffer;
1020     ACPI_STATUS             Status;
1021 
1022 
1023     Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
1024     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
1025     if (!ParentPath)
1026     {
1027         return (AE_NO_MEMORY);
1028     }
1029 
1030     /* Get handles to the resource methods for this device */
1031 
1032     (void) AcpiGetHandle (Node, METHOD_NAME__PRT,
1033         ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode));
1034     (void) AcpiGetHandle (Node, METHOD_NAME__CRS,
1035         ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode));
1036     (void) AcpiGetHandle (Node, METHOD_NAME__PRS,
1037         ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode));
1038     (void) AcpiGetHandle (Node, METHOD_NAME__AEI,
1039         ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode));
1040 
1041     if (!PrtNode && !CrsNode && !PrsNode && !AeiNode)
1042     {
1043         goto Cleanup;   /* Nothing to do */
1044     }
1045 
1046     AcpiOsPrintf ("\nDevice: %s\n", ParentPath);
1047 
1048     /* Prepare for a return object of arbitrary size */
1049 
1050     ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1051     ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1052 
1053 
1054     /* _PRT */
1055 
1056     if (PrtNode)
1057     {
1058         AcpiOsPrintf ("Evaluating _PRT\n");
1059 
1060         Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnBuffer);
1061         if (ACPI_FAILURE (Status))
1062         {
1063             AcpiOsPrintf ("Could not evaluate _PRT: %s\n",
1064                 AcpiFormatException (Status));
1065             goto GetCrs;
1066         }
1067 
1068         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1069         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1070 
1071         Status = AcpiGetIrqRoutingTable (Node, &ReturnBuffer);
1072         if (ACPI_FAILURE (Status))
1073         {
1074             AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1075                 AcpiFormatException (Status));
1076             goto GetCrs;
1077         }
1078 
1079         AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1080     }
1081 
1082 
1083     /* _CRS */
1084 
1085 GetCrs:
1086     if (CrsNode)
1087     {
1088         AcpiOsPrintf ("Evaluating _CRS\n");
1089 
1090         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1091         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1092 
1093         Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnBuffer);
1094         if (ACPI_FAILURE (Status))
1095         {
1096             AcpiOsPrintf ("Could not evaluate _CRS: %s\n",
1097                 AcpiFormatException (Status));
1098             goto GetPrs;
1099         }
1100 
1101         /* This code exercises the AcpiWalkResources interface */
1102 
1103         Status = AcpiWalkResources (Node, METHOD_NAME__CRS,
1104             AcpiDbResourceCallback, NULL);
1105         if (ACPI_FAILURE (Status))
1106         {
1107             AcpiOsPrintf ("AcpiWalkResources failed: %s\n",
1108                 AcpiFormatException (Status));
1109             goto GetPrs;
1110         }
1111 
1112         /* Get the _CRS resource list (test ALLOCATE buffer) */
1113 
1114         ReturnBuffer.Pointer = NULL;
1115         ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1116 
1117         Status = AcpiGetCurrentResources (Node, &ReturnBuffer);
1118         if (ACPI_FAILURE (Status))
1119         {
1120             AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1121                 AcpiFormatException (Status));
1122             goto GetPrs;
1123         }
1124 
1125         /* This code exercises the AcpiWalkResourceBuffer interface */
1126 
1127         Status = AcpiWalkResourceBuffer (&ReturnBuffer,
1128             AcpiDbResourceCallback, NULL);
1129         if (ACPI_FAILURE (Status))
1130         {
1131             AcpiOsPrintf ("AcpiWalkResourceBuffer failed: %s\n",
1132                 AcpiFormatException (Status));
1133             goto EndCrs;
1134         }
1135 
1136         /* Dump the _CRS resource list */
1137 
1138         AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1139             ReturnBuffer.Pointer));
1140 
1141         /*
1142          * Perform comparison of original AML to newly created AML. This
1143          * tests both the AML->Resource conversion and the Resource->AML
1144          * conversion.
1145          */
1146         (void) AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1147 
1148         /* Execute _SRS with the resource list */
1149 
1150         AcpiOsPrintf ("Evaluating _SRS\n");
1151 
1152         Status = AcpiSetCurrentResources (Node, &ReturnBuffer);
1153         if (ACPI_FAILURE (Status))
1154         {
1155             AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1156                 AcpiFormatException (Status));
1157             goto EndCrs;
1158         }
1159 
1160 EndCrs:
1161         ACPI_FREE (ReturnBuffer.Pointer);
1162     }
1163 
1164 
1165     /* _PRS */
1166 
1167 GetPrs:
1168     if (PrsNode)
1169     {
1170         AcpiOsPrintf ("Evaluating _PRS\n");
1171 
1172         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1173         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1174 
1175         Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnBuffer);
1176         if (ACPI_FAILURE (Status))
1177         {
1178             AcpiOsPrintf ("Could not evaluate _PRS: %s\n",
1179                 AcpiFormatException (Status));
1180             goto GetAei;
1181         }
1182 
1183         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1184         ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
1185 
1186         Status = AcpiGetPossibleResources (Node, &ReturnBuffer);
1187         if (ACPI_FAILURE (Status))
1188         {
1189             AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1190                 AcpiFormatException (Status));
1191             goto GetAei;
1192         }
1193 
1194         AcpiRsDumpResourceList (ACPI_CAST_PTR (
1195             ACPI_RESOURCE, AcpiGbl_DbBuffer));
1196     }
1197 
1198 
1199     /* _AEI */
1200 
1201 GetAei:
1202     if (AeiNode)
1203     {
1204         AcpiOsPrintf ("Evaluating _AEI\n");
1205 
1206         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1207         ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
1208 
1209         Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnBuffer);
1210         if (ACPI_FAILURE (Status))
1211         {
1212             AcpiOsPrintf ("Could not evaluate _AEI: %s\n",
1213                 AcpiFormatException (Status));
1214             goto Cleanup;
1215         }
1216 
1217         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1218         ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
1219 
1220         Status = AcpiGetEventResources (Node, &ReturnBuffer);
1221         if (ACPI_FAILURE (Status))
1222         {
1223             AcpiOsPrintf ("AcpiGetEventResources failed: %s\n",
1224                 AcpiFormatException (Status));
1225             goto Cleanup;
1226         }
1227 
1228         AcpiRsDumpResourceList (ACPI_CAST_PTR (
1229             ACPI_RESOURCE, AcpiGbl_DbBuffer));
1230     }
1231 
1232 
1233 Cleanup:
1234     ACPI_FREE (ParentPath);
1235     return (AE_OK);
1236 }
1237 
1238 
1239 /*******************************************************************************
1240  *
1241  * FUNCTION:    AcpiDbDisplayResources
1242  *
1243  * PARAMETERS:  ObjectArg           - String object name or object pointer.
1244  *                                    NULL or "*" means "display resources for
1245  *                                    all devices"
1246  *
1247  * RETURN:      None
1248  *
1249  * DESCRIPTION: Display the resource objects associated with a device.
1250  *
1251  ******************************************************************************/
1252 
1253 void
1254 AcpiDbDisplayResources (
1255     char                    *ObjectArg)
1256 {
1257     ACPI_NAMESPACE_NODE     *Node;
1258 
1259 
1260     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1261     AcpiDbgLevel |= ACPI_LV_RESOURCES;
1262 
1263     /* Asterisk means "display resources for all devices" */
1264 
1265     if (!ObjectArg || (!strcmp (ObjectArg, "*")))
1266     {
1267         (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1268             ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL);
1269     }
1270     else
1271     {
1272         /* Convert string to object pointer */
1273 
1274         Node = AcpiDbConvertToNode (ObjectArg);
1275         if (Node)
1276         {
1277             if (Node->Type != ACPI_TYPE_DEVICE)
1278             {
1279                 AcpiOsPrintf (
1280                     "%4.4s: Name is not a device object (%s)\n",
1281                     Node->Name.Ascii, AcpiUtGetTypeName (Node->Type));
1282             }
1283             else
1284             {
1285                 (void) AcpiDbDeviceResources (Node, 0, NULL, NULL);
1286             }
1287         }
1288     }
1289 
1290     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1291 }
1292 
1293 
1294 #if (!ACPI_REDUCED_HARDWARE)
1295 /*******************************************************************************
1296  *
1297  * FUNCTION:    AcpiDbGenerateGpe
1298  *
1299  * PARAMETERS:  GpeArg              - Raw GPE number, ascii string
1300  *              BlockArg            - GPE block number, ascii string
1301  *                                    0 or 1 for FADT GPE blocks
1302  *
1303  * RETURN:      None
1304  *
1305  * DESCRIPTION: Simulate firing of a GPE
1306  *
1307  ******************************************************************************/
1308 
1309 void
1310 AcpiDbGenerateGpe (
1311     char                    *GpeArg,
1312     char                    *BlockArg)
1313 {
1314     UINT32                  BlockNumber = 0;
1315     UINT32                  GpeNumber;
1316     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1317 
1318 
1319     GpeNumber = strtoul (GpeArg, NULL, 0);
1320 
1321     /*
1322      * If no block arg, or block arg == 0 or 1, use the FADT-defined
1323      * GPE blocks.
1324      */
1325     if (BlockArg)
1326     {
1327         BlockNumber = strtoul (BlockArg, NULL, 0);
1328         if (BlockNumber == 1)
1329         {
1330             BlockNumber = 0;
1331         }
1332     }
1333 
1334     GpeEventInfo = AcpiEvGetGpeEventInfo (
1335         ACPI_TO_POINTER (BlockNumber), GpeNumber);
1336     if (!GpeEventInfo)
1337     {
1338         AcpiOsPrintf ("Invalid GPE\n");
1339         return;
1340     }
1341 
1342     (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
1343 }
1344 
1345 
1346 /*******************************************************************************
1347  *
1348  * FUNCTION:    AcpiDbGenerateSci
1349  *
1350  * PARAMETERS:  None
1351  *
1352  * RETURN:      None
1353  *
1354  * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
1355  *
1356  ******************************************************************************/
1357 
1358 void
1359 AcpiDbGenerateSci (
1360     void)
1361 {
1362     AcpiEvSciDispatch ();
1363 }
1364 
1365 #endif /* !ACPI_REDUCED_HARDWARE */
1366 
1367 
1368 /*******************************************************************************
1369  *
1370  * FUNCTION:    AcpiDbTrace
1371  *
1372  * PARAMETERS:  EnableArg           - ENABLE/AML to enable tracer
1373  *                                    DISABLE to disable tracer
1374  *              MethodArg           - Method to trace
1375  *              OnceArg             - Whether trace once
1376  *
1377  * RETURN:      None
1378  *
1379  * DESCRIPTION: Control method tracing facility
1380  *
1381  ******************************************************************************/
1382 
1383 void
1384 AcpiDbTrace (
1385     char                    *EnableArg,
1386     char                    *MethodArg,
1387     char                    *OnceArg)
1388 {
1389     UINT32                  DebugLevel = 0;
1390     UINT32                  DebugLayer = 0;
1391     UINT32                  Flags = 0;
1392 
1393 
1394     AcpiUtStrupr (EnableArg);
1395     AcpiUtStrupr (OnceArg);
1396 
1397     if (MethodArg)
1398     {
1399         if (AcpiDbTraceMethodName)
1400         {
1401             ACPI_FREE (AcpiDbTraceMethodName);
1402             AcpiDbTraceMethodName = NULL;
1403         }
1404 
1405         AcpiDbTraceMethodName = ACPI_ALLOCATE (strlen (MethodArg) + 1);
1406         if (!AcpiDbTraceMethodName)
1407         {
1408             AcpiOsPrintf ("Failed to allocate method name (%s)\n",
1409                 MethodArg);
1410             return;
1411         }
1412 
1413         strcpy (AcpiDbTraceMethodName, MethodArg);
1414     }
1415 
1416     if (!strcmp (EnableArg, "ENABLE") ||
1417         !strcmp (EnableArg, "METHOD") ||
1418         !strcmp (EnableArg, "OPCODE"))
1419     {
1420         if (!strcmp (EnableArg, "ENABLE"))
1421         {
1422             /* Inherit current console settings */
1423 
1424             DebugLevel = AcpiGbl_DbConsoleDebugLevel;
1425             DebugLayer = AcpiDbgLayer;
1426         }
1427         else
1428         {
1429             /* Restrict console output to trace points only */
1430 
1431             DebugLevel = ACPI_LV_TRACE_POINT;
1432             DebugLayer = ACPI_EXECUTER;
1433         }
1434 
1435         Flags = ACPI_TRACE_ENABLED;
1436 
1437         if (!strcmp (EnableArg, "OPCODE"))
1438         {
1439             Flags |= ACPI_TRACE_OPCODE;
1440         }
1441 
1442         if (OnceArg && !strcmp (OnceArg, "ONCE"))
1443         {
1444             Flags |= ACPI_TRACE_ONESHOT;
1445         }
1446     }
1447 
1448     (void) AcpiDebugTrace (AcpiDbTraceMethodName,
1449         DebugLevel, DebugLayer, Flags);
1450 }
1451