Sync ACPICA with Intel's version 20190108.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / debugger / dbcmds.c
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 - 2019, 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 "acpi.h"
153 #include "accommon.h"
154 #include "acevents.h"
155 #include "acdebug.h"
156 #include "acnamesp.h"
157 #include "acresrc.h"
158 #include "actables.h"
159
160 #ifdef ACPI_DEBUGGER
161
162 #define _COMPONENT          ACPI_CA_DEBUGGER
163         ACPI_MODULE_NAME    ("dbcmds")
164
165
166 /* Local prototypes */
167
168 static void
169 AcpiDmCompareAmlResources (
170     UINT8                   *Aml1Buffer,
171     ACPI_RSDESC_SIZE        Aml1BufferLength,
172     UINT8                   *Aml2Buffer,
173     ACPI_RSDESC_SIZE        Aml2BufferLength);
174
175 static ACPI_STATUS
176 AcpiDmTestResourceConversion (
177     ACPI_NAMESPACE_NODE     *Node,
178     char                    *Name);
179
180 static ACPI_STATUS
181 AcpiDbResourceCallback (
182     ACPI_RESOURCE           *Resource,
183     void                    *Context);
184
185 static ACPI_STATUS
186 AcpiDbDeviceResources (
187     ACPI_HANDLE             ObjHandle,
188     UINT32                  NestingLevel,
189     void                    *Context,
190     void                    **ReturnValue);
191
192 static void
193 AcpiDbDoOneSleepState (
194     UINT8                   SleepState);
195
196
197 static char                 *AcpiDbTraceMethodName = NULL;
198
199
200 /*******************************************************************************
201  *
202  * FUNCTION:    AcpiDbConvertToNode
203  *
204  * PARAMETERS:  InString            - String to convert
205  *
206  * RETURN:      Pointer to a NS node
207  *
208  * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
209  *              alphanumeric strings.
210  *
211  ******************************************************************************/
212
213 ACPI_NAMESPACE_NODE *
214 AcpiDbConvertToNode (
215     char                    *InString)
216 {
217     ACPI_NAMESPACE_NODE     *Node;
218     ACPI_SIZE               Address;
219
220
221     if ((*InString >= 0x30) && (*InString <= 0x39))
222     {
223         /* Numeric argument, convert */
224
225         Address = strtoul (InString, NULL, 16);
226         Node = ACPI_TO_POINTER (Address);
227         if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
228         {
229             AcpiOsPrintf ("Address %p is invalid", Node);
230             return (NULL);
231         }
232
233         /* Make sure pointer is valid NS node */
234
235         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
236         {
237             AcpiOsPrintf ("Address %p is not a valid namespace node [%s]\n",
238                 Node, AcpiUtGetDescriptorName (Node));
239             return (NULL);
240         }
241     }
242     else
243     {
244         /*
245          * Alpha argument: The parameter is a name string that must be
246          * resolved to a Namespace object.
247          */
248         Node = AcpiDbLocalNsLookup (InString);
249         if (!Node)
250         {
251             AcpiOsPrintf (
252                 "Could not find [%s] in namespace, defaulting to root node\n",
253                 InString);
254             Node = AcpiGbl_RootNode;
255         }
256     }
257
258     return (Node);
259 }
260
261
262 /*******************************************************************************
263  *
264  * FUNCTION:    AcpiDbSleep
265  *
266  * PARAMETERS:  ObjectArg           - Desired sleep state (0-5). NULL means
267  *                                    invoke all possible sleep states.
268  *
269  * RETURN:      Status
270  *
271  * DESCRIPTION: Simulate sleep/wake sequences
272  *
273  ******************************************************************************/
274
275 ACPI_STATUS
276 AcpiDbSleep (
277     char                    *ObjectArg)
278 {
279     UINT8                   SleepState;
280     UINT32                  i;
281
282
283     ACPI_FUNCTION_TRACE (AcpiDbSleep);
284
285
286     /* Null input (no arguments) means to invoke all sleep states */
287
288     if (!ObjectArg)
289     {
290         AcpiOsPrintf ("Invoking all possible sleep states, 0-%d\n",
291             ACPI_S_STATES_MAX);
292
293         for (i = 0; i <= ACPI_S_STATES_MAX; i++)
294         {
295             AcpiDbDoOneSleepState ((UINT8) i);
296         }
297
298         return_ACPI_STATUS (AE_OK);
299     }
300
301     /* Convert argument to binary and invoke the sleep state */
302
303     SleepState = (UINT8) strtoul (ObjectArg, NULL, 0);
304     AcpiDbDoOneSleepState (SleepState);
305     return_ACPI_STATUS (AE_OK);
306 }
307
308
309 /*******************************************************************************
310  *
311  * FUNCTION:    AcpiDbDoOneSleepState
312  *
313  * PARAMETERS:  SleepState          - Desired sleep state (0-5)
314  *
315  * RETURN:      None
316  *
317  * DESCRIPTION: Simulate a sleep/wake sequence
318  *
319  ******************************************************************************/
320
321 static void
322 AcpiDbDoOneSleepState (
323     UINT8                   SleepState)
324 {
325     ACPI_STATUS             Status;
326     UINT8                   SleepTypeA;
327     UINT8                   SleepTypeB;
328
329
330     /* Validate parameter */
331
332     if (SleepState > ACPI_S_STATES_MAX)
333     {
334         AcpiOsPrintf ("Sleep state %d out of range (%d max)\n",
335             SleepState, ACPI_S_STATES_MAX);
336         return;
337     }
338
339     AcpiOsPrintf ("\n---- Invoking sleep state S%d (%s):\n",
340         SleepState, AcpiGbl_SleepStateNames[SleepState]);
341
342     /* Get the values for the sleep type registers (for display only) */
343
344     Status = AcpiGetSleepTypeData (SleepState, &SleepTypeA, &SleepTypeB);
345     if (ACPI_FAILURE (Status))
346     {
347         AcpiOsPrintf ("Could not evaluate [%s] method, %s\n",
348             AcpiGbl_SleepStateNames[SleepState],
349             AcpiFormatException (Status));
350         return;
351     }
352
353     AcpiOsPrintf (
354         "Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
355         SleepState, SleepTypeA, SleepTypeB);
356
357     /* Invoke the various sleep/wake interfaces */
358
359     AcpiOsPrintf ("**** Sleep: Prepare to sleep (S%d) ****\n",
360         SleepState);
361     Status = AcpiEnterSleepStatePrep (SleepState);
362     if (ACPI_FAILURE (Status))
363     {
364         goto ErrorExit;
365     }
366
367     AcpiOsPrintf ("**** Sleep: Going to sleep (S%d) ****\n",
368         SleepState);
369     Status = AcpiEnterSleepState (SleepState);
370     if (ACPI_FAILURE (Status))
371     {
372         goto ErrorExit;
373     }
374
375     AcpiOsPrintf ("**** Wake: Prepare to return from sleep (S%d) ****\n",
376         SleepState);
377     Status = AcpiLeaveSleepStatePrep (SleepState);
378     if (ACPI_FAILURE (Status))
379     {
380         goto ErrorExit;
381     }
382
383     AcpiOsPrintf ("**** Wake: Return from sleep (S%d) ****\n",
384         SleepState);
385     Status = AcpiLeaveSleepState (SleepState);
386     if (ACPI_FAILURE (Status))
387     {
388         goto ErrorExit;
389     }
390
391     return;
392
393
394 ErrorExit:
395     ACPI_EXCEPTION ((AE_INFO, Status, "During invocation of sleep state S%d",
396         SleepState));
397 }
398
399
400 /*******************************************************************************
401  *
402  * FUNCTION:    AcpiDbDisplayLocks
403  *
404  * PARAMETERS:  None
405  *
406  * RETURN:      None
407  *
408  * DESCRIPTION: Display information about internal mutexes.
409  *
410  ******************************************************************************/
411
412 void
413 AcpiDbDisplayLocks (
414     void)
415 {
416     UINT32                  i;
417
418
419     for (i = 0; i < ACPI_MAX_MUTEX; i++)
420     {
421         AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
422             AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
423                 ? "Locked" : "Unlocked");
424     }
425 }
426
427
428 /*******************************************************************************
429  *
430  * FUNCTION:    AcpiDbDisplayTableInfo
431  *
432  * PARAMETERS:  TableArg            - Name of table to be displayed
433  *
434  * RETURN:      None
435  *
436  * DESCRIPTION: Display information about loaded tables. Current
437  *              implementation displays all loaded tables.
438  *
439  ******************************************************************************/
440
441 void
442 AcpiDbDisplayTableInfo (
443     char                    *TableArg)
444 {
445     UINT32                  i;
446     ACPI_TABLE_DESC         *TableDesc;
447     ACPI_STATUS             Status;
448
449
450     /* Header */
451
452     AcpiOsPrintf ("Idx ID    Status Type                    "
453         "TableHeader (Sig, Address, Length, Misc)\n");
454
455     /* Walk the entire root table list */
456
457     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
458     {
459         TableDesc = &AcpiGbl_RootTableList.Tables[i];
460
461         /* Index and Table ID */
462
463         AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId);
464
465         /* Decode the table flags */
466
467         if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED))
468         {
469             AcpiOsPrintf ("NotLoaded ");
470         }
471         else
472         {
473             AcpiOsPrintf ("   Loaded ");
474         }
475
476         switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
477         {
478         case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
479
480             AcpiOsPrintf ("External/virtual  ");
481             break;
482
483         case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
484
485             AcpiOsPrintf ("Internal/physical ");
486             break;
487
488         case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
489
490             AcpiOsPrintf ("Internal/virtual  ");
491             break;
492
493         default:
494
495             AcpiOsPrintf ("INVALID TYPE      ");
496             break;
497         }
498
499         /* Make sure that the table is mapped */
500
501         Status = AcpiTbValidateTable (TableDesc);
502         if (ACPI_FAILURE (Status))
503         {
504             return;
505         }
506
507         /* Dump the table header */
508
509         if (TableDesc->Pointer)
510         {
511             AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
512         }
513         else
514         {
515             /* If the pointer is null, the table has been unloaded */
516
517             ACPI_INFO (("%4.4s - Table has been unloaded",
518                 TableDesc->Signature.Ascii));
519         }
520     }
521 }
522
523
524 /*******************************************************************************
525  *
526  * FUNCTION:    AcpiDbUnloadAcpiTable
527  *
528  * PARAMETERS:  ObjectName          - Namespace pathname for an object that
529  *                                    is owned by the table to be unloaded
530  *
531  * RETURN:      None
532  *
533  * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
534  *              by the table.
535  *
536  ******************************************************************************/
537
538 void
539 AcpiDbUnloadAcpiTable (
540     char                    *ObjectName)
541 {
542     ACPI_NAMESPACE_NODE     *Node;
543     ACPI_STATUS             Status;
544
545
546     /* Translate name to an Named object */
547
548     Node = AcpiDbConvertToNode (ObjectName);
549     if (!Node)
550     {
551         return;
552     }
553
554     Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node));
555     if (ACPI_SUCCESS (Status))
556     {
557         AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n",
558             ObjectName, Node);
559     }
560     else
561     {
562         AcpiOsPrintf ("%s, while unloading parent table of [%s]\n",
563             AcpiFormatException (Status), ObjectName);
564     }
565 }
566
567
568 /*******************************************************************************
569  *
570  * FUNCTION:    AcpiDbSendNotify
571  *
572  * PARAMETERS:  Name                - Name of ACPI object where to send notify
573  *              Value               - Value of the notify to send.
574  *
575  * RETURN:      None
576  *
577  * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
578  *              named object as an ACPI notify.
579  *
580  ******************************************************************************/
581
582 void
583 AcpiDbSendNotify (
584     char                    *Name,
585     UINT32                  Value)
586 {
587     ACPI_NAMESPACE_NODE     *Node;
588     ACPI_STATUS             Status;
589
590
591     /* Translate name to an Named object */
592
593     Node = AcpiDbConvertToNode (Name);
594     if (!Node)
595     {
596         return;
597     }
598
599     /* Dispatch the notify if legal */
600
601     if (AcpiEvIsNotifyObject (Node))
602     {
603         Status = AcpiEvQueueNotifyRequest (Node, Value);
604         if (ACPI_FAILURE (Status))
605         {
606             AcpiOsPrintf ("Could not queue notify\n");
607         }
608     }
609     else
610     {
611         AcpiOsPrintf (
612             "Named object [%4.4s] Type %s, "
613             "must be Device/Thermal/Processor type\n",
614             AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type));
615     }
616 }
617
618
619 /*******************************************************************************
620  *
621  * FUNCTION:    AcpiDbDisplayInterfaces
622  *
623  * PARAMETERS:  ActionArg           - Null, "install", or "remove"
624  *              InterfaceNameArg    - Name for install/remove options
625  *
626  * RETURN:      None
627  *
628  * DESCRIPTION: Display or modify the global _OSI interface list
629  *
630  ******************************************************************************/
631
632 void
633 AcpiDbDisplayInterfaces (
634     char                    *ActionArg,
635     char                    *InterfaceNameArg)
636 {
637     ACPI_INTERFACE_INFO     *NextInterface;
638     char                    *SubString;
639     ACPI_STATUS             Status;
640
641
642     /* If no arguments, just display current interface list */
643
644     if (!ActionArg)
645     {
646         (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
647
648         NextInterface = AcpiGbl_SupportedInterfaces;
649         while (NextInterface)
650         {
651             if (!(NextInterface->Flags & ACPI_OSI_INVALID))
652             {
653                 AcpiOsPrintf ("%s\n", NextInterface->Name);
654             }
655
656             NextInterface = NextInterface->Next;
657         }
658
659         AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
660         return;
661     }
662
663     /* If ActionArg exists, so must InterfaceNameArg */
664
665     if (!InterfaceNameArg)
666     {
667         AcpiOsPrintf ("Missing Interface Name argument\n");
668         return;
669     }
670
671     /* Uppercase the action for match below */
672
673     AcpiUtStrupr (ActionArg);
674
675     /* Install - install an interface */
676
677     SubString = strstr ("INSTALL", ActionArg);
678     if (SubString)
679     {
680         Status = AcpiInstallInterface (InterfaceNameArg);
681         if (ACPI_FAILURE (Status))
682         {
683             AcpiOsPrintf ("%s, while installing \"%s\"\n",
684                 AcpiFormatException (Status), InterfaceNameArg);
685         }
686         return;
687     }
688
689     /* Remove - remove an interface */
690
691     SubString = strstr ("REMOVE", ActionArg);
692     if (SubString)
693     {
694         Status = AcpiRemoveInterface (InterfaceNameArg);
695         if (ACPI_FAILURE (Status))
696         {
697             AcpiOsPrintf ("%s, while removing \"%s\"\n",
698                 AcpiFormatException (Status), InterfaceNameArg);
699         }
700         return;
701     }
702
703     /* Invalid ActionArg */
704
705     AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg);
706     return;
707 }
708
709
710 /*******************************************************************************
711  *
712  * FUNCTION:    AcpiDbDisplayTemplate
713  *
714  * PARAMETERS:  BufferArg           - Buffer name or address
715  *
716  * RETURN:      None
717  *
718  * DESCRIPTION: Dump a buffer that contains a resource template
719  *
720  ******************************************************************************/
721
722 void
723 AcpiDbDisplayTemplate (
724     char                    *BufferArg)
725 {
726     ACPI_NAMESPACE_NODE     *Node;
727     ACPI_STATUS             Status;
728     ACPI_BUFFER             ReturnBuffer;
729
730
731     /* Translate BufferArg to an Named object */
732
733     Node = AcpiDbConvertToNode (BufferArg);
734     if (!Node || (Node == AcpiGbl_RootNode))
735     {
736         AcpiOsPrintf ("Invalid argument: %s\n", BufferArg);
737         return;
738     }
739
740     /* We must have a buffer object */
741
742     if (Node->Type != ACPI_TYPE_BUFFER)
743     {
744         AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n",
745             BufferArg);
746         return;
747     }
748
749     ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
750     ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
751
752     /* Attempt to convert the raw buffer to a resource list */
753
754     Status = AcpiRsCreateResourceList (Node->Object, &ReturnBuffer);
755
756     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
757     AcpiDbgLevel |= ACPI_LV_RESOURCES;
758
759     if (ACPI_FAILURE (Status))
760     {
761         AcpiOsPrintf (
762             "Could not convert Buffer to a resource list: %s, %s\n",
763             BufferArg, AcpiFormatException (Status));
764         goto DumpBuffer;
765     }
766
767     /* Now we can dump the resource list */
768
769     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
770         ReturnBuffer.Pointer));
771
772 DumpBuffer:
773     AcpiOsPrintf ("\nRaw data buffer:\n");
774     AcpiUtDebugDumpBuffer ((UINT8 *) Node->Object->Buffer.Pointer,
775         Node->Object->Buffer.Length,
776         DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
777
778     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
779     return;
780 }
781
782
783 /*******************************************************************************
784  *
785  * FUNCTION:    AcpiDmCompareAmlResources
786  *
787  * PARAMETERS:  Aml1Buffer          - Contains first resource list
788  *              Aml1BufferLength    - Length of first resource list
789  *              Aml2Buffer          - Contains second resource list
790  *              Aml2BufferLength    - Length of second resource list
791  *
792  * RETURN:      None
793  *
794  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
795  *              order to isolate a miscompare to an individual resource)
796  *
797  ******************************************************************************/
798
799 static void
800 AcpiDmCompareAmlResources (
801     UINT8                   *Aml1Buffer,
802     ACPI_RSDESC_SIZE        Aml1BufferLength,
803     UINT8                   *Aml2Buffer,
804     ACPI_RSDESC_SIZE        Aml2BufferLength)
805 {
806     UINT8                   *Aml1;
807     UINT8                   *Aml2;
808     UINT8                   *Aml1End;
809     UINT8                   *Aml2End;
810     ACPI_RSDESC_SIZE        Aml1Length;
811     ACPI_RSDESC_SIZE        Aml2Length;
812     ACPI_RSDESC_SIZE        Offset = 0;
813     UINT8                   ResourceType;
814     UINT32                  Count = 0;
815     UINT32                  i;
816
817
818     /* Compare overall buffer sizes (may be different due to size rounding) */
819
820     if (Aml1BufferLength != Aml2BufferLength)
821     {
822         AcpiOsPrintf (
823             "**** Buffer length mismatch in converted "
824             "AML: Original %X, New %X ****\n",
825             Aml1BufferLength, Aml2BufferLength);
826     }
827
828     Aml1 = Aml1Buffer;
829     Aml2 = Aml2Buffer;
830     Aml1End = Aml1Buffer + Aml1BufferLength;
831     Aml2End = Aml2Buffer + Aml2BufferLength;
832
833     /* Walk the descriptor lists, comparing each descriptor */
834
835     while ((Aml1 < Aml1End) && (Aml2 < Aml2End))
836     {
837         /* Get the lengths of each descriptor */
838
839         Aml1Length = AcpiUtGetDescriptorLength (Aml1);
840         Aml2Length = AcpiUtGetDescriptorLength (Aml2);
841         ResourceType = AcpiUtGetResourceType (Aml1);
842
843         /* Check for descriptor length match */
844
845         if (Aml1Length != Aml2Length)
846         {
847             AcpiOsPrintf (
848                 "**** Length mismatch in descriptor [%.2X] type %2.2X, "
849                 "Offset %8.8X Len1 %X, Len2 %X ****\n",
850                 Count, ResourceType, Offset, Aml1Length, Aml2Length);
851         }
852
853         /* Check for descriptor byte match */
854
855         else if (memcmp (Aml1, Aml2, Aml1Length))
856         {
857             AcpiOsPrintf (
858                 "**** Data mismatch in descriptor [%.2X] type %2.2X, "
859                 "Offset %8.8X ****\n",
860                 Count, ResourceType, Offset);
861
862             for (i = 0; i < Aml1Length; i++)
863             {
864                 if (Aml1[i] != Aml2[i])
865                 {
866                     AcpiOsPrintf (
867                         "Mismatch at byte offset %.2X: is %2.2X, "
868                         "should be %2.2X\n",
869                         i, Aml2[i], Aml1[i]);
870                 }
871             }
872         }
873
874         /* Exit on EndTag descriptor */
875
876         if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
877         {
878             return;
879         }
880
881         /* Point to next descriptor in each buffer */
882
883         Count++;
884         Offset += Aml1Length;
885         Aml1 += Aml1Length;
886         Aml2 += Aml2Length;
887     }
888 }
889
890
891 /*******************************************************************************
892  *
893  * FUNCTION:    AcpiDmTestResourceConversion
894  *
895  * PARAMETERS:  Node                - Parent device node
896  *              Name                - resource method name (_CRS)
897  *
898  * RETURN:      Status
899  *
900  * DESCRIPTION: Compare the original AML with a conversion of the AML to
901  *              internal resource list, then back to AML.
902  *
903  ******************************************************************************/
904
905 static ACPI_STATUS
906 AcpiDmTestResourceConversion (
907     ACPI_NAMESPACE_NODE     *Node,
908     char                    *Name)
909 {
910     ACPI_STATUS             Status;
911     ACPI_BUFFER             ReturnBuffer;
912     ACPI_BUFFER             ResourceBuffer;
913     ACPI_BUFFER             NewAml;
914     ACPI_OBJECT             *OriginalAml;
915
916
917     AcpiOsPrintf ("Resource Conversion Comparison:\n");
918
919     NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
920     ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
921     ResourceBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
922
923     /* Get the original _CRS AML resource template */
924
925     Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnBuffer);
926     if (ACPI_FAILURE (Status))
927     {
928         AcpiOsPrintf ("Could not obtain %s: %s\n",
929             Name, AcpiFormatException (Status));
930         return (Status);
931     }
932
933     /* Get the AML resource template, converted to internal resource structs */
934
935     Status = AcpiGetCurrentResources (Node, &ResourceBuffer);
936     if (ACPI_FAILURE (Status))
937     {
938         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
939             AcpiFormatException (Status));
940         goto Exit1;
941     }
942
943     /* Convert internal resource list to external AML resource template */
944
945     Status = AcpiRsCreateAmlResources (&ResourceBuffer, &NewAml);
946     if (ACPI_FAILURE (Status))
947     {
948         AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
949             AcpiFormatException (Status));
950         goto Exit2;
951     }
952
953     /* Compare original AML to the newly created AML resource list */
954
955     OriginalAml = ReturnBuffer.Pointer;
956
957     AcpiDmCompareAmlResources (OriginalAml->Buffer.Pointer,
958         (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
959         NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
960
961     /* Cleanup and exit */
962
963     ACPI_FREE (NewAml.Pointer);
964 Exit2:
965     ACPI_FREE (ResourceBuffer.Pointer);
966 Exit1:
967     ACPI_FREE (ReturnBuffer.Pointer);
968     return (Status);
969 }
970
971
972 /*******************************************************************************
973  *
974  * FUNCTION:    AcpiDbResourceCallback
975  *
976  * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
977  *
978  * RETURN:      Status
979  *
980  * DESCRIPTION: Simple callback to exercise AcpiWalkResources and
981  *              AcpiWalkResourceBuffer.
982  *
983  ******************************************************************************/
984
985 static ACPI_STATUS
986 AcpiDbResourceCallback (
987     ACPI_RESOURCE           *Resource,
988     void                    *Context)
989 {
990
991     return (AE_OK);
992 }
993
994
995 /*******************************************************************************
996  *
997  * FUNCTION:    AcpiDbDeviceResources
998  *
999  * PARAMETERS:  ACPI_WALK_CALLBACK
1000  *
1001  * RETURN:      Status
1002  *
1003  * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
1004  *
1005  ******************************************************************************/
1006
1007 static ACPI_STATUS
1008 AcpiDbDeviceResources (
1009     ACPI_HANDLE             ObjHandle,
1010     UINT32                  NestingLevel,
1011     void                    *Context,
1012     void                    **ReturnValue)
1013 {
1014     ACPI_NAMESPACE_NODE     *Node;
1015     ACPI_NAMESPACE_NODE     *PrtNode = NULL;
1016     ACPI_NAMESPACE_NODE     *CrsNode = NULL;
1017     ACPI_NAMESPACE_NODE     *PrsNode = NULL;
1018     ACPI_NAMESPACE_NODE     *AeiNode = NULL;
1019     char                    *ParentPath;
1020     ACPI_BUFFER             ReturnBuffer;
1021     ACPI_STATUS             Status;
1022
1023
1024     Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
1025     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
1026     if (!ParentPath)
1027     {
1028         return (AE_NO_MEMORY);
1029     }
1030
1031     /* Get handles to the resource methods for this device */
1032
1033     (void) AcpiGetHandle (Node, METHOD_NAME__PRT,
1034         ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode));
1035     (void) AcpiGetHandle (Node, METHOD_NAME__CRS,
1036         ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode));
1037     (void) AcpiGetHandle (Node, METHOD_NAME__PRS,
1038         ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode));
1039     (void) AcpiGetHandle (Node, METHOD_NAME__AEI,
1040         ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode));
1041
1042     if (!PrtNode && !CrsNode && !PrsNode && !AeiNode)
1043     {
1044         goto Cleanup;   /* Nothing to do */
1045     }
1046
1047     AcpiOsPrintf ("\nDevice: %s\n", ParentPath);
1048
1049     /* Prepare for a return object of arbitrary size */
1050
1051     ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1052     ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1053
1054
1055     /* _PRT */
1056
1057     if (PrtNode)
1058     {
1059         AcpiOsPrintf ("Evaluating _PRT\n");
1060
1061         Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnBuffer);
1062         if (ACPI_FAILURE (Status))
1063         {
1064             AcpiOsPrintf ("Could not evaluate _PRT: %s\n",
1065                 AcpiFormatException (Status));
1066             goto GetCrs;
1067         }
1068
1069         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1070         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1071
1072         Status = AcpiGetIrqRoutingTable (Node, &ReturnBuffer);
1073         if (ACPI_FAILURE (Status))
1074         {
1075             AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1076                 AcpiFormatException (Status));
1077             goto GetCrs;
1078         }
1079
1080         AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1081     }
1082
1083
1084     /* _CRS */
1085
1086 GetCrs:
1087     if (CrsNode)
1088     {
1089         AcpiOsPrintf ("Evaluating _CRS\n");
1090
1091         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1092         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1093
1094         Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnBuffer);
1095         if (ACPI_FAILURE (Status))
1096         {
1097             AcpiOsPrintf ("Could not evaluate _CRS: %s\n",
1098                 AcpiFormatException (Status));
1099             goto GetPrs;
1100         }
1101
1102         /* This code exercises the AcpiWalkResources interface */
1103
1104         Status = AcpiWalkResources (Node, METHOD_NAME__CRS,
1105             AcpiDbResourceCallback, NULL);
1106         if (ACPI_FAILURE (Status))
1107         {
1108             AcpiOsPrintf ("AcpiWalkResources failed: %s\n",
1109                 AcpiFormatException (Status));
1110             goto GetPrs;
1111         }
1112
1113         /* Get the _CRS resource list (test ALLOCATE buffer) */
1114
1115         ReturnBuffer.Pointer = NULL;
1116         ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1117
1118         Status = AcpiGetCurrentResources (Node, &ReturnBuffer);
1119         if (ACPI_FAILURE (Status))
1120         {
1121             AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1122                 AcpiFormatException (Status));
1123             goto GetPrs;
1124         }
1125
1126         /* This code exercises the AcpiWalkResourceBuffer interface */
1127
1128         Status = AcpiWalkResourceBuffer (&ReturnBuffer,
1129             AcpiDbResourceCallback, NULL);
1130         if (ACPI_FAILURE (Status))
1131         {
1132             AcpiOsPrintf ("AcpiWalkResourceBuffer failed: %s\n",
1133                 AcpiFormatException (Status));
1134             goto EndCrs;
1135         }
1136
1137         /* Dump the _CRS resource list */
1138
1139         AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1140             ReturnBuffer.Pointer));
1141
1142         /*
1143          * Perform comparison of original AML to newly created AML. This
1144          * tests both the AML->Resource conversion and the Resource->AML
1145          * conversion.
1146          */
1147         (void) AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1148
1149         /* Execute _SRS with the resource list */
1150
1151         AcpiOsPrintf ("Evaluating _SRS\n");
1152
1153         Status = AcpiSetCurrentResources (Node, &ReturnBuffer);
1154         if (ACPI_FAILURE (Status))
1155         {
1156             AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1157                 AcpiFormatException (Status));
1158             goto EndCrs;
1159         }
1160
1161 EndCrs:
1162         ACPI_FREE (ReturnBuffer.Pointer);
1163     }
1164
1165
1166     /* _PRS */
1167
1168 GetPrs:
1169     if (PrsNode)
1170     {
1171         AcpiOsPrintf ("Evaluating _PRS\n");
1172
1173         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1174         ReturnBuffer.Length  = ACPI_DEBUG_BUFFER_SIZE;
1175
1176         Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnBuffer);
1177         if (ACPI_FAILURE (Status))
1178         {
1179             AcpiOsPrintf ("Could not evaluate _PRS: %s\n",
1180                 AcpiFormatException (Status));
1181             goto GetAei;
1182         }
1183
1184         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1185         ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
1186
1187         Status = AcpiGetPossibleResources (Node, &ReturnBuffer);
1188         if (ACPI_FAILURE (Status))
1189         {
1190             AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1191                 AcpiFormatException (Status));
1192             goto GetAei;
1193         }
1194
1195         AcpiRsDumpResourceList (ACPI_CAST_PTR (
1196             ACPI_RESOURCE, AcpiGbl_DbBuffer));
1197     }
1198
1199
1200     /* _AEI */
1201
1202 GetAei:
1203     if (AeiNode)
1204     {
1205         AcpiOsPrintf ("Evaluating _AEI\n");
1206
1207         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1208         ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
1209
1210         Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnBuffer);
1211         if (ACPI_FAILURE (Status))
1212         {
1213             AcpiOsPrintf ("Could not evaluate _AEI: %s\n",
1214                 AcpiFormatException (Status));
1215             goto Cleanup;
1216         }
1217
1218         ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
1219         ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
1220
1221         Status = AcpiGetEventResources (Node, &ReturnBuffer);
1222         if (ACPI_FAILURE (Status))
1223         {
1224             AcpiOsPrintf ("AcpiGetEventResources failed: %s\n",
1225                 AcpiFormatException (Status));
1226             goto Cleanup;
1227         }
1228
1229         AcpiRsDumpResourceList (ACPI_CAST_PTR (
1230             ACPI_RESOURCE, AcpiGbl_DbBuffer));
1231     }
1232
1233
1234 Cleanup:
1235     ACPI_FREE (ParentPath);
1236     return (AE_OK);
1237 }
1238
1239
1240 /*******************************************************************************
1241  *
1242  * FUNCTION:    AcpiDbDisplayResources
1243  *
1244  * PARAMETERS:  ObjectArg           - String object name or object pointer.
1245  *                                    NULL or "*" means "display resources for
1246  *                                    all devices"
1247  *
1248  * RETURN:      None
1249  *
1250  * DESCRIPTION: Display the resource objects associated with a device.
1251  *
1252  ******************************************************************************/
1253
1254 void
1255 AcpiDbDisplayResources (
1256     char                    *ObjectArg)
1257 {
1258     ACPI_NAMESPACE_NODE     *Node;
1259
1260
1261     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1262     AcpiDbgLevel |= ACPI_LV_RESOURCES;
1263
1264     /* Asterisk means "display resources for all devices" */
1265
1266     if (!ObjectArg || (!strcmp (ObjectArg, "*")))
1267     {
1268         (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1269             ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL);
1270     }
1271     else
1272     {
1273         /* Convert string to object pointer */
1274
1275         Node = AcpiDbConvertToNode (ObjectArg);
1276         if (Node)
1277         {
1278             if (Node->Type != ACPI_TYPE_DEVICE)
1279             {
1280                 AcpiOsPrintf (
1281                     "%4.4s: Name is not a device object (%s)\n",
1282                     Node->Name.Ascii, AcpiUtGetTypeName (Node->Type));
1283             }
1284             else
1285             {
1286                 (void) AcpiDbDeviceResources (Node, 0, NULL, NULL);
1287             }
1288         }
1289     }
1290
1291     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1292 }
1293
1294
1295 #if (!ACPI_REDUCED_HARDWARE)
1296 /*******************************************************************************
1297  *
1298  * FUNCTION:    AcpiDbGenerateGpe
1299  *
1300  * PARAMETERS:  GpeArg              - Raw GPE number, ascii string
1301  *              BlockArg            - GPE block number, ascii string
1302  *                                    0 or 1 for FADT GPE blocks
1303  *
1304  * RETURN:      None
1305  *
1306  * DESCRIPTION: Simulate firing of a GPE
1307  *
1308  ******************************************************************************/
1309
1310 void
1311 AcpiDbGenerateGpe (
1312     char                    *GpeArg,
1313     char                    *BlockArg)
1314 {
1315     UINT32                  BlockNumber = 0;
1316     UINT32                  GpeNumber;
1317     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1318
1319
1320     GpeNumber = strtoul (GpeArg, NULL, 0);
1321
1322     /*
1323      * If no block arg, or block arg == 0 or 1, use the FADT-defined
1324      * GPE blocks.
1325      */
1326     if (BlockArg)
1327     {
1328         BlockNumber = strtoul (BlockArg, NULL, 0);
1329         if (BlockNumber == 1)
1330         {
1331             BlockNumber = 0;
1332         }
1333     }
1334
1335     GpeEventInfo = AcpiEvGetGpeEventInfo (
1336         ACPI_TO_POINTER (BlockNumber), GpeNumber);
1337     if (!GpeEventInfo)
1338     {
1339         AcpiOsPrintf ("Invalid GPE\n");
1340         return;
1341     }
1342
1343     (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
1344 }
1345
1346
1347 /*******************************************************************************
1348  *
1349  * FUNCTION:    AcpiDbGenerateSci
1350  *
1351  * PARAMETERS:  None
1352  *
1353  * RETURN:      None
1354  *
1355  * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
1356  *
1357  ******************************************************************************/
1358
1359 void
1360 AcpiDbGenerateSci (
1361     void)
1362 {
1363     AcpiEvSciDispatch ();
1364 }
1365
1366 #endif /* !ACPI_REDUCED_HARDWARE */
1367
1368
1369 /*******************************************************************************
1370  *
1371  * FUNCTION:    AcpiDbTrace
1372  *
1373  * PARAMETERS:  EnableArg           - ENABLE/AML to enable tracer
1374  *                                    DISABLE to disable tracer
1375  *              MethodArg           - Method to trace
1376  *              OnceArg             - Whether trace once
1377  *
1378  * RETURN:      None
1379  *
1380  * DESCRIPTION: Control method tracing facility
1381  *
1382  ******************************************************************************/
1383
1384 void
1385 AcpiDbTrace (
1386     char                    *EnableArg,
1387     char                    *MethodArg,
1388     char                    *OnceArg)
1389 {
1390     UINT32                  DebugLevel = 0;
1391     UINT32                  DebugLayer = 0;
1392     UINT32                  Flags = 0;
1393
1394
1395     AcpiUtStrupr (EnableArg);
1396     AcpiUtStrupr (OnceArg);
1397
1398     if (MethodArg)
1399     {
1400         if (AcpiDbTraceMethodName)
1401         {
1402             ACPI_FREE (AcpiDbTraceMethodName);
1403             AcpiDbTraceMethodName = NULL;
1404         }
1405
1406         AcpiDbTraceMethodName = ACPI_ALLOCATE (strlen (MethodArg) + 1);
1407         if (!AcpiDbTraceMethodName)
1408         {
1409             AcpiOsPrintf ("Failed to allocate method name (%s)\n",
1410                 MethodArg);
1411             return;
1412         }
1413
1414         strcpy (AcpiDbTraceMethodName, MethodArg);
1415     }
1416
1417     if (!strcmp (EnableArg, "ENABLE") ||
1418         !strcmp (EnableArg, "METHOD") ||
1419         !strcmp (EnableArg, "OPCODE"))
1420     {
1421         if (!strcmp (EnableArg, "ENABLE"))
1422         {
1423             /* Inherit current console settings */
1424
1425             DebugLevel = AcpiGbl_DbConsoleDebugLevel;
1426             DebugLayer = AcpiDbgLayer;
1427         }
1428         else
1429         {
1430             /* Restrict console output to trace points only */
1431
1432             DebugLevel = ACPI_LV_TRACE_POINT;
1433             DebugLayer = ACPI_EXECUTER;
1434         }
1435
1436         Flags = ACPI_TRACE_ENABLED;
1437
1438         if (!strcmp (EnableArg, "OPCODE"))
1439         {
1440             Flags |= ACPI_TRACE_OPCODE;
1441         }
1442
1443         if (OnceArg && !strcmp (OnceArg, "ONCE"))
1444         {
1445             Flags |= ACPI_TRACE_ONESHOT;
1446         }
1447     }
1448
1449     (void) AcpiDebugTrace (AcpiDbTraceMethodName,
1450         DebugLevel, DebugLayer, Flags);
1451 }
1452
1453 #endif /* ACPI_DEBUGGER */