xref: /dflybsd-src/sys/contrib/dev/acpica/source/components/debugger/dbcmds.c (revision e4adeac153e9f588eff22befbf196d2fd3444bc3)
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 - 2021, 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 */
1454