]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/dbexec.c
Vendor import of the Intel ACPI CA 20021118 drop.
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / dbexec.c
1 /*******************************************************************************
2  *
3  * Module Name: dbexec - debugger control method execution
4  *              $Revision: 46 $
5  *
6  ******************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2002, 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
117
118 #include "acpi.h"
119 #include "acdebug.h"
120
121 #ifdef ACPI_DEBUGGER
122
123 #define _COMPONENT          ACPI_CA_DEBUGGER
124         ACPI_MODULE_NAME    ("dbexec")
125
126
127 static ACPI_DB_METHOD_INFO  AcpiGbl_DbMethodInfo;
128
129
130 /*******************************************************************************
131  *
132  * FUNCTION:    AcpiDbExecuteMethod
133  *
134  * PARAMETERS:  Info            - Valid info segment
135  *              ReturnObj       - Where to put return object
136  *
137  * RETURN:      Status
138  *
139  * DESCRIPTION: Execute a control method.
140  *
141  ******************************************************************************/
142
143 ACPI_STATUS
144 AcpiDbExecuteMethod (
145     ACPI_DB_METHOD_INFO     *Info,
146     ACPI_BUFFER             *ReturnObj)
147 {
148     ACPI_STATUS             Status;
149     ACPI_OBJECT_LIST        ParamObjects;
150     ACPI_OBJECT             Params[MTH_NUM_ARGS];
151     UINT32                  i;
152
153
154     if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel)
155     {
156         AcpiOsPrintf ("Warning: debug output is not enabled!\n");
157     }
158
159     /* Are there arguments to the method? */
160
161     if (Info->Args && Info->Args[0])
162     {
163         for (i = 0; Info->Args[i] && i < MTH_NUM_ARGS; i++)
164         {
165             Params[i].Type              = ACPI_TYPE_INTEGER;
166             Params[i].Integer.Value     = ACPI_STRTOUL (Info->Args[i], NULL, 16);
167         }
168
169         ParamObjects.Pointer        = Params;
170         ParamObjects.Count          = i;
171     }
172     else
173     {
174         /* Setup default parameters */
175
176         Params[0].Type              = ACPI_TYPE_INTEGER;
177         Params[0].Integer.Value     = 0x01020304;
178
179         Params[1].Type              = ACPI_TYPE_STRING;
180         Params[1].String.Length     = 12;
181         Params[1].String.Pointer    = "AML Debugger";
182
183         ParamObjects.Pointer        = Params;
184         ParamObjects.Count          = 2;
185     }
186
187     /* Prepare for a return object of arbitrary size */
188
189     ReturnObj->Pointer           = AcpiGbl_DbBuffer;
190     ReturnObj->Length            = ACPI_DEBUG_BUFFER_SIZE;
191
192     /* Do the actual method execution */
193
194     Status = AcpiEvaluateObject (NULL, Info->Pathname, &ParamObjects, ReturnObj);
195
196     AcpiGbl_CmSingleStep = FALSE;
197     AcpiGbl_MethodExecuting = FALSE;
198
199     return (Status);
200 }
201
202
203 /*******************************************************************************
204  *
205  * FUNCTION:    AcpiDbExecuteSetup
206  *
207  * PARAMETERS:  Info            - Valid method info
208  *
209  * RETURN:      Status
210  *
211  * DESCRIPTION: Setup info segment prior to method execution
212  *
213  ******************************************************************************/
214
215 void
216 AcpiDbExecuteSetup (
217     ACPI_DB_METHOD_INFO     *Info)
218 {
219
220     /* Catenate the current scope to the supplied name */
221
222     Info->Pathname[0] = 0;
223     if ((Info->Name[0] != '\\') &&
224         (Info->Name[0] != '/'))
225     {
226         ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf);
227     }
228
229     ACPI_STRCAT (Info->Pathname, Info->Name);
230     AcpiDbPrepNamestring (Info->Pathname);
231
232     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
233     AcpiOsPrintf ("Executing %s\n", Info->Pathname);
234
235     if (Info->Flags & EX_SINGLE_STEP)
236     {
237         AcpiGbl_CmSingleStep = TRUE;
238         AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
239     }
240
241     else
242     {
243         /* No single step, allow redirection to a file */
244
245         AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
246     }
247 }
248
249
250 /*******************************************************************************
251  *
252  * FUNCTION:    AcpiDbGetOutstandingAllocations
253  *
254  * PARAMETERS:  None
255  *
256  * RETURN:      Current global allocation count minus cache entries
257  *
258  * DESCRIPTION: Determine the current number of "outstanding" allocations --
259  *              those allocations that have not been freed and also are not
260  *              in one of the various object caches.
261  *
262  ******************************************************************************/
263
264 UINT32
265 AcpiDbGetOutstandingAllocations (
266     void)
267 {
268     UINT32                  Outstanding = 0;
269
270 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
271     UINT32                  i;
272
273
274     for (i = ACPI_MEM_LIST_FIRST_CACHE_LIST; i < ACPI_NUM_MEM_LISTS; i++)
275     {
276         Outstanding += (AcpiGbl_MemoryLists[i].TotalAllocated -
277                         AcpiGbl_MemoryLists[i].TotalFreed -
278                         AcpiGbl_MemoryLists[i].CacheDepth);
279     }
280 #endif
281
282     return (Outstanding);
283 }
284
285
286 /*******************************************************************************
287  *
288  * FUNCTION:    AcpiDbExecute
289  *
290  * PARAMETERS:  Name                - Name of method to execute
291  *              Args                - Parameters to the method
292  *              Flags               - single step/no single step
293  *
294  * RETURN:      Status
295  *
296  * DESCRIPTION: Execute a control method.  Name is relative to the current
297  *              scope.
298  *
299  ******************************************************************************/
300
301 void
302 AcpiDbExecute (
303     NATIVE_CHAR             *Name,
304     NATIVE_CHAR             **Args,
305     UINT32                  Flags)
306 {
307     ACPI_STATUS             Status;
308     ACPI_BUFFER             ReturnObj;
309
310
311 #ifdef ACPI_DEBUG_OUTPUT
312     UINT32                  PreviousAllocations;
313     UINT32                  Allocations;
314
315
316     /* Memory allocation tracking */
317
318     PreviousAllocations = AcpiDbGetOutstandingAllocations ();
319 #endif
320
321     AcpiGbl_DbMethodInfo.Name = Name;
322     AcpiGbl_DbMethodInfo.Args = Args;
323     AcpiGbl_DbMethodInfo.Flags = Flags;
324
325     ReturnObj.Pointer = NULL;
326     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
327
328     AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
329     Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj);
330
331     /*
332      * Allow any handlers in separate threads to complete.
333      * (Such as Notify handlers invoked from AML executed above).
334      */
335     AcpiOsSleep (0, 10);
336
337
338 #ifdef ACPI_DEBUG_OUTPUT
339
340     /* Memory allocation tracking */
341
342     Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations;
343
344     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
345
346     if (Allocations > 0)
347     {
348         AcpiOsPrintf ("Outstanding: %ld allocations after execution\n",
349                         Allocations);
350     }
351 #endif
352
353     if (ACPI_FAILURE (Status))
354     {
355         AcpiOsPrintf ("Execution of %s failed with status %s\n",
356             AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status));
357     }
358
359     else
360     {
361         /* Display a return object, if any */
362
363         if (ReturnObj.Length)
364         {
365             AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
366                 AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, 
367                 (UINT32) ReturnObj.Length);
368             AcpiDbDumpObject (ReturnObj.Pointer, 1);
369         }
370         else
371         {
372             AcpiOsPrintf ("No return object from execution of %s\n",
373                 AcpiGbl_DbMethodInfo.Pathname);
374         }
375     }
376
377     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
378 }
379
380
381 /*******************************************************************************
382  *
383  * FUNCTION:    AcpiDbMethodThread
384  *
385  * PARAMETERS:  Context             - Execution info segment
386  *
387  * RETURN:      None
388  *
389  * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
390  *              simply dispatches it.
391  *
392  ******************************************************************************/
393
394 void ACPI_SYSTEM_XFACE
395 AcpiDbMethodThread (
396     void                    *Context)
397 {
398     ACPI_STATUS             Status;
399     ACPI_DB_METHOD_INFO     *Info = Context;
400     UINT32                  i;
401     ACPI_BUFFER             ReturnObj;
402
403
404     for (i = 0; i < Info->NumLoops; i++)
405     {
406         Status = AcpiDbExecuteMethod (Info, &ReturnObj);
407         if (ACPI_SUCCESS (Status))
408         {
409             if (ReturnObj.Length)
410             {
411                 AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
412                     Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length);
413                 AcpiDbDumpObject (ReturnObj.Pointer, 1);
414             }
415         }
416     }
417
418     /* Signal our completion */
419
420     Status = AcpiOsSignalSemaphore (Info->ThreadGate, 1);
421     if (ACPI_FAILURE (Status))
422     {
423         AcpiOsPrintf ("Could not signal debugger semaphore\n");
424     }
425 }
426
427
428 /*******************************************************************************
429  *
430  * FUNCTION:    AcpiDbCreateExecutionThreads
431  *
432  * PARAMETERS:  NumThreadsArg           - Number of threads to create
433  *              NumLoopsArg             - Loop count for the thread(s)
434  *              MethodNameArg           - Control method to execute
435  *
436  * RETURN:      None
437  *
438  * DESCRIPTION: Create threads to execute method(s)
439  *
440  ******************************************************************************/
441
442 void
443 AcpiDbCreateExecutionThreads (
444     NATIVE_CHAR             *NumThreadsArg,
445     NATIVE_CHAR             *NumLoopsArg,
446     NATIVE_CHAR             *MethodNameArg)
447 {
448     ACPI_STATUS             Status;
449     UINT32                  NumThreads;
450     UINT32                  NumLoops;
451     UINT32                  i;
452     ACPI_HANDLE             ThreadGate;
453
454
455     /* Get the arguments */
456
457     NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0);
458     NumLoops   = ACPI_STRTOUL (NumLoopsArg, NULL, 0);
459
460     if (!NumThreads || !NumLoops)
461     {
462         AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", NumThreads, NumLoops);
463         return;
464     }
465
466     /* Create the synchronization semaphore */
467
468     Status = AcpiOsCreateSemaphore (1, 0, &ThreadGate);
469     if (ACPI_FAILURE (Status))
470     {
471         AcpiOsPrintf ("Could not create semaphore, %s\n", AcpiFormatException (Status));
472         return;
473     }
474
475     /* Setup the context to be passed to each thread */
476
477     AcpiGbl_DbMethodInfo.Name = MethodNameArg;
478     AcpiGbl_DbMethodInfo.Args = NULL;
479     AcpiGbl_DbMethodInfo.Flags = 0;
480     AcpiGbl_DbMethodInfo.NumLoops = NumLoops;
481     AcpiGbl_DbMethodInfo.ThreadGate = ThreadGate;
482
483     AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
484
485     /* Create the threads */
486
487     AcpiOsPrintf ("Creating %X threads to execute %X times each\n", NumThreads, NumLoops);
488
489     for (i = 0; i < (NumThreads); i++)
490     {
491         Status = AcpiOsQueueForExecution (OSD_PRIORITY_MED, AcpiDbMethodThread, &AcpiGbl_DbMethodInfo);
492         if (ACPI_FAILURE (Status))
493         {
494             break;
495         }
496     }
497
498     /* Wait for all threads to complete */
499
500     i = NumThreads;
501     while (i)   /* Brain damage for OSD implementations that only support wait of 1 unit */
502     {
503         Status = AcpiOsWaitSemaphore (ThreadGate, 1, ACPI_WAIT_FOREVER);
504         i--;
505     }
506
507     /* Cleanup and exit */
508
509     (void) AcpiOsDeleteSemaphore (ThreadGate);
510
511     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
512     AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads);
513     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
514 }
515
516
517 #endif /* ACPI_DEBUGGER */
518
519