dbexec.c revision 99679
152419Sjulian/*******************************************************************************
252419Sjulian *
3139823Simp * Module Name: dbexec - debugger control method execution
4139823Simp *              $Revision: 41 $
5139823Simp *
652419Sjulian ******************************************************************************/
752419Sjulian
870700Sjulian/******************************************************************************
952419Sjulian *
1052419Sjulian * 1. Copyright Notice
1152419Sjulian *
1252419Sjulian * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp.
1352419Sjulian * All rights reserved.
1452419Sjulian *
1552419Sjulian * 2. License
1652419Sjulian *
1752419Sjulian * 2.1. This is your license from Intel Corp. under its intellectual property
1852419Sjulian * rights.  You may have additional license terms from the party that provided
1970700Sjulian * you this software, covering your right to use that party's intellectual
2052419Sjulian * property rights.
2152419Sjulian *
2252419Sjulian * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2352419Sjulian * copy of the source code appearing in this file ("Covered Code") an
2452419Sjulian * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2552419Sjulian * base code distributed originally by Intel ("Original Intel Code") to copy,
2652419Sjulian * make derivatives, distribute, use and display any portion of the Covered
2752419Sjulian * Code in any form, with the right to sublicense such rights; and
2852419Sjulian *
2952419Sjulian * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3052419Sjulian * license (with the right to sublicense), under only those claims of Intel
3152419Sjulian * patents that are infringed by the Original Intel Code, to make, use, sell,
3252419Sjulian * offer to sell, and import the Covered Code and derivative works thereof
3352419Sjulian * solely to the minimum extent necessary to exercise the above copyright
3452419Sjulian * license, and in no event shall the patent license extend to any additions
3552419Sjulian * to or modifications of the Original Intel Code.  No other license or right
3652419Sjulian * is granted directly or by implication, estoppel or otherwise;
3752419Sjulian *
3867506Sjulian * The above copyright and patent license is granted only if the following
3967506Sjulian * conditions are met:
4052419Sjulian *
4152419Sjulian * 3. Conditions
4252419Sjulian *
4352419Sjulian * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4452419Sjulian * Redistribution of source code of any substantial portion of the Covered
4552419Sjulian * Code or modification with rights to further distribute source must include
4652419Sjulian * the above Copyright Notice, the above License, this list of Conditions,
4752419Sjulian * and the following Disclaimer and Export Compliance provision.  In addition,
4852419Sjulian * Licensee must cause all Covered Code to which Licensee contributes to
4952419Sjulian * contain a file documenting the changes Licensee made to create that Covered
50139236Sglebius * Code and the date of any change.  Licensee must include in that file the
51139235Sglebius * documentation of any changes made by any predecessor Licensee.  Licensee
5252419Sjulian * must include a prominent statement that the modification is derived,
53131933Smarcel * directly or indirectly, from Original Intel Code.
5452419Sjulian *
55154225Sglebius * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56114216Skan * Redistribution of source code of any substantial portion of the Covered
5752419Sjulian * Code or modification without rights to further distribute source must
58139235Sglebius * include the following Disclaimer and Export Compliance provision in the
5952419Sjulian * documentation and/or other materials provided with distribution.  In
6072946Sjulian * addition, Licensee may not authorize further sublicense of source of any
61139235Sglebius * portion of the Covered Code, and must include terms to the effect that the
62172806Smav * license from Licensee to its licensee is limited to the intellectual
63175847Smav * property embodied in the software Licensee provides to its licensee, and
64177953Smav * not to intellectual property embodied in modifications its licensee may
6552419Sjulian * make.
6652419Sjulian *
6752419Sjulian * 3.3. Redistribution of Executable. Redistribution in executable form of any
6852419Sjulian * substantial portion of the Covered Code or modification must reproduce the
6952419Sjulian * above Copyright Notice, and the following Disclaimer and Export Compliance
7053913Sarchie * provision in the documentation and/or other materials provided with the
7152419Sjulian * distribution.
7272053Sjulian *
7359756Speter * 3.4. Intel retains all right, title, and interest in and to the Original
74151974Sglebius * Intel Code.
75151974Sglebius *
76151974Sglebius * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7770784Sjulian * Intel shall be used in advertising or otherwise to promote the sale, use or
78176802Smav * other dealings in products derived from or relating to the Covered Code
79152451Sglebius * without prior written authorization from Intel.
8070784Sjulian *
8170784Sjulian * 4. Disclaimer and Export Compliance
8270784Sjulian *
8370784Sjulian * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8470784Sjulian * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8570784Sjulian * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8670784Sjulian * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8770784Sjulian * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8870784Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8970784Sjulian * PARTICULAR PURPOSE.
9070784Sjulian *
9170935Sjulian * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92152451Sglebius * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9370935Sjulian * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94152451Sglebius * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9570935Sjulian * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9670935Sjulian * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9770935Sjulian * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9870935Sjulian * LIMITED REMEDY.
9970935Sjulian *
10070935Sjulian * 4.3. Licensee shall not export, either directly or indirectly, any of this
10170935Sjulian * software or system incorporating such software without first obtaining any
10270935Sjulian * required license or other approval from the U. S. Department of Commerce or
10370935Sjulian * any other agency or department of the United States Government.  In the
10470935Sjulian * event Licensee exports any such software from the United States or
10570935Sjulian * re-exports any such software from a foreign destination, Licensee shall
10670935Sjulian * ensure that the distribution and export/re-export of the software is in
10770935Sjulian * compliance with all laws, regulations, orders, or other restrictions of the
10870935Sjulian * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10970935Sjulian * any of its subsidiaries will export/re-export any technical data, process,
11070935Sjulian * software, or service, directly or indirectly, to any country for which the
11170784Sjulian * United States government or any agency thereof requires an export license,
11270935Sjulian * other governmental approval, or letter of assurance, without first obtaining
11370935Sjulian * such license, approval or letter.
11470935Sjulian *
115132464Sjulian *****************************************************************************/
11670935Sjulian
11770935Sjulian
11870935Sjulian#include "acpi.h"
11970935Sjulian#include "acdebug.h"
12070935Sjulian
12170935Sjulian#ifdef ENABLE_DEBUGGER
12270935Sjulian
12370935Sjulian#define _COMPONENT          ACPI_DEBUGGER
12470935Sjulian        ACPI_MODULE_NAME    ("dbexec")
12570935Sjulian
12670935Sjulian
12770935Sjulianstatic ACPI_DB_METHOD_INFO  AcpiGbl_DbMethodInfo;
12870935Sjulian
12970935Sjulian
13070935Sjulian/*******************************************************************************
13170935Sjulian *
13270935Sjulian * FUNCTION:    AcpiDbExecuteMethod
13370935Sjulian *
13470935Sjulian * PARAMETERS:  Info            - Valid info segment
13570935Sjulian *              ReturnObj       - Where to put return object
13670935Sjulian *
13770935Sjulian * RETURN:      Status
13870935Sjulian *
13970935Sjulian * DESCRIPTION: Execute a control method.
14070935Sjulian *
14170935Sjulian ******************************************************************************/
14270935Sjulian
143148261SglebiusACPI_STATUS
14470935SjulianAcpiDbExecuteMethod (
14570935Sjulian    ACPI_DB_METHOD_INFO     *Info,
14670935Sjulian    ACPI_BUFFER             *ReturnObj)
14771885Sjulian{
14871885Sjulian    ACPI_STATUS             Status;
14970935Sjulian    ACPI_OBJECT_LIST        ParamObjects;
15070935Sjulian    ACPI_OBJECT             Params[MTH_NUM_ARGS];
15170935Sjulian    UINT32                  i;
15270935Sjulian
15370935Sjulian
15470935Sjulian    if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel)
15570935Sjulian    {
15670935Sjulian        AcpiOsPrintf ("Warning: debug output is not enabled!\n");
15770935Sjulian    }
15870935Sjulian
15970935Sjulian    /* Are there arguments to the method? */
16070700Sjulian
16170700Sjulian    if (Info->Args && Info->Args[0])
16271902Sjulian    {
16370700Sjulian        for (i = 0; Info->Args[i] && i < MTH_NUM_ARGS; i++)
16452419Sjulian        {
16570700Sjulian            Params[i].Type              = ACPI_TYPE_INTEGER;
16670700Sjulian            Params[i].Integer.Value     = ACPI_STRTOUL (Info->Args[i], NULL, 16);
16752419Sjulian        }
16870700Sjulian
16971354Sjulian        ParamObjects.Pointer        = Params;
170176802Smav        ParamObjects.Count          = i;
17171354Sjulian    }
17270700Sjulian    else
17371354Sjulian    {
17471354Sjulian        /* Setup default parameters */
17571354Sjulian
17671354Sjulian        Params[0].Type              = ACPI_TYPE_INTEGER;
177131008Srwatson        Params[0].Integer.Value     = 0x01020304;
17871354Sjulian
17971354Sjulian        Params[1].Type              = ACPI_TYPE_STRING;
18071354Sjulian        Params[1].String.Length     = 12;
18171354Sjulian        Params[1].String.Pointer    = "AML Debugger";
18271354Sjulian
18371354Sjulian        ParamObjects.Pointer        = Params;
18471354Sjulian        ParamObjects.Count          = 2;
18571354Sjulian    }
18652722Sjulian
187176802Smav    /* Prepare for a return object of arbitrary size */
188176802Smav
189176802Smav    ReturnObj->Pointer           = AcpiGbl_DbBuffer;
190176802Smav    ReturnObj->Length            = ACPI_DEBUG_BUFFER_SIZE;
191176802Smav
192176802Smav    /* Do the actual method execution */
193176802Smav
194176802Smav    Status = AcpiEvaluateObject (NULL, Info->Pathname, &ParamObjects, ReturnObj);
195176802Smav
196176802Smav    AcpiGbl_CmSingleStep = FALSE;
197176802Smav    AcpiGbl_MethodExecuting = FALSE;
19870700Sjulian
199176802Smav    return (Status);
20052419Sjulian}
20152419Sjulian
20270700Sjulian
20352722Sjulian/*******************************************************************************
20452419Sjulian *
205177953Smav * FUNCTION:    AcpiDbExecuteSetup
20652419Sjulian *
207170180Sglebius * PARAMETERS:  Info            - Valid method info
20870700Sjulian *
20970700Sjulian * RETURN:      Status
210172806Smav *
211172806Smav * DESCRIPTION: Setup info segment prior to method execution
212172806Smav *
213172806Smav ******************************************************************************/
21471047Sjulian
21571047Sjulianvoid
21652419SjulianAcpiDbExecuteSetup (
217152451Sglebius    ACPI_DB_METHOD_INFO     *Info)
21870700Sjulian{
21970700Sjulian
22070700Sjulian    /* Catenate the current scope to the supplied name */
22170700Sjulian
22270700Sjulian    Info->Pathname[0] = 0;
22370700Sjulian    if ((Info->Name[0] != '\\') &&
22471849Sjulian        (Info->Name[0] != '/'))
22570784Sjulian    {
22670700Sjulian        ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf);
22770700Sjulian    }
22852419Sjulian
22952419Sjulian    ACPI_STRCAT (Info->Pathname, Info->Name);
23070700Sjulian    AcpiDbPrepNamestring (Info->Pathname);
23170700Sjulian
23270700Sjulian    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
23370700Sjulian    AcpiOsPrintf ("Executing %s\n", Info->Pathname);
23452419Sjulian
23570700Sjulian    if (Info->Flags & EX_SINGLE_STEP)
23670784Sjulian    {
23770784Sjulian        AcpiGbl_CmSingleStep = TRUE;
23870784Sjulian        AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
23970784Sjulian    }
24070784Sjulian
24170784Sjulian    else
242168049Swkoszek    {
243168137Swkoszek        /* No single step, allow redirection to a file */
244168049Swkoszek
245168137Swkoszek        AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
246168049Swkoszek    }
247168137Swkoszek}
248168049Swkoszek
249168137Swkoszek
250168049Swkoszek/*******************************************************************************
251168137Swkoszek *
252168049Swkoszek * FUNCTION:    AcpiDbGetOutstandingAllocations
253168137Swkoszek *
254168049Swkoszek * PARAMETERS:  None
25570784Sjulian *
25670784Sjulian * RETURN:      Current global allocation count minus cache entries
25770784Sjulian *
25870784Sjulian * DESCRIPTION: Determine the current number of "outstanding" allocations --
25970784Sjulian *              those allocations that have not been freed and also are not
26070784Sjulian *              in one of the various object caches.
26170784Sjulian *
26270784Sjulian ******************************************************************************/
26370784Sjulian
26470784SjulianUINT32
26570784SjulianAcpiDbGetOutstandingAllocations (
26670784Sjulian    void)
26770784Sjulian{
26870784Sjulian    UINT32                  Outstanding = 0;
26972200Sbmilekic
27070784Sjulian#ifdef ACPI_DBG_TRACK_ALLOCATIONS
27170784Sjulian    UINT32                  i;
27270784Sjulian
27370784Sjulian
27470784Sjulian    for (i = ACPI_MEM_LIST_FIRST_CACHE_LIST; i < ACPI_NUM_MEM_LISTS; i++)
27570784Sjulian    {
27672200Sbmilekic        Outstanding += (AcpiGbl_MemoryLists[i].TotalAllocated -
27770784Sjulian                        AcpiGbl_MemoryLists[i].TotalFreed -
27870784Sjulian                        AcpiGbl_MemoryLists[i].CacheDepth);
27972200Sbmilekic    }
28070784Sjulian#endif
28170784Sjulian
28270784Sjulian    return (Outstanding);
28372200Sbmilekic}
28470784Sjulian
28572200Sbmilekic
28670784Sjulian/*******************************************************************************
28770784Sjulian *
28870784Sjulian * FUNCTION:    AcpiDbExecute
28970784Sjulian *
29070784Sjulian * PARAMETERS:  Name                - Name of method to execute
29170784Sjulian *              Args                - Parameters to the method
29270784Sjulian *              Flags               - single step/no single step
29370784Sjulian *
29470784Sjulian * RETURN:      Status
29570784Sjulian *
29672200Sbmilekic * DESCRIPTION: Execute a control method.  Name is relative to the current
29770784Sjulian *              scope.
29870784Sjulian *
29970784Sjulian ******************************************************************************/
30070784Sjulian
30170784Sjulianvoid
30270784SjulianAcpiDbExecute (
30372200Sbmilekic    NATIVE_CHAR             *Name,
30470784Sjulian    NATIVE_CHAR             **Args,
30570784Sjulian    UINT32                  Flags)
30672200Sbmilekic{
30770784Sjulian    ACPI_STATUS             Status;
30870784Sjulian    ACPI_BUFFER             ReturnObj;
30970784Sjulian
31072200Sbmilekic
31170784Sjulian#ifdef ACPI_DEBUG
31272200Sbmilekic    UINT32                  PreviousAllocations;
31370784Sjulian    UINT32                  Allocations;
31470784Sjulian
31570784Sjulian
31670784Sjulian    /* Memory allocation tracking */
31770784Sjulian
31870784Sjulian    PreviousAllocations = AcpiDbGetOutstandingAllocations ();
31970784Sjulian#endif
32070784Sjulian
32170784Sjulian    AcpiGbl_DbMethodInfo.Name = Name;
32270784Sjulian    AcpiGbl_DbMethodInfo.Args = Args;
32370784Sjulian    AcpiGbl_DbMethodInfo.Flags = Flags;
32472200Sbmilekic
32570784Sjulian    AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
32670784Sjulian    Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj);
32772200Sbmilekic
32870784Sjulian    /*
32970784Sjulian     * Allow any handlers in separate threads to complete.
33070784Sjulian     * (Such as Notify handlers invoked from AML executed above).
33170784Sjulian     */
33272200Sbmilekic    AcpiOsSleep (0, 10);
33370784Sjulian
33470784Sjulian
33572200Sbmilekic#ifdef ACPI_DEBUG
33670784Sjulian
33770784Sjulian    /* Memory allocation tracking */
33870784Sjulian
33970784Sjulian    Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations;
34070784Sjulian
34170784Sjulian    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
34270784Sjulian
34370700Sjulian    if (Allocations > 0)
34470700Sjulian    {
34570784Sjulian        AcpiOsPrintf ("Outstanding: %ld allocations after execution\n",
34670784Sjulian                        Allocations);
34770784Sjulian    }
348131933Smarcel#endif
34952419Sjulian
35071047Sjulian    if (ACPI_FAILURE (Status))
35152419Sjulian    {
35252419Sjulian        AcpiOsPrintf ("Execution of %s failed with status %s\n",
35352722Sjulian            AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status));
35452722Sjulian    }
35553403Sarchie
35653403Sarchie    else
35753403Sarchie    {
35853403Sarchie        /* Display a return object, if any */
35953403Sarchie
360113255Sdes        if (ReturnObj.Length)
361149818Sglebius        {
36253403Sarchie            AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
363149818Sglebius                AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, ReturnObj.Length);
364149818Sglebius            AcpiDbDumpObject (ReturnObj.Pointer, 1);
365149818Sglebius        }
366149827Sglebius    }
36753403Sarchie
36853403Sarchie    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
36987599Sobrien}
37053403Sarchie
37153403Sarchie
37253403Sarchie/*******************************************************************************
37353403Sarchie *
37453403Sarchie * FUNCTION:    AcpiDbMethodThread
37552722Sjulian *
376172806Smav * PARAMETERS:  Context             - Execution info segment
37753403Sarchie *
37852419Sjulian * RETURN:      None
37953913Sarchie *
38053913Sarchie * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
38153913Sarchie *              simply dispatches it.
38253913Sarchie *
38353913Sarchie ******************************************************************************/
38497685Sarchie
38597685Sarchievoid ACPI_SYSTEM_XFACE
38653913SarchieAcpiDbMethodThread (
38753913Sarchie    void                    *Context)
38897685Sarchie{
38953913Sarchie    ACPI_STATUS             Status;
39053913Sarchie    ACPI_DB_METHOD_INFO     *Info = Context;
39153913Sarchie    UINT32                  i;
39253913Sarchie    ACPI_BUFFER             ReturnObj;
39353913Sarchie
39453913Sarchie
39553913Sarchie    for (i = 0; i < Info->NumLoops; i++)
39653913Sarchie    {
39753913Sarchie        Status = AcpiDbExecuteMethod (Info, &ReturnObj);
39853913Sarchie        if (ACPI_SUCCESS (Status))
39953913Sarchie        {
40072645Sasmodai            if (ReturnObj.Length)
40153913Sarchie            {
40253913Sarchie                AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
40353913Sarchie                    Info->Pathname, ReturnObj.Pointer, ReturnObj.Length);
40453913Sarchie                AcpiDbDumpObject (ReturnObj.Pointer, 1);
40553913Sarchie            }
40653913Sarchie        }
40753913Sarchie    }
40853913Sarchie
40953913Sarchie    /* Signal our completion */
41053913Sarchie
41153913Sarchie    Status = AcpiOsSignalSemaphore (Info->ThreadGate, 1);
41253913Sarchie    if (ACPI_FAILURE (Status))
41353913Sarchie    {
41453913Sarchie        AcpiOsPrintf ("Could not signal debugger semaphore\n");
41553913Sarchie    }
41653913Sarchie}
41753913Sarchie
41853913Sarchie
41953913Sarchie/*******************************************************************************
42053913Sarchie *
42153913Sarchie * FUNCTION:    AcpiDbCreateExecutionThreads
42253913Sarchie *
42353913Sarchie * PARAMETERS:  NumThreadsArg           - Number of threads to create
42453913Sarchie *              NumLoopsArg             - Loop count for the thread(s)
42553913Sarchie *              MethodNameArg           - Control method to execute
42653913Sarchie *
42753913Sarchie * RETURN:      None
42853913Sarchie *
42953913Sarchie * DESCRIPTION: Create threads to execute method(s)
43053913Sarchie *
43153913Sarchie ******************************************************************************/
43253913Sarchie
43353913Sarchievoid
43453913SarchieAcpiDbCreateExecutionThreads (
43553913Sarchie    NATIVE_CHAR             *NumThreadsArg,
43653913Sarchie    NATIVE_CHAR             *NumLoopsArg,
43753913Sarchie    NATIVE_CHAR             *MethodNameArg)
43853913Sarchie{
43953913Sarchie    ACPI_STATUS             Status;
44053913Sarchie    UINT32                  NumThreads;
44153913Sarchie    UINT32                  NumLoops;
44253913Sarchie    UINT32                  i;
44353913Sarchie    ACPI_HANDLE             ThreadGate;
44453913Sarchie
44553913Sarchie
44653913Sarchie    /* Get the arguments */
44753913Sarchie
44853913Sarchie    NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0);
44953913Sarchie    NumLoops   = ACPI_STRTOUL (NumLoopsArg, NULL, 0);
45053913Sarchie
45153913Sarchie    if (!NumThreads || !NumLoops)
45253913Sarchie    {
45353913Sarchie        AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", NumThreads, NumLoops);
45453913Sarchie        return;
45553913Sarchie    }
45653913Sarchie
45753913Sarchie    /* Create the synchronization semaphore */
45853913Sarchie
45953913Sarchie    Status = AcpiOsCreateSemaphore (1, 0, &ThreadGate);
46053913Sarchie    if (ACPI_FAILURE (Status))
46153913Sarchie    {
46253913Sarchie        AcpiOsPrintf ("Could not create semaphore, %s\n", AcpiFormatException (Status));
46353913Sarchie        return;
46453913Sarchie    }
46553913Sarchie
46653913Sarchie    /* Setup the context to be passed to each thread */
46753913Sarchie
46853913Sarchie    AcpiGbl_DbMethodInfo.Name = MethodNameArg;
46953913Sarchie    AcpiGbl_DbMethodInfo.Args = NULL;
47053913Sarchie    AcpiGbl_DbMethodInfo.Flags = 0;
47153913Sarchie    AcpiGbl_DbMethodInfo.NumLoops = NumLoops;
47253913Sarchie    AcpiGbl_DbMethodInfo.ThreadGate = ThreadGate;
47353913Sarchie
47453913Sarchie    AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
47553913Sarchie
47653913Sarchie    /* Create the threads */
47753913Sarchie
47853913Sarchie    AcpiOsPrintf ("Creating %X threads to execute %X times each\n", NumThreads, NumLoops);
47953913Sarchie
48053913Sarchie    for (i = 0; i < (NumThreads); i++)
48153913Sarchie    {
48253913Sarchie        Status = AcpiOsQueueForExecution (OSD_PRIORITY_MED, AcpiDbMethodThread, &AcpiGbl_DbMethodInfo);
48353913Sarchie        if (ACPI_FAILURE (Status))
48453913Sarchie        {
48553913Sarchie            break;
48653913Sarchie        }
48753913Sarchie    }
48853913Sarchie
48953913Sarchie    /* Wait for all threads to complete */
49053913Sarchie
49153913Sarchie    i = NumThreads;
49253913Sarchie    while (i)   /* Brain damage for OSD implementations that only support wait of 1 unit */
49353913Sarchie    {
49453913Sarchie        Status = AcpiOsWaitSemaphore (ThreadGate, 1, WAIT_FOREVER);
49553913Sarchie        i--;
49653913Sarchie    }
49753913Sarchie
49853913Sarchie    /* Cleanup and exit */
49953913Sarchie
50053913Sarchie    (void) AcpiOsDeleteSemaphore (ThreadGate);
50153913Sarchie
50253913Sarchie    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
50353913Sarchie    AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads);
50453913Sarchie    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
50553913Sarchie}
50653913Sarchie
50753913Sarchie
50853913Sarchie#endif /* ENABLE_DEBUGGER */
50953913Sarchie
51053913Sarchie
51153913Sarchie