dbexec.c revision 222544
167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dbexec - debugger control method execution
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
7217365Sjkim/*
8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
4467754Smsmith
45193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
46193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
47193341Sjkim#include <contrib/dev/acpica/include/acdebug.h>
48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
4967754Smsmith
50102550Siwasaki#ifdef ACPI_DEBUGGER
5167754Smsmith
52102550Siwasaki#define _COMPONENT          ACPI_CA_DEBUGGER
5391116Smsmith        ACPI_MODULE_NAME    ("dbexec")
5467754Smsmith
5567754Smsmith
56222544Sjkimstatic ACPI_DB_METHOD_INFO          AcpiGbl_DbMethodInfo;
57222544Sjkim#define DB_DEFAULT_PKG_ELEMENTS     33
5867754Smsmith
59151937Sjkim/* Local prototypes */
6067754Smsmith
61151937Sjkimstatic ACPI_STATUS
62151937SjkimAcpiDbExecuteMethod (
63151937Sjkim    ACPI_DB_METHOD_INFO     *Info,
64151937Sjkim    ACPI_BUFFER             *ReturnObj);
65151937Sjkim
66151937Sjkimstatic void
67151937SjkimAcpiDbExecuteSetup (
68151937Sjkim    ACPI_DB_METHOD_INFO     *Info);
69151937Sjkim
70151937Sjkimstatic UINT32
71151937SjkimAcpiDbGetOutstandingAllocations (
72151937Sjkim    void);
73151937Sjkim
74151937Sjkimstatic void ACPI_SYSTEM_XFACE
75151937SjkimAcpiDbMethodThread (
76151937Sjkim    void                    *Context);
77151937Sjkim
78151937Sjkimstatic ACPI_STATUS
79151937SjkimAcpiDbExecutionWalk (
80151937Sjkim    ACPI_HANDLE             ObjHandle,
81151937Sjkim    UINT32                  NestingLevel,
82151937Sjkim    void                    *Context,
83151937Sjkim    void                    **ReturnValue);
84151937Sjkim
85222544Sjkimstatic ACPI_STATUS
86222544SjkimAcpiDbHexCharToValue (
87222544Sjkim    int                     HexChar,
88222544Sjkim    UINT8                   *ReturnValue);
89151937Sjkim
90222544Sjkimstatic ACPI_STATUS
91222544SjkimAcpiDbConvertToPackage (
92222544Sjkim    char                    *String,
93222544Sjkim    ACPI_OBJECT             *Object);
94222544Sjkim
95222544Sjkimstatic ACPI_STATUS
96222544SjkimAcpiDbConvertToObject (
97222544Sjkim    ACPI_OBJECT_TYPE        Type,
98222544Sjkim    char                    *String,
99222544Sjkim    ACPI_OBJECT             *Object);
100222544Sjkim
101222544Sjkimstatic void
102222544SjkimAcpiDbDeleteObjects (
103222544Sjkim    UINT32                  Count,
104222544Sjkim    ACPI_OBJECT             *Objects);
105222544Sjkim
106222544Sjkim
10767754Smsmith/*******************************************************************************
10867754Smsmith *
109222544Sjkim * FUNCTION:    AcpiDbHexCharToValue
110222544Sjkim *
111222544Sjkim * PARAMETERS:  HexChar             - Ascii Hex digit, 0-9|a-f|A-F
112222544Sjkim *              ReturnValue         - Where the converted value is returned
113222544Sjkim *
114222544Sjkim * RETURN:      Status
115222544Sjkim *
116222544Sjkim * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16).
117222544Sjkim *
118222544Sjkim ******************************************************************************/
119222544Sjkim
120222544Sjkimstatic ACPI_STATUS
121222544SjkimAcpiDbHexCharToValue (
122222544Sjkim    int                     HexChar,
123222544Sjkim    UINT8                   *ReturnValue)
124222544Sjkim{
125222544Sjkim    UINT8                   Value;
126222544Sjkim
127222544Sjkim
128222544Sjkim    /* Digit must be ascii [0-9a-fA-F] */
129222544Sjkim
130222544Sjkim    if (!ACPI_IS_XDIGIT (HexChar))
131222544Sjkim    {
132222544Sjkim        return (AE_BAD_HEX_CONSTANT);
133222544Sjkim    }
134222544Sjkim
135222544Sjkim    if (HexChar <= 0x39)
136222544Sjkim    {
137222544Sjkim        Value = (UINT8) (HexChar - 0x30);
138222544Sjkim    }
139222544Sjkim    else
140222544Sjkim    {
141222544Sjkim        Value = (UINT8) (ACPI_TOUPPER (HexChar) - 0x37);
142222544Sjkim    }
143222544Sjkim
144222544Sjkim    *ReturnValue = Value;
145222544Sjkim    return (AE_OK);
146222544Sjkim}
147222544Sjkim
148222544Sjkim
149222544Sjkim/*******************************************************************************
150222544Sjkim *
151222544Sjkim * FUNCTION:    AcpiDbHexByteToBinary
152222544Sjkim *
153222544Sjkim * PARAMETERS:  HexByte             - Double hex digit (0x00 - 0xFF) in format:
154222544Sjkim *                                    HiByte then LoByte.
155222544Sjkim *              ReturnValue         - Where the converted value is returned
156222544Sjkim *
157222544Sjkim * RETURN:      Status
158222544Sjkim *
159222544Sjkim * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255).
160222544Sjkim *
161222544Sjkim ******************************************************************************/
162222544Sjkim
163222544Sjkimstatic ACPI_STATUS
164222544SjkimAcpiDbHexByteToBinary (
165222544Sjkim    char                    *HexByte,
166222544Sjkim    UINT8                   *ReturnValue)
167222544Sjkim{
168222544Sjkim    UINT8                   Local0;
169222544Sjkim    UINT8                   Local1;
170222544Sjkim    ACPI_STATUS             Status;
171222544Sjkim
172222544Sjkim
173222544Sjkim    /* High byte */
174222544Sjkim
175222544Sjkim    Status = AcpiDbHexCharToValue (HexByte[0], &Local0);
176222544Sjkim    if (ACPI_FAILURE (Status))
177222544Sjkim    {
178222544Sjkim        return (Status);
179222544Sjkim    }
180222544Sjkim
181222544Sjkim    /* Low byte */
182222544Sjkim
183222544Sjkim    Status = AcpiDbHexCharToValue (HexByte[1], &Local1);
184222544Sjkim    if (ACPI_FAILURE (Status))
185222544Sjkim    {
186222544Sjkim        return (Status);
187222544Sjkim    }
188222544Sjkim
189222544Sjkim    *ReturnValue = (UINT8) ((Local0 << 4) | Local1);
190222544Sjkim    return (AE_OK);
191222544Sjkim}
192222544Sjkim
193222544Sjkim
194222544Sjkim/*******************************************************************************
195222544Sjkim *
196222544Sjkim * FUNCTION:    AcpiDbConvertToBuffer
197222544Sjkim *
198222544Sjkim * PARAMETERS:  String              - Input string to be converted
199222544Sjkim *              Object              - Where the buffer object is returned
200222544Sjkim *
201222544Sjkim * RETURN:      Status
202222544Sjkim *
203222544Sjkim * DESCRIPTION: Convert a string to a buffer object. String is treated a list
204222544Sjkim *              of buffer elements, each separated by a space or comma.
205222544Sjkim *
206222544Sjkim ******************************************************************************/
207222544Sjkim
208222544Sjkimstatic ACPI_STATUS
209222544SjkimAcpiDbConvertToBuffer (
210222544Sjkim    char                    *String,
211222544Sjkim    ACPI_OBJECT             *Object)
212222544Sjkim{
213222544Sjkim    UINT32                  i;
214222544Sjkim    UINT32                  j;
215222544Sjkim    UINT32                  Length;
216222544Sjkim    UINT8                   *Buffer;
217222544Sjkim    ACPI_STATUS             Status;
218222544Sjkim
219222544Sjkim
220222544Sjkim    /* Generate the final buffer length */
221222544Sjkim
222222544Sjkim    for (i = 0, Length = 0; String[i];)
223222544Sjkim    {
224222544Sjkim        i+=2;
225222544Sjkim        Length++;
226222544Sjkim
227222544Sjkim        while (String[i] &&
228222544Sjkim              ((String[i] == ',') || (String[i] == ' ')))
229222544Sjkim        {
230222544Sjkim            i++;
231222544Sjkim        }
232222544Sjkim    }
233222544Sjkim
234222544Sjkim    Buffer = ACPI_ALLOCATE (Length);
235222544Sjkim    if (!Buffer)
236222544Sjkim    {
237222544Sjkim        return (AE_NO_MEMORY);
238222544Sjkim    }
239222544Sjkim
240222544Sjkim    /* Convert the command line bytes to the buffer */
241222544Sjkim
242222544Sjkim    for (i = 0, j = 0; String[i];)
243222544Sjkim    {
244222544Sjkim        Status = AcpiDbHexByteToBinary (&String[i], &Buffer[j]);
245222544Sjkim        if (ACPI_FAILURE (Status))
246222544Sjkim        {
247222544Sjkim            ACPI_FREE (Buffer);
248222544Sjkim            return (Status);
249222544Sjkim        }
250222544Sjkim
251222544Sjkim        j++;
252222544Sjkim        i+=2;
253222544Sjkim        while (String[i] &&
254222544Sjkim              ((String[i] == ',') || (String[i] == ' ')))
255222544Sjkim        {
256222544Sjkim            i++;
257222544Sjkim        }
258222544Sjkim    }
259222544Sjkim
260222544Sjkim    Object->Type = ACPI_TYPE_BUFFER;
261222544Sjkim    Object->Buffer.Pointer = Buffer;
262222544Sjkim    Object->Buffer.Length = Length;
263222544Sjkim    return (AE_OK);
264222544Sjkim}
265222544Sjkim
266222544Sjkim
267222544Sjkim/*******************************************************************************
268222544Sjkim *
269222544Sjkim * FUNCTION:    AcpiDbConvertToPackage
270222544Sjkim *
271222544Sjkim * PARAMETERS:  String              - Input string to be converted
272222544Sjkim *              Object              - Where the package object is returned
273222544Sjkim *
274222544Sjkim * RETURN:      Status
275222544Sjkim *
276222544Sjkim * DESCRIPTION: Convert a string to a package object. Handles nested packages
277222544Sjkim *              via recursion with AcpiDbConvertToObject.
278222544Sjkim *
279222544Sjkim ******************************************************************************/
280222544Sjkim
281222544Sjkimstatic ACPI_STATUS
282222544SjkimAcpiDbConvertToPackage (
283222544Sjkim    char                    *String,
284222544Sjkim    ACPI_OBJECT             *Object)
285222544Sjkim{
286222544Sjkim    char                    *This;
287222544Sjkim    char                    *Next;
288222544Sjkim    UINT32                  i;
289222544Sjkim    ACPI_OBJECT_TYPE        Type;
290222544Sjkim    ACPI_OBJECT             *Elements;
291222544Sjkim    ACPI_STATUS             Status;
292222544Sjkim
293222544Sjkim
294222544Sjkim    Elements = ACPI_ALLOCATE_ZEROED (
295222544Sjkim        DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT));
296222544Sjkim
297222544Sjkim    This = String;
298222544Sjkim    for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++)
299222544Sjkim    {
300222544Sjkim        This = AcpiDbGetNextToken (This, &Next, &Type);
301222544Sjkim        if (!This)
302222544Sjkim        {
303222544Sjkim            break;
304222544Sjkim        }
305222544Sjkim
306222544Sjkim        /* Recursive call to convert each package element */
307222544Sjkim
308222544Sjkim        Status = AcpiDbConvertToObject (Type, This, &Elements[i]);
309222544Sjkim        if (ACPI_FAILURE (Status))
310222544Sjkim        {
311222544Sjkim            AcpiDbDeleteObjects (i + 1, Elements);
312222544Sjkim            ACPI_FREE (Elements);
313222544Sjkim            return (Status);
314222544Sjkim        }
315222544Sjkim
316222544Sjkim        This = Next;
317222544Sjkim    }
318222544Sjkim
319222544Sjkim    Object->Type = ACPI_TYPE_PACKAGE;
320222544Sjkim    Object->Package.Count = i;
321222544Sjkim    Object->Package.Elements = Elements;
322222544Sjkim    return (AE_OK);
323222544Sjkim}
324222544Sjkim
325222544Sjkim
326222544Sjkim/*******************************************************************************
327222544Sjkim *
328222544Sjkim * FUNCTION:    AcpiDbConvertToObject
329222544Sjkim *
330222544Sjkim * PARAMETERS:  Type                - Object type as determined by parser
331222544Sjkim *              String              - Input string to be converted
332222544Sjkim *              Object              - Where the new object is returned
333222544Sjkim *
334222544Sjkim * RETURN:      Status
335222544Sjkim *
336222544Sjkim * DESCRIPTION: Convert a typed and tokenized string to an ACPI_OBJECT. Typing:
337222544Sjkim *              1) String objects were surrounded by quotes.
338222544Sjkim *              2) Buffer objects were surrounded by parentheses.
339222544Sjkim *              3) Package objects were surrounded by brackets "[]".
340222544Sjkim *              4) All standalone tokens are treated as integers.
341222544Sjkim *
342222544Sjkim ******************************************************************************/
343222544Sjkim
344222544Sjkimstatic ACPI_STATUS
345222544SjkimAcpiDbConvertToObject (
346222544Sjkim    ACPI_OBJECT_TYPE        Type,
347222544Sjkim    char                    *String,
348222544Sjkim    ACPI_OBJECT             *Object)
349222544Sjkim{
350222544Sjkim    ACPI_STATUS             Status = AE_OK;
351222544Sjkim
352222544Sjkim
353222544Sjkim    switch (Type)
354222544Sjkim    {
355222544Sjkim    case ACPI_TYPE_STRING:
356222544Sjkim        Object->Type = ACPI_TYPE_STRING;
357222544Sjkim        Object->String.Pointer = String;
358222544Sjkim        Object->String.Length = (UINT32) ACPI_STRLEN (String);
359222544Sjkim        break;
360222544Sjkim
361222544Sjkim    case ACPI_TYPE_BUFFER:
362222544Sjkim        Status = AcpiDbConvertToBuffer (String, Object);
363222544Sjkim        break;
364222544Sjkim
365222544Sjkim    case ACPI_TYPE_PACKAGE:
366222544Sjkim        Status = AcpiDbConvertToPackage (String, Object);
367222544Sjkim        break;
368222544Sjkim
369222544Sjkim    default:
370222544Sjkim        Object->Type = ACPI_TYPE_INTEGER;
371222544Sjkim        Status = AcpiUtStrtoul64 (String, 16, &Object->Integer.Value);
372222544Sjkim        break;
373222544Sjkim    }
374222544Sjkim
375222544Sjkim    return (Status);
376222544Sjkim}
377222544Sjkim
378222544Sjkim
379222544Sjkim/*******************************************************************************
380222544Sjkim *
381222544Sjkim * FUNCTION:    AcpiDbDeleteObjects
382222544Sjkim *
383222544Sjkim * PARAMETERS:  Count               - Count of objects in the list
384222544Sjkim *              Objects             - Array of ACPI_OBJECTs to be deleted
385222544Sjkim *
386222544Sjkim * RETURN:      None
387222544Sjkim *
388222544Sjkim * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested
389222544Sjkim *              packages via recursion.
390222544Sjkim *
391222544Sjkim ******************************************************************************/
392222544Sjkim
393222544Sjkimstatic void
394222544SjkimAcpiDbDeleteObjects (
395222544Sjkim    UINT32                  Count,
396222544Sjkim    ACPI_OBJECT             *Objects)
397222544Sjkim{
398222544Sjkim    UINT32                  i;
399222544Sjkim
400222544Sjkim
401222544Sjkim    for (i = 0; i < Count; i++)
402222544Sjkim    {
403222544Sjkim        switch (Objects[i].Type)
404222544Sjkim        {
405222544Sjkim        case ACPI_TYPE_BUFFER:
406222544Sjkim            ACPI_FREE (Objects[i].Buffer.Pointer);
407222544Sjkim            break;
408222544Sjkim
409222544Sjkim        case ACPI_TYPE_PACKAGE:
410222544Sjkim
411222544Sjkim            /* Recursive call to delete package elements */
412222544Sjkim
413222544Sjkim            AcpiDbDeleteObjects (Objects[i].Package.Count,
414222544Sjkim                Objects[i].Package.Elements);
415222544Sjkim
416222544Sjkim            /* Free the elements array */
417222544Sjkim
418222544Sjkim            ACPI_FREE (Objects[i].Package.Elements);
419222544Sjkim            break;
420222544Sjkim
421222544Sjkim        default:
422222544Sjkim            break;
423222544Sjkim        }
424222544Sjkim    }
425222544Sjkim}
426222544Sjkim
427222544Sjkim
428222544Sjkim/*******************************************************************************
429222544Sjkim *
43067754Smsmith * FUNCTION:    AcpiDbExecuteMethod
43167754Smsmith *
43267754Smsmith * PARAMETERS:  Info            - Valid info segment
43367754Smsmith *              ReturnObj       - Where to put return object
43467754Smsmith *
43567754Smsmith * RETURN:      Status
43667754Smsmith *
43767754Smsmith * DESCRIPTION: Execute a control method.
43867754Smsmith *
43967754Smsmith ******************************************************************************/
44067754Smsmith
441151937Sjkimstatic ACPI_STATUS
44267754SmsmithAcpiDbExecuteMethod (
44391116Smsmith    ACPI_DB_METHOD_INFO     *Info,
44467754Smsmith    ACPI_BUFFER             *ReturnObj)
44567754Smsmith{
44667754Smsmith    ACPI_STATUS             Status;
44767754Smsmith    ACPI_OBJECT_LIST        ParamObjects;
448114237Snjl    ACPI_OBJECT             Params[ACPI_METHOD_NUM_ARGS];
449193267Sjkim    ACPI_HANDLE             Handle;
450222544Sjkim    ACPI_DEVICE_INFO        *ObjInfo;
45167754Smsmith    UINT32                  i;
45267754Smsmith
45367754Smsmith
454216471Sjkim    ACPI_FUNCTION_TRACE (DbExecuteMethod);
455216471Sjkim
456216471Sjkim
45783174Smsmith    if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel)
45867754Smsmith    {
45967754Smsmith        AcpiOsPrintf ("Warning: debug output is not enabled!\n");
46067754Smsmith    }
46167754Smsmith
462193267Sjkim    /* Get the NS node, determines existence also */
46367754Smsmith
464193267Sjkim    Status = AcpiGetHandle (NULL, Info->Pathname, &Handle);
465193267Sjkim    if (ACPI_FAILURE (Status))
46667754Smsmith    {
467216471Sjkim        return_ACPI_STATUS (Status);
468193267Sjkim    }
46967754Smsmith
470193267Sjkim    /* Get the object info for number of method parameters */
471193267Sjkim
472197104Sjkim    Status = AcpiGetObjectInfo (Handle, &ObjInfo);
473193267Sjkim    if (ACPI_FAILURE (Status))
474193267Sjkim    {
475216471Sjkim        return_ACPI_STATUS (Status);
47667754Smsmith    }
477193267Sjkim
478193267Sjkim    ParamObjects.Pointer = NULL;
479193267Sjkim    ParamObjects.Count   = 0;
480193267Sjkim
481193267Sjkim    if (ObjInfo->Type == ACPI_TYPE_METHOD)
48267754Smsmith    {
483193267Sjkim        /* Are there arguments to the method? */
48467754Smsmith
485222544Sjkim        i = 0;
486193267Sjkim        if (Info->Args && Info->Args[0])
487193267Sjkim        {
488222544Sjkim            /* Get arguments passed on the command line */
489222544Sjkim
490222544Sjkim            for (; Info->Args[i] &&
491217365Sjkim                (i < ACPI_METHOD_NUM_ARGS) &&
492217365Sjkim                (i < ObjInfo->ParamCount);
493217365Sjkim                i++)
494193267Sjkim            {
495222544Sjkim                /* Convert input string (token) to an actual ACPI_OBJECT */
496222544Sjkim
497222544Sjkim                Status = AcpiDbConvertToObject (Info->Types[i],
498222544Sjkim                    Info->Args[i], &Params[i]);
499222544Sjkim                if (ACPI_FAILURE (Status))
500222544Sjkim                {
501222544Sjkim                    ACPI_EXCEPTION ((AE_INFO, Status,
502222544Sjkim                        "While parsing method arguments"));
503222544Sjkim                    goto Cleanup;
504222544Sjkim                }
505193267Sjkim            }
506222544Sjkim        }
50767754Smsmith
508222544Sjkim        /* Create additional "default" parameters as needed */
509222544Sjkim
510222544Sjkim        if (i < ObjInfo->ParamCount)
511193267Sjkim        {
512222544Sjkim            AcpiOsPrintf ("Adding %u arguments containing default values\n",
513222544Sjkim                ObjInfo->ParamCount - i);
51467754Smsmith
515222544Sjkim            for (; i < ObjInfo->ParamCount; i++)
516193267Sjkim            {
517193267Sjkim                switch (i)
518193267Sjkim                {
519193267Sjkim                case 0:
520193267Sjkim
521193267Sjkim                    Params[0].Type           = ACPI_TYPE_INTEGER;
522193267Sjkim                    Params[0].Integer.Value  = 0x01020304;
523193267Sjkim                    break;
524193267Sjkim
525193267Sjkim                case 1:
526193267Sjkim
527193267Sjkim                    Params[1].Type           = ACPI_TYPE_STRING;
528193267Sjkim                    Params[1].String.Length  = 12;
529193267Sjkim                    Params[1].String.Pointer = "AML Debugger";
530193267Sjkim                    break;
531193267Sjkim
532193267Sjkim                default:
533193267Sjkim
534193267Sjkim                    Params[i].Type           = ACPI_TYPE_INTEGER;
535202771Sjkim                    Params[i].Integer.Value  = i * (UINT64) 0x1000;
536193267Sjkim                    break;
537193267Sjkim                }
538193267Sjkim            }
539222544Sjkim        }
540193267Sjkim
541222544Sjkim        ParamObjects.Count = ObjInfo->ParamCount;
542222544Sjkim        ParamObjects.Pointer = Params;
54367754Smsmith    }
54467754Smsmith
54567754Smsmith    /* Prepare for a return object of arbitrary size */
54667754Smsmith
547151937Sjkim    ReturnObj->Pointer = AcpiGbl_DbBuffer;
548151937Sjkim    ReturnObj->Length  = ACPI_DEBUG_BUFFER_SIZE;
54967754Smsmith
55067754Smsmith    /* Do the actual method execution */
55167754Smsmith
552114237Snjl    AcpiGbl_MethodExecuting = TRUE;
553151937Sjkim    Status = AcpiEvaluateObject (NULL,
554222544Sjkim        Info->Pathname, &ParamObjects, ReturnObj);
55567754Smsmith
55667754Smsmith    AcpiGbl_CmSingleStep = FALSE;
55767754Smsmith    AcpiGbl_MethodExecuting = FALSE;
55867754Smsmith
559216471Sjkim    if (ACPI_FAILURE (Status))
560216471Sjkim    {
561216471Sjkim        ACPI_EXCEPTION ((AE_INFO, Status,
562222544Sjkim            "while executing %s from debugger", Info->Pathname));
563216471Sjkim
564216471Sjkim        if (Status == AE_BUFFER_OVERFLOW)
565216471Sjkim        {
566216471Sjkim            ACPI_ERROR ((AE_INFO,
567222544Sjkim                "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)",
568216471Sjkim                ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length));
569216471Sjkim        }
570216471Sjkim    }
571216471Sjkim
572222544SjkimCleanup:
573222544Sjkim    AcpiDbDeleteObjects (ObjInfo->ParamCount, Params);
574222544Sjkim    ACPI_FREE (ObjInfo);
575222544Sjkim
576216471Sjkim    return_ACPI_STATUS (Status);
57767754Smsmith}
57867754Smsmith
57967754Smsmith
58067754Smsmith/*******************************************************************************
58167754Smsmith *
58267754Smsmith * FUNCTION:    AcpiDbExecuteSetup
58367754Smsmith *
58467754Smsmith * PARAMETERS:  Info            - Valid method info
58567754Smsmith *
586151937Sjkim * RETURN:      None
58767754Smsmith *
58867754Smsmith * DESCRIPTION: Setup info segment prior to method execution
58967754Smsmith *
59067754Smsmith ******************************************************************************/
59167754Smsmith
592151937Sjkimstatic void
59367754SmsmithAcpiDbExecuteSetup (
59499679Siwasaki    ACPI_DB_METHOD_INFO     *Info)
59567754Smsmith{
59667754Smsmith
59767754Smsmith    /* Catenate the current scope to the supplied name */
59867754Smsmith
59967754Smsmith    Info->Pathname[0] = 0;
60067754Smsmith    if ((Info->Name[0] != '\\') &&
60167754Smsmith        (Info->Name[0] != '/'))
60267754Smsmith    {
60391116Smsmith        ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf);
60467754Smsmith    }
60567754Smsmith
60691116Smsmith    ACPI_STRCAT (Info->Pathname, Info->Name);
60767754Smsmith    AcpiDbPrepNamestring (Info->Pathname);
60867754Smsmith
60991116Smsmith    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
61067754Smsmith    AcpiOsPrintf ("Executing %s\n", Info->Pathname);
61167754Smsmith
61267754Smsmith    if (Info->Flags & EX_SINGLE_STEP)
61367754Smsmith    {
61467754Smsmith        AcpiGbl_CmSingleStep = TRUE;
61591116Smsmith        AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
61667754Smsmith    }
61767754Smsmith
61867754Smsmith    else
61967754Smsmith    {
62067754Smsmith        /* No single step, allow redirection to a file */
62167754Smsmith
62291116Smsmith        AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
62367754Smsmith    }
62467754Smsmith}
62567754Smsmith
62667754Smsmith
627151937Sjkim#ifdef ACPI_DBG_TRACK_ALLOCATIONS
628167802SjkimUINT32
629151937SjkimAcpiDbGetCacheInfo (
630151937Sjkim    ACPI_MEMORY_LIST        *Cache)
631151937Sjkim{
632151937Sjkim
633151937Sjkim    return (Cache->TotalAllocated - Cache->TotalFreed - Cache->CurrentDepth);
634151937Sjkim}
635151937Sjkim#endif
636151937Sjkim
63767754Smsmith/*******************************************************************************
63867754Smsmith *
63982367Smsmith * FUNCTION:    AcpiDbGetOutstandingAllocations
64082367Smsmith *
64182367Smsmith * PARAMETERS:  None
64282367Smsmith *
64382367Smsmith * RETURN:      Current global allocation count minus cache entries
64482367Smsmith *
64582367Smsmith * DESCRIPTION: Determine the current number of "outstanding" allocations --
64682367Smsmith *              those allocations that have not been freed and also are not
64782367Smsmith *              in one of the various object caches.
64882367Smsmith *
64982367Smsmith ******************************************************************************/
65082367Smsmith
651151937Sjkimstatic UINT32
65299679SiwasakiAcpiDbGetOutstandingAllocations (
65399679Siwasaki    void)
65482367Smsmith{
65582367Smsmith    UINT32                  Outstanding = 0;
65682367Smsmith
65782367Smsmith#ifdef ACPI_DBG_TRACK_ALLOCATIONS
65882367Smsmith
659151937Sjkim    Outstanding += AcpiDbGetCacheInfo (AcpiGbl_StateCache);
660151937Sjkim    Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeCache);
661151937Sjkim    Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeExtCache);
662151937Sjkim    Outstanding += AcpiDbGetCacheInfo (AcpiGbl_OperandCache);
66382367Smsmith#endif
66482367Smsmith
66582367Smsmith    return (Outstanding);
66682367Smsmith}
66782367Smsmith
66882367Smsmith
66982367Smsmith/*******************************************************************************
67082367Smsmith *
671114237Snjl * FUNCTION:    AcpiDbExecutionWalk
672114237Snjl *
673114237Snjl * PARAMETERS:  WALK_CALLBACK
674114237Snjl *
675114237Snjl * RETURN:      Status
676114237Snjl *
677114237Snjl * DESCRIPTION: Execute a control method.  Name is relative to the current
678114237Snjl *              scope.
679114237Snjl *
680114237Snjl ******************************************************************************/
681114237Snjl
682151937Sjkimstatic ACPI_STATUS
683114237SnjlAcpiDbExecutionWalk (
684114237Snjl    ACPI_HANDLE             ObjHandle,
685114237Snjl    UINT32                  NestingLevel,
686114237Snjl    void                    *Context,
687114237Snjl    void                    **ReturnValue)
688114237Snjl{
689114237Snjl    ACPI_OPERAND_OBJECT     *ObjDesc;
690114237Snjl    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
691114237Snjl    ACPI_BUFFER             ReturnObj;
692114237Snjl    ACPI_STATUS             Status;
693114237Snjl
694114237Snjl
695114237Snjl    ObjDesc = AcpiNsGetAttachedObject (Node);
696114237Snjl    if (ObjDesc->Method.ParamCount)
697114237Snjl    {
698114237Snjl        return (AE_OK);
699114237Snjl    }
700114237Snjl
701114237Snjl    ReturnObj.Pointer = NULL;
702114237Snjl    ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
703114237Snjl
704114237Snjl    AcpiNsPrintNodePathname (Node, "Execute");
705114237Snjl
706114237Snjl    /* Do the actual method execution */
707114237Snjl
708114237Snjl    AcpiOsPrintf ("\n");
709114237Snjl    AcpiGbl_MethodExecuting = TRUE;
710114237Snjl
711114237Snjl    Status = AcpiEvaluateObject (Node, NULL, NULL, &ReturnObj);
712114237Snjl
713123315Snjl    AcpiOsPrintf ("[%4.4s] returned %s\n", AcpiUtGetNodeName (Node),
714123315Snjl            AcpiFormatException (Status));
715114237Snjl    AcpiGbl_MethodExecuting = FALSE;
716114237Snjl
717114237Snjl    return (AE_OK);
718114237Snjl}
719114237Snjl
720114237Snjl
721114237Snjl/*******************************************************************************
722114237Snjl *
72367754Smsmith * FUNCTION:    AcpiDbExecute
72467754Smsmith *
72567754Smsmith * PARAMETERS:  Name                - Name of method to execute
72667754Smsmith *              Args                - Parameters to the method
72767754Smsmith *              Flags               - single step/no single step
72867754Smsmith *
729151937Sjkim * RETURN:      None
73067754Smsmith *
73167754Smsmith * DESCRIPTION: Execute a control method.  Name is relative to the current
73267754Smsmith *              scope.
73367754Smsmith *
73467754Smsmith ******************************************************************************/
73567754Smsmith
73667754Smsmithvoid
73767754SmsmithAcpiDbExecute (
738114237Snjl    char                    *Name,
739114237Snjl    char                    **Args,
740222544Sjkim    ACPI_OBJECT_TYPE        *Types,
74167754Smsmith    UINT32                  Flags)
74267754Smsmith{
74367754Smsmith    ACPI_STATUS             Status;
74469450Smsmith    ACPI_BUFFER             ReturnObj;
745167802Sjkim    char                    *NameString;
74669450Smsmith
74769450Smsmith
748102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT
74967754Smsmith    UINT32                  PreviousAllocations;
75067754Smsmith    UINT32                  Allocations;
75167754Smsmith
75267754Smsmith
75367754Smsmith    /* Memory allocation tracking */
75467754Smsmith
75582367Smsmith    PreviousAllocations = AcpiDbGetOutstandingAllocations ();
75669450Smsmith#endif
75767754Smsmith
758114237Snjl    if (*Name == '*')
759114237Snjl    {
760151937Sjkim        (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT,
761199337Sjkim                    ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL);
762114237Snjl        return;
763114237Snjl    }
764114237Snjl    else
765114237Snjl    {
766167802Sjkim        NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1);
767167802Sjkim        if (!NameString)
768167802Sjkim        {
769167802Sjkim            return;
770167802Sjkim        }
771167802Sjkim
772167802Sjkim        ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
773167802Sjkim
774167802Sjkim        ACPI_STRCPY (NameString, Name);
775167802Sjkim        AcpiUtStrupr (NameString);
776167802Sjkim        AcpiGbl_DbMethodInfo.Name = NameString;
777114237Snjl        AcpiGbl_DbMethodInfo.Args = Args;
778222544Sjkim        AcpiGbl_DbMethodInfo.Types = Types;
779114237Snjl        AcpiGbl_DbMethodInfo.Flags = Flags;
78067754Smsmith
781114237Snjl        ReturnObj.Pointer = NULL;
782114237Snjl        ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
783100966Siwasaki
784114237Snjl        AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
785114237Snjl        Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj);
786167802Sjkim        ACPI_FREE (NameString);
787114237Snjl    }
78867754Smsmith
78982367Smsmith    /*
79082367Smsmith     * Allow any handlers in separate threads to complete.
79182367Smsmith     * (Such as Notify handlers invoked from AML executed above).
79282367Smsmith     */
793202771Sjkim    AcpiOsSleep ((UINT64) 10);
79467754Smsmith
79582367Smsmith
796102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT
79769450Smsmith
79867754Smsmith    /* Memory allocation tracking */
79967754Smsmith
80082367Smsmith    Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations;
80167754Smsmith
80291116Smsmith    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
80367754Smsmith
80467754Smsmith    if (Allocations > 0)
80567754Smsmith    {
806138287Smarks        AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n",
80782367Smsmith                        Allocations);
80867754Smsmith    }
80969450Smsmith#endif
81067754Smsmith
81167754Smsmith    if (ACPI_FAILURE (Status))
81267754Smsmith    {
81383174Smsmith        AcpiOsPrintf ("Execution of %s failed with status %s\n",
81483174Smsmith            AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status));
81567754Smsmith    }
81667754Smsmith    else
81767754Smsmith    {
81867754Smsmith        /* Display a return object, if any */
81967754Smsmith
82067754Smsmith        if (ReturnObj.Length)
82167754Smsmith        {
82277424Smsmith            AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
823114237Snjl                AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer,
824104470Siwasaki                (UINT32) ReturnObj.Length);
825151937Sjkim            AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
82667754Smsmith        }
827100966Siwasaki        else
828100966Siwasaki        {
829102550Siwasaki            AcpiOsPrintf ("No return object from execution of %s\n",
830100966Siwasaki                AcpiGbl_DbMethodInfo.Pathname);
831100966Siwasaki        }
83267754Smsmith    }
83367754Smsmith
83491116Smsmith    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
83567754Smsmith}
83667754Smsmith
83767754Smsmith
83867754Smsmith/*******************************************************************************
83967754Smsmith *
84067754Smsmith * FUNCTION:    AcpiDbMethodThread
84167754Smsmith *
84267754Smsmith * PARAMETERS:  Context             - Execution info segment
84367754Smsmith *
84467754Smsmith * RETURN:      None
84567754Smsmith *
84667754Smsmith * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
84767754Smsmith *              simply dispatches it.
84867754Smsmith *
84967754Smsmith ******************************************************************************/
85067754Smsmith
851151937Sjkimstatic void ACPI_SYSTEM_XFACE
85267754SmsmithAcpiDbMethodThread (
85367754Smsmith    void                    *Context)
85467754Smsmith{
85567754Smsmith    ACPI_STATUS             Status;
85691116Smsmith    ACPI_DB_METHOD_INFO     *Info = Context;
857193267Sjkim    ACPI_DB_METHOD_INFO     LocalInfo;
85867754Smsmith    UINT32                  i;
859167802Sjkim    UINT8                   Allow;
86067754Smsmith    ACPI_BUFFER             ReturnObj;
86167754Smsmith
86267754Smsmith
863193267Sjkim    /*
864193267Sjkim     * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments.
865193267Sjkim     * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads
866193267Sjkim     * concurrently.
867193267Sjkim     *
868193267Sjkim     * Note: The arguments we are passing are used by the ASL test suite
869193267Sjkim     * (aslts). Do not change them without updating the tests.
870193267Sjkim     */
871193267Sjkim    (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER);
872193267Sjkim
873167802Sjkim    if (Info->InitArgs)
874167802Sjkim    {
875167802Sjkim        AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr);
876212761Sjkim        AcpiDbUInt32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr);
877167802Sjkim    }
878167802Sjkim
879167802Sjkim    if (Info->Threads && (Info->NumCreated < Info->NumThreads))
880167802Sjkim    {
881212761Sjkim        Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId();
882167802Sjkim    }
883167802Sjkim
884193267Sjkim    LocalInfo = *Info;
885193267Sjkim    LocalInfo.Args = LocalInfo.Arguments;
886193267Sjkim    LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr;
887193267Sjkim    LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr;
888193267Sjkim    LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr;
889193267Sjkim    LocalInfo.Arguments[3] = NULL;
890193267Sjkim
891222544Sjkim    LocalInfo.Types = LocalInfo.ArgTypes;
892222544Sjkim
893193267Sjkim    (void) AcpiOsSignalSemaphore (Info->InfoGate, 1);
894193267Sjkim
89567754Smsmith    for (i = 0; i < Info->NumLoops; i++)
89667754Smsmith    {
897193267Sjkim        Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj);
898117521Snjl        if (ACPI_FAILURE (Status))
89967754Smsmith        {
900117521Snjl            AcpiOsPrintf ("%s During execution of %s at iteration %X\n",
901117521Snjl                AcpiFormatException (Status), Info->Pathname, i);
902127175Snjl            if (Status == AE_ABORT_METHOD)
903127175Snjl            {
904127175Snjl                break;
905127175Snjl            }
90667754Smsmith        }
907117521Snjl
908167802Sjkim#if 0
909128212Snjl        if ((i % 100) == 0)
910117521Snjl        {
911209746Sjkim            AcpiOsPrintf ("%u executions, Thread 0x%x\n", i, AcpiOsGetThreadId ());
912117521Snjl        }
913117521Snjl
914117521Snjl        if (ReturnObj.Length)
915117521Snjl        {
916117521Snjl            AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
917117521Snjl                Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length);
918151937Sjkim            AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
919117521Snjl        }
920117521Snjl#endif
92167754Smsmith    }
92267754Smsmith
92367754Smsmith    /* Signal our completion */
92467754Smsmith
925167802Sjkim    Allow = 0;
926193267Sjkim    (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER);
927167802Sjkim    Info->NumCompleted++;
928167802Sjkim
929167802Sjkim    if (Info->NumCompleted == Info->NumThreads)
93099679Siwasaki    {
931167802Sjkim        /* Do signal for main thread once only */
932167802Sjkim        Allow = 1;
93399679Siwasaki    }
934167802Sjkim
935193267Sjkim    (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1);
936167802Sjkim
937167802Sjkim    if (Allow)
938167802Sjkim    {
939167802Sjkim        Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1);
940167802Sjkim        if (ACPI_FAILURE (Status))
941167802Sjkim        {
942167802Sjkim            AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n",
943167802Sjkim                AcpiFormatException (Status));
944167802Sjkim        }
945167802Sjkim    }
94667754Smsmith}
94767754Smsmith
94867754Smsmith
94967754Smsmith/*******************************************************************************
95067754Smsmith *
95167754Smsmith * FUNCTION:    AcpiDbCreateExecutionThreads
95267754Smsmith *
95367754Smsmith * PARAMETERS:  NumThreadsArg           - Number of threads to create
95467754Smsmith *              NumLoopsArg             - Loop count for the thread(s)
95567754Smsmith *              MethodNameArg           - Control method to execute
95667754Smsmith *
95767754Smsmith * RETURN:      None
95867754Smsmith *
95967754Smsmith * DESCRIPTION: Create threads to execute method(s)
96067754Smsmith *
96167754Smsmith ******************************************************************************/
96267754Smsmith
96367754Smsmithvoid
96467754SmsmithAcpiDbCreateExecutionThreads (
965114237Snjl    char                    *NumThreadsArg,
966114237Snjl    char                    *NumLoopsArg,
967114237Snjl    char                    *MethodNameArg)
96867754Smsmith{
96967754Smsmith    ACPI_STATUS             Status;
97067754Smsmith    UINT32                  NumThreads;
97167754Smsmith    UINT32                  NumLoops;
97267754Smsmith    UINT32                  i;
973167802Sjkim    UINT32                  Size;
974167802Sjkim    ACPI_MUTEX              MainThreadGate;
975167802Sjkim    ACPI_MUTEX              ThreadCompleteGate;
976193267Sjkim    ACPI_MUTEX              InfoGate;
97767754Smsmith
978193267Sjkim
97967754Smsmith    /* Get the arguments */
98067754Smsmith
98191116Smsmith    NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0);
98291116Smsmith    NumLoops   = ACPI_STRTOUL (NumLoopsArg, NULL, 0);
98367754Smsmith
98467754Smsmith    if (!NumThreads || !NumLoops)
98567754Smsmith    {
986151937Sjkim        AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n",
987151937Sjkim            NumThreads, NumLoops);
98867754Smsmith        return;
98967754Smsmith    }
99067754Smsmith
991167802Sjkim    /*
992167802Sjkim     * Create the semaphore for synchronization of
993167802Sjkim     * the created threads with the main thread.
994167802Sjkim     */
995167802Sjkim    Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate);
996167802Sjkim    if (ACPI_FAILURE (Status))
997167802Sjkim    {
998167802Sjkim        AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n",
999167802Sjkim            AcpiFormatException (Status));
1000167802Sjkim        return;
1001167802Sjkim    }
100267754Smsmith
1003167802Sjkim    /*
1004167802Sjkim     * Create the semaphore for synchronization
1005167802Sjkim     * between the created threads.
1006167802Sjkim     */
1007167802Sjkim    Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate);
100867754Smsmith    if (ACPI_FAILURE (Status))
100967754Smsmith    {
1010167802Sjkim        AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n",
1011151937Sjkim            AcpiFormatException (Status));
1012167802Sjkim        (void) AcpiOsDeleteSemaphore (MainThreadGate);
101367754Smsmith        return;
101467754Smsmith    }
101567754Smsmith
1016193267Sjkim    Status = AcpiOsCreateSemaphore (1, 1, &InfoGate);
1017193267Sjkim    if (ACPI_FAILURE (Status))
1018193267Sjkim    {
1019193267Sjkim        AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n",
1020193267Sjkim            AcpiFormatException (Status));
1021193267Sjkim        (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
1022193267Sjkim        (void) AcpiOsDeleteSemaphore (MainThreadGate);
1023193267Sjkim        return;
1024193267Sjkim    }
1025193267Sjkim
1026167802Sjkim    ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
1027167802Sjkim
1028167802Sjkim    /* Array to store IDs of threads */
1029167802Sjkim
1030167802Sjkim    AcpiGbl_DbMethodInfo.NumThreads = NumThreads;
1031212761Sjkim    Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads;
1032212761Sjkim    AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size);
1033167802Sjkim    if (AcpiGbl_DbMethodInfo.Threads == NULL)
1034167802Sjkim    {
1035167802Sjkim        AcpiOsPrintf ("No memory for thread IDs array\n");
1036167802Sjkim        (void) AcpiOsDeleteSemaphore (MainThreadGate);
1037167802Sjkim        (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
1038193267Sjkim        (void) AcpiOsDeleteSemaphore (InfoGate);
1039167802Sjkim        return;
1040167802Sjkim    }
1041167802Sjkim    ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size);
1042167802Sjkim
104367754Smsmith    /* Setup the context to be passed to each thread */
104467754Smsmith
104583174Smsmith    AcpiGbl_DbMethodInfo.Name = MethodNameArg;
104683174Smsmith    AcpiGbl_DbMethodInfo.Flags = 0;
104783174Smsmith    AcpiGbl_DbMethodInfo.NumLoops = NumLoops;
1048167802Sjkim    AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate;
1049167802Sjkim    AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate;
1050193267Sjkim    AcpiGbl_DbMethodInfo.InfoGate = InfoGate;
105167754Smsmith
1052167802Sjkim    /* Init arguments to be passed to method */
1053167802Sjkim
1054167802Sjkim    AcpiGbl_DbMethodInfo.InitArgs = 1;
1055167802Sjkim    AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments;
1056167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr;
1057167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr;
1058167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr;
1059167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[3] = NULL;
1060222544Sjkim
1061222544Sjkim    AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes;
1062222544Sjkim    AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER;
1063222544Sjkim    AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER;
1064222544Sjkim    AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER;
1065222544Sjkim
1066167802Sjkim    AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr);
1067167802Sjkim
106883174Smsmith    AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
106967754Smsmith
107067754Smsmith    /* Create the threads */
107167754Smsmith
1072151937Sjkim    AcpiOsPrintf ("Creating %X threads to execute %X times each\n",
1073151937Sjkim        NumThreads, NumLoops);
107467754Smsmith
107567754Smsmith    for (i = 0; i < (NumThreads); i++)
107667754Smsmith    {
1077167802Sjkim        Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread,
1078151937Sjkim            &AcpiGbl_DbMethodInfo);
107999679Siwasaki        if (ACPI_FAILURE (Status))
108099679Siwasaki        {
108199679Siwasaki            break;
108299679Siwasaki        }
108367754Smsmith    }
108467754Smsmith
108567754Smsmith    /* Wait for all threads to complete */
108667754Smsmith
1087193267Sjkim    (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER);
108867754Smsmith
1089167802Sjkim    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1090167802Sjkim    AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads);
1091167802Sjkim    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1092167802Sjkim
109367754Smsmith    /* Cleanup and exit */
109467754Smsmith
1095167802Sjkim    (void) AcpiOsDeleteSemaphore (MainThreadGate);
1096167802Sjkim    (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
1097193267Sjkim    (void) AcpiOsDeleteSemaphore (InfoGate);
109867754Smsmith
1099167802Sjkim    AcpiOsFree (AcpiGbl_DbMethodInfo.Threads);
1100167802Sjkim    AcpiGbl_DbMethodInfo.Threads = NULL;
110167754Smsmith}
110267754Smsmith
1103102550Siwasaki#endif /* ACPI_DEBUGGER */
110467754Smsmith
110567754Smsmith
1106