Use __DECONST to silence GCC. Make some private routines static.
[dragonfly.git] / sys / contrib / dev / acpica / dbxface.c
1 /*******************************************************************************
2  *
3  * Module Name: dbxface - AML Debugger external interfaces
4  *              $Revision: 70 $
5  *
6  ******************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116 /* $DragonFly: src/sys/contrib/dev/acpica/Attic/dbxface.c,v 1.1 2003/09/24 03:32:15 drhodus Exp $                                                               */
117
118 #include "acpi.h"
119 #include "amlcode.h"
120 #include "acdebug.h"
121 #include "acdisasm.h"
122
123
124 #ifdef ACPI_DEBUGGER
125
126 #define _COMPONENT          ACPI_CA_DEBUGGER
127         ACPI_MODULE_NAME    ("dbxface")
128
129
130 /*******************************************************************************
131  *
132  * FUNCTION:    AcpiDbStartCommand
133  *
134  * PARAMETERS:  WalkState       - Current walk
135  *
136  * RETURN:      Status
137  *
138  * DESCRIPTION: Enter debugger command loop
139  *
140  ******************************************************************************/
141
142 ACPI_STATUS
143 AcpiDbStartCommand (
144     ACPI_WALK_STATE         *WalkState,
145     ACPI_PARSE_OBJECT       *Op)
146 {
147     ACPI_STATUS             Status;
148
149
150     /* TBD: [Investigate] what are the namespace locking issues here */
151
152     /* AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); */
153
154     /* Go into the command loop and await next user command */
155
156
157     AcpiGbl_MethodExecuting = TRUE;
158     Status = AE_CTRL_TRUE;
159     while (Status == AE_CTRL_TRUE)
160     {
161         if (AcpiGbl_DebuggerConfiguration == DEBUGGER_MULTI_THREADED)
162         {
163             /* Handshake with the front-end that gets user command lines */
164
165             Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
166             if (ACPI_FAILURE (Status))
167             {
168                 return (Status);
169             }
170             Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
171             if (ACPI_FAILURE (Status))
172             {
173                 return (Status);
174             }
175         }
176         else
177         {
178             /* Single threaded, we must get a command line ourselves */
179
180             /* Force output to console until a command is entered */
181
182             AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
183
184             /* Different prompt if method is executing */
185
186             if (!AcpiGbl_MethodExecuting)
187             {
188                 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
189             }
190             else
191             {
192                 AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
193             }
194
195             /* Get the user input line */
196
197             (void) AcpiOsGetLine (AcpiGbl_DbLineBuf);
198         }
199
200         Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, WalkState, Op);
201     }
202
203     /* AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); */
204
205     return (Status);
206 }
207
208
209 /*******************************************************************************
210  *
211  * FUNCTION:    AcpiDbMethodEnd
212  *
213  * PARAMETERS:  WalkState       - Current walk
214  *
215  * RETURN:      Status
216  *
217  * DESCRIPTION:
218  *
219  ******************************************************************************/
220
221 void
222 AcpiDbMethodEnd (
223     ACPI_WALK_STATE         *WalkState)
224 {
225
226     if (!AcpiGbl_CmSingleStep)
227     {
228         return;
229     }
230
231     AcpiOsPrintf ("<Method Terminating>\n");
232
233     AcpiDbStartCommand (WalkState, NULL);
234 }
235
236
237 /*******************************************************************************
238  *
239  * FUNCTION:    AcpiDbSingleStep
240  *
241  * PARAMETERS:  WalkState       - Current walk
242  *              Op              - Current executing op
243  *              OpcodeClass     - Class of the current AML Opcode
244  *
245  * RETURN:      Status
246  *
247  * DESCRIPTION: Called just before execution of an AML opcode.
248  *
249  ******************************************************************************/
250
251 ACPI_STATUS
252 AcpiDbSingleStep (
253     ACPI_WALK_STATE         *WalkState,
254     ACPI_PARSE_OBJECT       *Op,
255     UINT32                  OpcodeClass)
256 {
257     ACPI_PARSE_OBJECT       *Next;
258     ACPI_STATUS             Status = AE_OK;
259     UINT32                  OriginalDebugLevel;
260     ACPI_PARSE_OBJECT       *DisplayOp;
261     ACPI_PARSE_OBJECT       *ParentOp;
262
263
264     ACPI_FUNCTION_ENTRY ();
265
266
267     /* Check the abort flag */
268
269     if (AcpiGbl_AbortMethod)
270     {
271         AcpiGbl_AbortMethod = FALSE;
272         return (AE_ABORT_METHOD);
273     }
274
275     /* Check for single-step breakpoint */
276
277     if (WalkState->MethodBreakpoint &&
278        (WalkState->MethodBreakpoint <= Op->Common.AmlOffset))
279     {
280         /* Check if the breakpoint has been reached or passed */
281         /* Hit the breakpoint, resume single step, reset breakpoint */
282
283         AcpiOsPrintf ("***Break*** at AML offset %X\n", Op->Common.AmlOffset);
284         AcpiGbl_CmSingleStep = TRUE;
285         AcpiGbl_StepToNextCall = FALSE;
286         WalkState->MethodBreakpoint = 0;
287     }
288
289     /* Check for user breakpoint (Must be on exact Aml offset) */
290
291     else if (WalkState->UserBreakpoint &&
292             (WalkState->UserBreakpoint == Op->Common.AmlOffset))
293     {
294         AcpiOsPrintf ("***UserBreakpoint*** at AML offset %X\n", Op->Common.AmlOffset);
295         AcpiGbl_CmSingleStep = TRUE;
296         AcpiGbl_StepToNextCall = FALSE;
297         WalkState->MethodBreakpoint = 0;
298     }
299
300     /*
301      * Check if this is an opcode that we are interested in --
302      * namely, opcodes that have arguments
303      */
304     if (Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
305     {
306         return (AE_OK);
307     }
308
309     switch (OpcodeClass)
310     {
311     case AML_CLASS_UNKNOWN:
312     case AML_CLASS_ARGUMENT:    /* constants, literals, etc.  do nothing */
313         return (AE_OK);
314
315     default:
316         /* All other opcodes -- continue */
317         break;
318     }
319
320     /*
321      * Under certain debug conditions, display this opcode and its operands
322      */
323     if ((AcpiGbl_DbOutputToFile)            ||
324         (AcpiGbl_CmSingleStep)              ||
325         (AcpiDbgLevel & ACPI_LV_PARSE))
326     {
327         if ((AcpiGbl_DbOutputToFile)        ||
328             (AcpiDbgLevel & ACPI_LV_PARSE))
329         {
330             AcpiOsPrintf ("\n[AmlDebug] Next AML Opcode to execute:\n");
331         }
332
333         /*
334          * Display this op (and only this op - zero out the NEXT field temporarily,
335          * and disable parser trace output for the duration of the display because
336          * we don't want the extraneous debug output)
337          */
338         OriginalDebugLevel = AcpiDbgLevel;
339         AcpiDbgLevel &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
340         Next = Op->Common.Next;
341         Op->Common.Next = NULL;
342
343
344         DisplayOp = Op;
345         ParentOp = Op->Common.Parent;
346         if (ParentOp)
347         {
348             if ((WalkState->ControlState) &&
349                 (WalkState->ControlState->Common.State == ACPI_CONTROL_PREDICATE_EXECUTING))
350             {
351                 /*
352                  * We are executing the predicate of an IF or WHILE statement
353                  * Search upwards for the containing IF or WHILE so that the
354                  * entire predicate can be displayed.
355                  */
356                 while (ParentOp)
357                 {
358                     if ((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
359                         (ParentOp->Common.AmlOpcode == AML_WHILE_OP))
360                     {
361                         DisplayOp = ParentOp;
362                         break;
363                     }
364                     ParentOp = ParentOp->Common.Parent;
365                 }
366             }
367             else
368             {
369                 while (ParentOp)
370                 {
371                     if ((ParentOp->Common.AmlOpcode == AML_IF_OP)     ||
372                         (ParentOp->Common.AmlOpcode == AML_ELSE_OP)   ||
373                         (ParentOp->Common.AmlOpcode == AML_SCOPE_OP)  ||
374                         (ParentOp->Common.AmlOpcode == AML_METHOD_OP) ||
375                         (ParentOp->Common.AmlOpcode == AML_WHILE_OP))
376                     {
377                         break;
378                     }
379                     DisplayOp = ParentOp;
380                     ParentOp = ParentOp->Common.Parent;
381                 }
382             }
383         }
384
385         /* Now we can display it */
386
387 #ifdef ACPI_DISASSEMBLER
388         AcpiDmDisassemble (WalkState, DisplayOp, ACPI_UINT32_MAX);
389 #endif
390
391         if ((Op->Common.AmlOpcode == AML_IF_OP) ||
392             (Op->Common.AmlOpcode == AML_WHILE_OP))
393         {
394             if (WalkState->ControlState->Common.Value)
395             {
396                 AcpiOsPrintf ("Predicate = [True], IF block was executed\n");
397             }
398             else
399             {
400                 AcpiOsPrintf ("Predicate = [False], Skipping IF block\n");
401             }
402         }
403         else if (Op->Common.AmlOpcode == AML_ELSE_OP)
404         {
405             AcpiOsPrintf ("Predicate = [False], ELSE block was executed\n");
406         }
407
408         /* Restore everything */
409
410         Op->Common.Next = Next;
411         AcpiOsPrintf ("\n");
412         if ((AcpiGbl_DbOutputToFile)        ||
413             (AcpiDbgLevel & ACPI_LV_PARSE))
414         {
415             AcpiOsPrintf ("\n");
416         }
417         AcpiDbgLevel = OriginalDebugLevel;
418     }
419
420     /* If we are not single stepping, just continue executing the method */
421
422     if (!AcpiGbl_CmSingleStep)
423     {
424         return (AE_OK);
425     }
426
427     /*
428      * If we are executing a step-to-call command,
429      * Check if this is a method call.
430      */
431     if (AcpiGbl_StepToNextCall)
432     {
433         if (Op->Common.AmlOpcode != AML_INT_METHODCALL_OP)
434         {
435             /* Not a method call, just keep executing */
436
437             return (AE_OK);
438         }
439
440         /* Found a method call, stop executing */
441
442         AcpiGbl_StepToNextCall = FALSE;
443     }
444
445     /*
446      * If the next opcode is a method call, we will "step over" it
447      * by default.
448      */
449     if (Op->Common.AmlOpcode == AML_INT_METHODCALL_OP)
450     {
451         AcpiGbl_CmSingleStep = FALSE;  /* No more single step while executing called method */
452
453         /* Set the breakpoint on/before the call, it will stop execution as soon as we return */
454
455         WalkState->MethodBreakpoint = 1;  /* Must be non-zero! */
456     }
457
458
459     Status = AcpiDbStartCommand (WalkState, Op);
460
461     /* User commands complete, continue execution of the interrupted method */
462
463     return (Status);
464 }
465
466
467 /*******************************************************************************
468  *
469  * FUNCTION:    AcpiDbInitialize
470  *
471  * PARAMETERS:  None
472  *
473  * RETURN:      Status
474  *
475  * DESCRIPTION: Init and start debugger
476  *
477  ******************************************************************************/
478
479 ACPI_STATUS
480 AcpiDbInitialize (void)
481 {
482     ACPI_STATUS             Status;
483
484
485     /* Init globals */
486
487     AcpiGbl_DbBuffer            = NULL;
488     AcpiGbl_DbFilename          = NULL;
489     AcpiGbl_DbOutputToFile      = FALSE;
490
491     AcpiGbl_DbDebugLevel        = ACPI_LV_VERBOSITY2;
492     AcpiGbl_DbConsoleDebugLevel = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES;
493     AcpiGbl_DbOutputFlags       = ACPI_DB_CONSOLE_OUTPUT;
494
495     AcpiGbl_DbOpt_tables        = FALSE;
496     AcpiGbl_DbOpt_stats         = FALSE;
497 #ifdef ACPI_DISASSEMBLER
498     AcpiGbl_DbOpt_disasm        = FALSE;
499     AcpiGbl_DbOpt_verbose       = TRUE;
500 #endif
501     AcpiGbl_DbOpt_ini_methods   = TRUE;
502
503     AcpiGbl_DbBuffer = AcpiOsAllocate (ACPI_DEBUG_BUFFER_SIZE);
504     if (!AcpiGbl_DbBuffer)
505     {
506         return (AE_NO_MEMORY);
507     }
508     ACPI_MEMSET (AcpiGbl_DbBuffer, 0, ACPI_DEBUG_BUFFER_SIZE);
509
510     /* Initial scope is the root */
511
512     AcpiGbl_DbScopeBuf [0] = '\\';
513     AcpiGbl_DbScopeBuf [1] =  0;
514     AcpiGbl_DbScopeNode = AcpiGbl_RootNode;
515
516     /*
517      * If configured for multi-thread support, the debug executor runs in
518      * a separate thread so that the front end can be in another address
519      * space, environment, or even another machine.
520      */
521     if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
522     {
523         /* These were created with one unit, grab it */
524
525         Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
526         if (ACPI_FAILURE (Status))
527         {
528             AcpiOsPrintf ("Could not get debugger mutex\n");
529             return (Status);
530         }
531
532         Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
533         if (ACPI_FAILURE (Status))
534         {
535             AcpiOsPrintf ("Could not get debugger mutex\n");
536             return (Status);
537         }
538
539         /* Create the debug execution thread to execute commands */
540
541         Status = AcpiOsQueueForExecution (0, AcpiDbExecuteThread, NULL);
542         if (ACPI_FAILURE (Status))
543         {
544             AcpiOsPrintf ("Could not start debugger thread\n");
545             return (Status);
546         }
547     }
548
549 #ifdef ACPI_DISASSEMBLER
550     if (!AcpiGbl_DbOpt_verbose)
551     {
552         AcpiGbl_DbOpt_disasm = TRUE;
553         AcpiGbl_DbOpt_stats = FALSE;
554     }
555 #endif
556
557     return (AE_OK);
558 }
559
560
561 /*******************************************************************************
562  *
563  * FUNCTION:    AcpiDbTerminate
564  *
565  * PARAMETERS:  None
566  *
567  * RETURN:      Status
568  *
569  * DESCRIPTION: Stop debugger
570  *
571  ******************************************************************************/
572
573 void
574 AcpiDbTerminate (void)
575 {
576
577     if (AcpiGbl_DbTablePtr)
578     {
579         AcpiOsFree (AcpiGbl_DbTablePtr);
580     }
581     if (AcpiGbl_DbBuffer)
582     {
583         AcpiOsFree (AcpiGbl_DbBuffer);
584     }
585 }
586
587
588 #endif /* ACPI_DEBUGGER */