dbexec.c revision 216471
167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dbexec - debugger control method execution
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
767754Smsmith/******************************************************************************
867754Smsmith *
967754Smsmith * 1. Copyright Notice
1067754Smsmith *
11202771Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
1270243Smsmith * All rights reserved.
1367754Smsmith *
1467754Smsmith * 2. License
1567754Smsmith *
1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1767754Smsmith * rights.  You may have additional license terms from the party that provided
1867754Smsmith * you this software, covering your right to use that party's intellectual
1967754Smsmith * property rights.
2067754Smsmith *
2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2667754Smsmith * Code in any form, with the right to sublicense such rights; and
2767754Smsmith *
2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
2967754Smsmith * license (with the right to sublicense), under only those claims of Intel
3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3367754Smsmith * license, and in no event shall the patent license extend to any additions
3467754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3567754Smsmith * is granted directly or by implication, estoppel or otherwise;
3667754Smsmith *
3767754Smsmith * The above copyright and patent license is granted only if the following
3867754Smsmith * conditions are met:
3967754Smsmith *
4067754Smsmith * 3. Conditions
4167754Smsmith *
4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4367754Smsmith * Redistribution of source code of any substantial portion of the Covered
4467754Smsmith * Code or modification with rights to further distribute source must include
4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4667754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered
4967754Smsmith * Code and the date of any change.  Licensee must include in that file the
5067754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5167754Smsmith * must include a prominent statement that the modification is derived,
5267754Smsmith * directly or indirectly, from Original Intel Code.
5367754Smsmith *
5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5567754Smsmith * Redistribution of source code of any substantial portion of the Covered
5667754Smsmith * Code or modification without rights to further distribute source must
5767754Smsmith * include the following Disclaimer and Export Compliance provision in the
5867754Smsmith * documentation and/or other materials provided with distribution.  In
5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6167754Smsmith * license from Licensee to its licensee is limited to the intellectual
6267754Smsmith * property embodied in the software Licensee provides to its licensee, and
6367754Smsmith * not to intellectual property embodied in modifications its licensee may
6467754Smsmith * make.
6567754Smsmith *
6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the
6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
6967754Smsmith * provision in the documentation and/or other materials provided with the
7067754Smsmith * distribution.
7167754Smsmith *
7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7367754Smsmith * Intel Code.
7467754Smsmith *
7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7767754Smsmith * other dealings in products derived from or relating to the Covered Code
7867754Smsmith * without prior written authorization from Intel.
7967754Smsmith *
8067754Smsmith * 4. Disclaimer and Export Compliance
8167754Smsmith *
8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8367754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8867754Smsmith * PARTICULAR PURPOSE.
8967754Smsmith *
9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9767754Smsmith * LIMITED REMEDY.
9867754Smsmith *
9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10067754Smsmith * software or system incorporating such software without first obtaining any
10167754Smsmith * required license or other approval from the U. S. Department of Commerce or
10267754Smsmith * any other agency or department of the United States Government.  In the
10367754Smsmith * event Licensee exports any such software from the United States or
10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10567754Smsmith * ensure that the distribution and export/re-export of the software is in
10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
10967754Smsmith * software, or service, directly or indirectly, to any country for which the
11067754Smsmith * United States government or any agency thereof requires an export license,
11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11267754Smsmith * such license, approval or letter.
11367754Smsmith *
11467754Smsmith *****************************************************************************/
11567754Smsmith
11667754Smsmith
117193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
118193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
119193341Sjkim#include <contrib/dev/acpica/include/acdebug.h>
120193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
12167754Smsmith
122102550Siwasaki#ifdef ACPI_DEBUGGER
12367754Smsmith
124102550Siwasaki#define _COMPONENT          ACPI_CA_DEBUGGER
12591116Smsmith        ACPI_MODULE_NAME    ("dbexec")
12667754Smsmith
12767754Smsmith
12899679Siwasakistatic ACPI_DB_METHOD_INFO  AcpiGbl_DbMethodInfo;
12967754Smsmith
130151937Sjkim/* Local prototypes */
13167754Smsmith
132151937Sjkimstatic ACPI_STATUS
133151937SjkimAcpiDbExecuteMethod (
134151937Sjkim    ACPI_DB_METHOD_INFO     *Info,
135151937Sjkim    ACPI_BUFFER             *ReturnObj);
136151937Sjkim
137151937Sjkimstatic void
138151937SjkimAcpiDbExecuteSetup (
139151937Sjkim    ACPI_DB_METHOD_INFO     *Info);
140151937Sjkim
141151937Sjkimstatic UINT32
142151937SjkimAcpiDbGetOutstandingAllocations (
143151937Sjkim    void);
144151937Sjkim
145151937Sjkimstatic void ACPI_SYSTEM_XFACE
146151937SjkimAcpiDbMethodThread (
147151937Sjkim    void                    *Context);
148151937Sjkim
149151937Sjkimstatic ACPI_STATUS
150151937SjkimAcpiDbExecutionWalk (
151151937Sjkim    ACPI_HANDLE             ObjHandle,
152151937Sjkim    UINT32                  NestingLevel,
153151937Sjkim    void                    *Context,
154151937Sjkim    void                    **ReturnValue);
155151937Sjkim
156151937Sjkim
15767754Smsmith/*******************************************************************************
15867754Smsmith *
15967754Smsmith * FUNCTION:    AcpiDbExecuteMethod
16067754Smsmith *
16167754Smsmith * PARAMETERS:  Info            - Valid info segment
16267754Smsmith *              ReturnObj       - Where to put return object
16367754Smsmith *
16467754Smsmith * RETURN:      Status
16567754Smsmith *
16667754Smsmith * DESCRIPTION: Execute a control method.
16767754Smsmith *
16867754Smsmith ******************************************************************************/
16967754Smsmith
170151937Sjkimstatic ACPI_STATUS
17167754SmsmithAcpiDbExecuteMethod (
17291116Smsmith    ACPI_DB_METHOD_INFO     *Info,
17367754Smsmith    ACPI_BUFFER             *ReturnObj)
17467754Smsmith{
17567754Smsmith    ACPI_STATUS             Status;
17667754Smsmith    ACPI_OBJECT_LIST        ParamObjects;
177114237Snjl    ACPI_OBJECT             Params[ACPI_METHOD_NUM_ARGS];
178193267Sjkim    ACPI_HANDLE             Handle;
17967754Smsmith    UINT32                  i;
180193267Sjkim    ACPI_DEVICE_INFO        *ObjInfo;
18167754Smsmith
18267754Smsmith
183216471Sjkim    ACPI_FUNCTION_TRACE (DbExecuteMethod);
184216471Sjkim
185216471Sjkim
18683174Smsmith    if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel)
18767754Smsmith    {
18867754Smsmith        AcpiOsPrintf ("Warning: debug output is not enabled!\n");
18967754Smsmith    }
19067754Smsmith
191193267Sjkim    /* Get the NS node, determines existence also */
19267754Smsmith
193193267Sjkim    Status = AcpiGetHandle (NULL, Info->Pathname, &Handle);
194193267Sjkim    if (ACPI_FAILURE (Status))
19567754Smsmith    {
196216471Sjkim        return_ACPI_STATUS (Status);
197193267Sjkim    }
19867754Smsmith
199193267Sjkim    /* Get the object info for number of method parameters */
200193267Sjkim
201197104Sjkim    Status = AcpiGetObjectInfo (Handle, &ObjInfo);
202193267Sjkim    if (ACPI_FAILURE (Status))
203193267Sjkim    {
204216471Sjkim        return_ACPI_STATUS (Status);
20567754Smsmith    }
206193267Sjkim
207193267Sjkim    ParamObjects.Pointer = NULL;
208193267Sjkim    ParamObjects.Count   = 0;
209193267Sjkim
210193267Sjkim    if (ObjInfo->Type == ACPI_TYPE_METHOD)
21167754Smsmith    {
212193267Sjkim        /* Are there arguments to the method? */
21367754Smsmith
214193267Sjkim        if (Info->Args && Info->Args[0])
215193267Sjkim        {
216193267Sjkim            for (i = 0; Info->Args[i] && i < ACPI_METHOD_NUM_ARGS; i++)
217193267Sjkim            {
218193267Sjkim                Params[i].Type          = ACPI_TYPE_INTEGER;
219193267Sjkim                Params[i].Integer.Value = ACPI_STRTOUL (Info->Args[i], NULL, 16);
220193267Sjkim            }
22167754Smsmith
222193267Sjkim            ParamObjects.Pointer = Params;
223193267Sjkim            ParamObjects.Count   = i;
224193267Sjkim        }
225193267Sjkim        else
226193267Sjkim        {
227193267Sjkim            /* Setup default parameters */
22867754Smsmith
229193267Sjkim            for (i = 0; i < ObjInfo->ParamCount; i++)
230193267Sjkim            {
231193267Sjkim                switch (i)
232193267Sjkim                {
233193267Sjkim                case 0:
234193267Sjkim
235193267Sjkim                    Params[0].Type           = ACPI_TYPE_INTEGER;
236193267Sjkim                    Params[0].Integer.Value  = 0x01020304;
237193267Sjkim                    break;
238193267Sjkim
239193267Sjkim                case 1:
240193267Sjkim
241193267Sjkim                    Params[1].Type           = ACPI_TYPE_STRING;
242193267Sjkim                    Params[1].String.Length  = 12;
243193267Sjkim                    Params[1].String.Pointer = "AML Debugger";
244193267Sjkim                    break;
245193267Sjkim
246193267Sjkim                default:
247193267Sjkim
248193267Sjkim                    Params[i].Type           = ACPI_TYPE_INTEGER;
249202771Sjkim                    Params[i].Integer.Value  = i * (UINT64) 0x1000;
250193267Sjkim                    break;
251193267Sjkim                }
252193267Sjkim            }
253193267Sjkim
254193267Sjkim            ParamObjects.Pointer     = Params;
255193267Sjkim            ParamObjects.Count       = ObjInfo->ParamCount;
256193267Sjkim        }
25767754Smsmith    }
25867754Smsmith
259197104Sjkim    ACPI_FREE (ObjInfo);
260193267Sjkim
26167754Smsmith    /* Prepare for a return object of arbitrary size */
26267754Smsmith
263151937Sjkim    ReturnObj->Pointer = AcpiGbl_DbBuffer;
264151937Sjkim    ReturnObj->Length  = ACPI_DEBUG_BUFFER_SIZE;
26567754Smsmith
26667754Smsmith    /* Do the actual method execution */
26767754Smsmith
268114237Snjl    AcpiGbl_MethodExecuting = TRUE;
269151937Sjkim    Status = AcpiEvaluateObject (NULL,
270151937Sjkim                Info->Pathname, &ParamObjects, ReturnObj);
27167754Smsmith
27267754Smsmith    AcpiGbl_CmSingleStep = FALSE;
27367754Smsmith    AcpiGbl_MethodExecuting = FALSE;
27467754Smsmith
275216471Sjkim    if (ACPI_FAILURE (Status))
276216471Sjkim    {
277216471Sjkim        ACPI_EXCEPTION ((AE_INFO, Status,
278216471Sjkim        "while executing %s from debugger", Info->Pathname));
279216471Sjkim
280216471Sjkim        if (Status == AE_BUFFER_OVERFLOW)
281216471Sjkim        {
282216471Sjkim            ACPI_ERROR ((AE_INFO,
283216471Sjkim            "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)",
284216471Sjkim                ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length));
285216471Sjkim        }
286216471Sjkim    }
287216471Sjkim
288216471Sjkim    return_ACPI_STATUS (Status);
28967754Smsmith}
29067754Smsmith
29167754Smsmith
29267754Smsmith/*******************************************************************************
29367754Smsmith *
29467754Smsmith * FUNCTION:    AcpiDbExecuteSetup
29567754Smsmith *
29667754Smsmith * PARAMETERS:  Info            - Valid method info
29767754Smsmith *
298151937Sjkim * RETURN:      None
29967754Smsmith *
30067754Smsmith * DESCRIPTION: Setup info segment prior to method execution
30167754Smsmith *
30267754Smsmith ******************************************************************************/
30367754Smsmith
304151937Sjkimstatic void
30567754SmsmithAcpiDbExecuteSetup (
30699679Siwasaki    ACPI_DB_METHOD_INFO     *Info)
30767754Smsmith{
30867754Smsmith
30967754Smsmith    /* Catenate the current scope to the supplied name */
31067754Smsmith
31167754Smsmith    Info->Pathname[0] = 0;
31267754Smsmith    if ((Info->Name[0] != '\\') &&
31367754Smsmith        (Info->Name[0] != '/'))
31467754Smsmith    {
31591116Smsmith        ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf);
31667754Smsmith    }
31767754Smsmith
31891116Smsmith    ACPI_STRCAT (Info->Pathname, Info->Name);
31967754Smsmith    AcpiDbPrepNamestring (Info->Pathname);
32067754Smsmith
32191116Smsmith    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
32267754Smsmith    AcpiOsPrintf ("Executing %s\n", Info->Pathname);
32367754Smsmith
32467754Smsmith    if (Info->Flags & EX_SINGLE_STEP)
32567754Smsmith    {
32667754Smsmith        AcpiGbl_CmSingleStep = TRUE;
32791116Smsmith        AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
32867754Smsmith    }
32967754Smsmith
33067754Smsmith    else
33167754Smsmith    {
33267754Smsmith        /* No single step, allow redirection to a file */
33367754Smsmith
33491116Smsmith        AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
33567754Smsmith    }
33667754Smsmith}
33767754Smsmith
33867754Smsmith
339151937Sjkim#ifdef ACPI_DBG_TRACK_ALLOCATIONS
340167802SjkimUINT32
341151937SjkimAcpiDbGetCacheInfo (
342151937Sjkim    ACPI_MEMORY_LIST        *Cache)
343151937Sjkim{
344151937Sjkim
345151937Sjkim    return (Cache->TotalAllocated - Cache->TotalFreed - Cache->CurrentDepth);
346151937Sjkim}
347151937Sjkim#endif
348151937Sjkim
34967754Smsmith/*******************************************************************************
35067754Smsmith *
35182367Smsmith * FUNCTION:    AcpiDbGetOutstandingAllocations
35282367Smsmith *
35382367Smsmith * PARAMETERS:  None
35482367Smsmith *
35582367Smsmith * RETURN:      Current global allocation count minus cache entries
35682367Smsmith *
35782367Smsmith * DESCRIPTION: Determine the current number of "outstanding" allocations --
35882367Smsmith *              those allocations that have not been freed and also are not
35982367Smsmith *              in one of the various object caches.
36082367Smsmith *
36182367Smsmith ******************************************************************************/
36282367Smsmith
363151937Sjkimstatic UINT32
36499679SiwasakiAcpiDbGetOutstandingAllocations (
36599679Siwasaki    void)
36682367Smsmith{
36782367Smsmith    UINT32                  Outstanding = 0;
36882367Smsmith
36982367Smsmith#ifdef ACPI_DBG_TRACK_ALLOCATIONS
37082367Smsmith
371151937Sjkim    Outstanding += AcpiDbGetCacheInfo (AcpiGbl_StateCache);
372151937Sjkim    Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeCache);
373151937Sjkim    Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeExtCache);
374151937Sjkim    Outstanding += AcpiDbGetCacheInfo (AcpiGbl_OperandCache);
37582367Smsmith#endif
37682367Smsmith
37782367Smsmith    return (Outstanding);
37882367Smsmith}
37982367Smsmith
38082367Smsmith
38182367Smsmith/*******************************************************************************
38282367Smsmith *
383114237Snjl * FUNCTION:    AcpiDbExecutionWalk
384114237Snjl *
385114237Snjl * PARAMETERS:  WALK_CALLBACK
386114237Snjl *
387114237Snjl * RETURN:      Status
388114237Snjl *
389114237Snjl * DESCRIPTION: Execute a control method.  Name is relative to the current
390114237Snjl *              scope.
391114237Snjl *
392114237Snjl ******************************************************************************/
393114237Snjl
394151937Sjkimstatic ACPI_STATUS
395114237SnjlAcpiDbExecutionWalk (
396114237Snjl    ACPI_HANDLE             ObjHandle,
397114237Snjl    UINT32                  NestingLevel,
398114237Snjl    void                    *Context,
399114237Snjl    void                    **ReturnValue)
400114237Snjl{
401114237Snjl    ACPI_OPERAND_OBJECT     *ObjDesc;
402114237Snjl    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
403114237Snjl    ACPI_BUFFER             ReturnObj;
404114237Snjl    ACPI_STATUS             Status;
405114237Snjl
406114237Snjl
407114237Snjl    ObjDesc = AcpiNsGetAttachedObject (Node);
408114237Snjl    if (ObjDesc->Method.ParamCount)
409114237Snjl    {
410114237Snjl        return (AE_OK);
411114237Snjl    }
412114237Snjl
413114237Snjl    ReturnObj.Pointer = NULL;
414114237Snjl    ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
415114237Snjl
416114237Snjl    AcpiNsPrintNodePathname (Node, "Execute");
417114237Snjl
418114237Snjl    /* Do the actual method execution */
419114237Snjl
420114237Snjl    AcpiOsPrintf ("\n");
421114237Snjl    AcpiGbl_MethodExecuting = TRUE;
422114237Snjl
423114237Snjl    Status = AcpiEvaluateObject (Node, NULL, NULL, &ReturnObj);
424114237Snjl
425123315Snjl    AcpiOsPrintf ("[%4.4s] returned %s\n", AcpiUtGetNodeName (Node),
426123315Snjl            AcpiFormatException (Status));
427114237Snjl    AcpiGbl_MethodExecuting = FALSE;
428114237Snjl
429114237Snjl    return (AE_OK);
430114237Snjl}
431114237Snjl
432114237Snjl
433114237Snjl/*******************************************************************************
434114237Snjl *
43567754Smsmith * FUNCTION:    AcpiDbExecute
43667754Smsmith *
43767754Smsmith * PARAMETERS:  Name                - Name of method to execute
43867754Smsmith *              Args                - Parameters to the method
43967754Smsmith *              Flags               - single step/no single step
44067754Smsmith *
441151937Sjkim * RETURN:      None
44267754Smsmith *
44367754Smsmith * DESCRIPTION: Execute a control method.  Name is relative to the current
44467754Smsmith *              scope.
44567754Smsmith *
44667754Smsmith ******************************************************************************/
44767754Smsmith
44867754Smsmithvoid
44967754SmsmithAcpiDbExecute (
450114237Snjl    char                    *Name,
451114237Snjl    char                    **Args,
45267754Smsmith    UINT32                  Flags)
45367754Smsmith{
45467754Smsmith    ACPI_STATUS             Status;
45569450Smsmith    ACPI_BUFFER             ReturnObj;
456167802Sjkim    char                    *NameString;
45769450Smsmith
45869450Smsmith
459102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT
46067754Smsmith    UINT32                  PreviousAllocations;
46167754Smsmith    UINT32                  Allocations;
46267754Smsmith
46367754Smsmith
46467754Smsmith    /* Memory allocation tracking */
46567754Smsmith
46682367Smsmith    PreviousAllocations = AcpiDbGetOutstandingAllocations ();
46769450Smsmith#endif
46867754Smsmith
469114237Snjl    if (*Name == '*')
470114237Snjl    {
471151937Sjkim        (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT,
472199337Sjkim                    ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL);
473114237Snjl        return;
474114237Snjl    }
475114237Snjl    else
476114237Snjl    {
477167802Sjkim        NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1);
478167802Sjkim        if (!NameString)
479167802Sjkim        {
480167802Sjkim            return;
481167802Sjkim        }
482167802Sjkim
483167802Sjkim        ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
484167802Sjkim
485167802Sjkim        ACPI_STRCPY (NameString, Name);
486167802Sjkim        AcpiUtStrupr (NameString);
487167802Sjkim        AcpiGbl_DbMethodInfo.Name = NameString;
488114237Snjl        AcpiGbl_DbMethodInfo.Args = Args;
489114237Snjl        AcpiGbl_DbMethodInfo.Flags = Flags;
49067754Smsmith
491114237Snjl        ReturnObj.Pointer = NULL;
492114237Snjl        ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
493100966Siwasaki
494114237Snjl        AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
495114237Snjl        Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj);
496167802Sjkim        ACPI_FREE (NameString);
497114237Snjl    }
49867754Smsmith
49982367Smsmith    /*
50082367Smsmith     * Allow any handlers in separate threads to complete.
50182367Smsmith     * (Such as Notify handlers invoked from AML executed above).
50282367Smsmith     */
503202771Sjkim    AcpiOsSleep ((UINT64) 10);
50467754Smsmith
50582367Smsmith
506102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT
50769450Smsmith
50867754Smsmith    /* Memory allocation tracking */
50967754Smsmith
51082367Smsmith    Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations;
51167754Smsmith
51291116Smsmith    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
51367754Smsmith
51467754Smsmith    if (Allocations > 0)
51567754Smsmith    {
516138287Smarks        AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n",
51782367Smsmith                        Allocations);
51867754Smsmith    }
51969450Smsmith#endif
52067754Smsmith
52167754Smsmith    if (ACPI_FAILURE (Status))
52267754Smsmith    {
52383174Smsmith        AcpiOsPrintf ("Execution of %s failed with status %s\n",
52483174Smsmith            AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status));
52567754Smsmith    }
52667754Smsmith    else
52767754Smsmith    {
52867754Smsmith        /* Display a return object, if any */
52967754Smsmith
53067754Smsmith        if (ReturnObj.Length)
53167754Smsmith        {
53277424Smsmith            AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
533114237Snjl                AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer,
534104470Siwasaki                (UINT32) ReturnObj.Length);
535151937Sjkim            AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
53667754Smsmith        }
537100966Siwasaki        else
538100966Siwasaki        {
539102550Siwasaki            AcpiOsPrintf ("No return object from execution of %s\n",
540100966Siwasaki                AcpiGbl_DbMethodInfo.Pathname);
541100966Siwasaki        }
54267754Smsmith    }
54367754Smsmith
54491116Smsmith    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
54567754Smsmith}
54667754Smsmith
54767754Smsmith
54867754Smsmith/*******************************************************************************
54967754Smsmith *
55067754Smsmith * FUNCTION:    AcpiDbMethodThread
55167754Smsmith *
55267754Smsmith * PARAMETERS:  Context             - Execution info segment
55367754Smsmith *
55467754Smsmith * RETURN:      None
55567754Smsmith *
55667754Smsmith * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
55767754Smsmith *              simply dispatches it.
55867754Smsmith *
55967754Smsmith ******************************************************************************/
56067754Smsmith
561151937Sjkimstatic void ACPI_SYSTEM_XFACE
56267754SmsmithAcpiDbMethodThread (
56367754Smsmith    void                    *Context)
56467754Smsmith{
56567754Smsmith    ACPI_STATUS             Status;
56691116Smsmith    ACPI_DB_METHOD_INFO     *Info = Context;
567193267Sjkim    ACPI_DB_METHOD_INFO     LocalInfo;
56867754Smsmith    UINT32                  i;
569167802Sjkim    UINT8                   Allow;
57067754Smsmith    ACPI_BUFFER             ReturnObj;
57167754Smsmith
57267754Smsmith
573193267Sjkim    /*
574193267Sjkim     * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments.
575193267Sjkim     * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads
576193267Sjkim     * concurrently.
577193267Sjkim     *
578193267Sjkim     * Note: The arguments we are passing are used by the ASL test suite
579193267Sjkim     * (aslts). Do not change them without updating the tests.
580193267Sjkim     */
581193267Sjkim    (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER);
582193267Sjkim
583167802Sjkim    if (Info->InitArgs)
584167802Sjkim    {
585167802Sjkim        AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr);
586212761Sjkim        AcpiDbUInt32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr);
587167802Sjkim    }
588167802Sjkim
589167802Sjkim    if (Info->Threads && (Info->NumCreated < Info->NumThreads))
590167802Sjkim    {
591212761Sjkim        Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId();
592167802Sjkim    }
593167802Sjkim
594193267Sjkim    LocalInfo = *Info;
595193267Sjkim    LocalInfo.Args = LocalInfo.Arguments;
596193267Sjkim    LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr;
597193267Sjkim    LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr;
598193267Sjkim    LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr;
599193267Sjkim    LocalInfo.Arguments[3] = NULL;
600193267Sjkim
601193267Sjkim    (void) AcpiOsSignalSemaphore (Info->InfoGate, 1);
602193267Sjkim
60367754Smsmith    for (i = 0; i < Info->NumLoops; i++)
60467754Smsmith    {
605193267Sjkim        Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj);
606117521Snjl        if (ACPI_FAILURE (Status))
60767754Smsmith        {
608117521Snjl            AcpiOsPrintf ("%s During execution of %s at iteration %X\n",
609117521Snjl                AcpiFormatException (Status), Info->Pathname, i);
610127175Snjl            if (Status == AE_ABORT_METHOD)
611127175Snjl            {
612127175Snjl                break;
613127175Snjl            }
61467754Smsmith        }
615117521Snjl
616167802Sjkim#if 0
617128212Snjl        if ((i % 100) == 0)
618117521Snjl        {
619209746Sjkim            AcpiOsPrintf ("%u executions, Thread 0x%x\n", i, AcpiOsGetThreadId ());
620117521Snjl        }
621117521Snjl
622117521Snjl        if (ReturnObj.Length)
623117521Snjl        {
624117521Snjl            AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
625117521Snjl                Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length);
626151937Sjkim            AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
627117521Snjl        }
628117521Snjl#endif
62967754Smsmith    }
63067754Smsmith
63167754Smsmith    /* Signal our completion */
63267754Smsmith
633167802Sjkim    Allow = 0;
634193267Sjkim    (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER);
635167802Sjkim    Info->NumCompleted++;
636167802Sjkim
637167802Sjkim    if (Info->NumCompleted == Info->NumThreads)
63899679Siwasaki    {
639167802Sjkim        /* Do signal for main thread once only */
640167802Sjkim        Allow = 1;
64199679Siwasaki    }
642167802Sjkim
643193267Sjkim    (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1);
644167802Sjkim
645167802Sjkim    if (Allow)
646167802Sjkim    {
647167802Sjkim        Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1);
648167802Sjkim        if (ACPI_FAILURE (Status))
649167802Sjkim        {
650167802Sjkim            AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n",
651167802Sjkim                AcpiFormatException (Status));
652167802Sjkim        }
653167802Sjkim    }
65467754Smsmith}
65567754Smsmith
65667754Smsmith
65767754Smsmith/*******************************************************************************
65867754Smsmith *
65967754Smsmith * FUNCTION:    AcpiDbCreateExecutionThreads
66067754Smsmith *
66167754Smsmith * PARAMETERS:  NumThreadsArg           - Number of threads to create
66267754Smsmith *              NumLoopsArg             - Loop count for the thread(s)
66367754Smsmith *              MethodNameArg           - Control method to execute
66467754Smsmith *
66567754Smsmith * RETURN:      None
66667754Smsmith *
66767754Smsmith * DESCRIPTION: Create threads to execute method(s)
66867754Smsmith *
66967754Smsmith ******************************************************************************/
67067754Smsmith
67167754Smsmithvoid
67267754SmsmithAcpiDbCreateExecutionThreads (
673114237Snjl    char                    *NumThreadsArg,
674114237Snjl    char                    *NumLoopsArg,
675114237Snjl    char                    *MethodNameArg)
67667754Smsmith{
67767754Smsmith    ACPI_STATUS             Status;
67867754Smsmith    UINT32                  NumThreads;
67967754Smsmith    UINT32                  NumLoops;
68067754Smsmith    UINT32                  i;
681167802Sjkim    UINT32                  Size;
682167802Sjkim    ACPI_MUTEX              MainThreadGate;
683167802Sjkim    ACPI_MUTEX              ThreadCompleteGate;
684193267Sjkim    ACPI_MUTEX              InfoGate;
68567754Smsmith
686193267Sjkim
68767754Smsmith    /* Get the arguments */
68867754Smsmith
68991116Smsmith    NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0);
69091116Smsmith    NumLoops   = ACPI_STRTOUL (NumLoopsArg, NULL, 0);
69167754Smsmith
69267754Smsmith    if (!NumThreads || !NumLoops)
69367754Smsmith    {
694151937Sjkim        AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n",
695151937Sjkim            NumThreads, NumLoops);
69667754Smsmith        return;
69767754Smsmith    }
69867754Smsmith
699167802Sjkim    /*
700167802Sjkim     * Create the semaphore for synchronization of
701167802Sjkim     * the created threads with the main thread.
702167802Sjkim     */
703167802Sjkim    Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate);
704167802Sjkim    if (ACPI_FAILURE (Status))
705167802Sjkim    {
706167802Sjkim        AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n",
707167802Sjkim            AcpiFormatException (Status));
708167802Sjkim        return;
709167802Sjkim    }
71067754Smsmith
711167802Sjkim    /*
712167802Sjkim     * Create the semaphore for synchronization
713167802Sjkim     * between the created threads.
714167802Sjkim     */
715167802Sjkim    Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate);
71667754Smsmith    if (ACPI_FAILURE (Status))
71767754Smsmith    {
718167802Sjkim        AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n",
719151937Sjkim            AcpiFormatException (Status));
720167802Sjkim        (void) AcpiOsDeleteSemaphore (MainThreadGate);
72167754Smsmith        return;
72267754Smsmith    }
72367754Smsmith
724193267Sjkim    Status = AcpiOsCreateSemaphore (1, 1, &InfoGate);
725193267Sjkim    if (ACPI_FAILURE (Status))
726193267Sjkim    {
727193267Sjkim        AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n",
728193267Sjkim            AcpiFormatException (Status));
729193267Sjkim        (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
730193267Sjkim        (void) AcpiOsDeleteSemaphore (MainThreadGate);
731193267Sjkim        return;
732193267Sjkim    }
733193267Sjkim
734167802Sjkim    ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
735167802Sjkim
736167802Sjkim    /* Array to store IDs of threads */
737167802Sjkim
738167802Sjkim    AcpiGbl_DbMethodInfo.NumThreads = NumThreads;
739212761Sjkim    Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads;
740212761Sjkim    AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size);
741167802Sjkim    if (AcpiGbl_DbMethodInfo.Threads == NULL)
742167802Sjkim    {
743167802Sjkim        AcpiOsPrintf ("No memory for thread IDs array\n");
744167802Sjkim        (void) AcpiOsDeleteSemaphore (MainThreadGate);
745167802Sjkim        (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
746193267Sjkim        (void) AcpiOsDeleteSemaphore (InfoGate);
747167802Sjkim        return;
748167802Sjkim    }
749167802Sjkim    ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size);
750167802Sjkim
75167754Smsmith    /* Setup the context to be passed to each thread */
75267754Smsmith
75383174Smsmith    AcpiGbl_DbMethodInfo.Name = MethodNameArg;
75483174Smsmith    AcpiGbl_DbMethodInfo.Flags = 0;
75583174Smsmith    AcpiGbl_DbMethodInfo.NumLoops = NumLoops;
756167802Sjkim    AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate;
757167802Sjkim    AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate;
758193267Sjkim    AcpiGbl_DbMethodInfo.InfoGate = InfoGate;
75967754Smsmith
760167802Sjkim    /* Init arguments to be passed to method */
761167802Sjkim
762167802Sjkim    AcpiGbl_DbMethodInfo.InitArgs = 1;
763167802Sjkim    AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments;
764167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr;
765167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr;
766167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr;
767167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[3] = NULL;
768167802Sjkim    AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr);
769167802Sjkim
77083174Smsmith    AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
77167754Smsmith
77267754Smsmith    /* Create the threads */
77367754Smsmith
774151937Sjkim    AcpiOsPrintf ("Creating %X threads to execute %X times each\n",
775151937Sjkim        NumThreads, NumLoops);
77667754Smsmith
77767754Smsmith    for (i = 0; i < (NumThreads); i++)
77867754Smsmith    {
779167802Sjkim        Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread,
780151937Sjkim            &AcpiGbl_DbMethodInfo);
78199679Siwasaki        if (ACPI_FAILURE (Status))
78299679Siwasaki        {
78399679Siwasaki            break;
78499679Siwasaki        }
78567754Smsmith    }
78667754Smsmith
78767754Smsmith    /* Wait for all threads to complete */
78867754Smsmith
789193267Sjkim    (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER);
79067754Smsmith
791167802Sjkim    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
792167802Sjkim    AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads);
793167802Sjkim    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
794167802Sjkim
79567754Smsmith    /* Cleanup and exit */
79667754Smsmith
797167802Sjkim    (void) AcpiOsDeleteSemaphore (MainThreadGate);
798167802Sjkim    (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
799193267Sjkim    (void) AcpiOsDeleteSemaphore (InfoGate);
80067754Smsmith
801167802Sjkim    AcpiOsFree (AcpiGbl_DbMethodInfo.Threads);
802167802Sjkim    AcpiGbl_DbMethodInfo.Threads = NULL;
80367754Smsmith}
80467754Smsmith
805102550Siwasaki#endif /* ACPI_DEBUGGER */
80667754Smsmith
80767754Smsmith
808