dbexec.c revision 239340
167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dbexec - debugger control method execution
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
7217365Sjkim/*
8229989Sjkim * Copyright (C) 2000 - 2012, 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
107239340Sjkimstatic UINT8 *
108239340SjkimAcpiDbEncodePldBuffer (
109239340Sjkim    ACPI_PLD_INFO           *PldInfo);
110239340Sjkim
111239340Sjkimstatic void
112239340SjkimAcpiDbDumpPldBuffer (
113239340Sjkim    ACPI_OBJECT             *ObjDesc);
114239340Sjkim
115239340Sjkim
11667754Smsmith/*******************************************************************************
11767754Smsmith *
118222544Sjkim * FUNCTION:    AcpiDbHexCharToValue
119222544Sjkim *
120222544Sjkim * PARAMETERS:  HexChar             - Ascii Hex digit, 0-9|a-f|A-F
121222544Sjkim *              ReturnValue         - Where the converted value is returned
122222544Sjkim *
123222544Sjkim * RETURN:      Status
124222544Sjkim *
125222544Sjkim * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16).
126222544Sjkim *
127222544Sjkim ******************************************************************************/
128222544Sjkim
129222544Sjkimstatic ACPI_STATUS
130222544SjkimAcpiDbHexCharToValue (
131222544Sjkim    int                     HexChar,
132222544Sjkim    UINT8                   *ReturnValue)
133222544Sjkim{
134222544Sjkim    UINT8                   Value;
135222544Sjkim
136222544Sjkim
137222544Sjkim    /* Digit must be ascii [0-9a-fA-F] */
138222544Sjkim
139222544Sjkim    if (!ACPI_IS_XDIGIT (HexChar))
140222544Sjkim    {
141222544Sjkim        return (AE_BAD_HEX_CONSTANT);
142222544Sjkim    }
143222544Sjkim
144222544Sjkim    if (HexChar <= 0x39)
145222544Sjkim    {
146222544Sjkim        Value = (UINT8) (HexChar - 0x30);
147222544Sjkim    }
148222544Sjkim    else
149222544Sjkim    {
150222544Sjkim        Value = (UINT8) (ACPI_TOUPPER (HexChar) - 0x37);
151222544Sjkim    }
152222544Sjkim
153222544Sjkim    *ReturnValue = Value;
154222544Sjkim    return (AE_OK);
155222544Sjkim}
156222544Sjkim
157222544Sjkim
158222544Sjkim/*******************************************************************************
159222544Sjkim *
160222544Sjkim * FUNCTION:    AcpiDbHexByteToBinary
161222544Sjkim *
162222544Sjkim * PARAMETERS:  HexByte             - Double hex digit (0x00 - 0xFF) in format:
163222544Sjkim *                                    HiByte then LoByte.
164222544Sjkim *              ReturnValue         - Where the converted value is returned
165222544Sjkim *
166222544Sjkim * RETURN:      Status
167222544Sjkim *
168222544Sjkim * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255).
169222544Sjkim *
170222544Sjkim ******************************************************************************/
171222544Sjkim
172222544Sjkimstatic ACPI_STATUS
173222544SjkimAcpiDbHexByteToBinary (
174222544Sjkim    char                    *HexByte,
175222544Sjkim    UINT8                   *ReturnValue)
176222544Sjkim{
177222544Sjkim    UINT8                   Local0;
178222544Sjkim    UINT8                   Local1;
179222544Sjkim    ACPI_STATUS             Status;
180222544Sjkim
181222544Sjkim
182222544Sjkim    /* High byte */
183222544Sjkim
184222544Sjkim    Status = AcpiDbHexCharToValue (HexByte[0], &Local0);
185222544Sjkim    if (ACPI_FAILURE (Status))
186222544Sjkim    {
187222544Sjkim        return (Status);
188222544Sjkim    }
189222544Sjkim
190222544Sjkim    /* Low byte */
191222544Sjkim
192222544Sjkim    Status = AcpiDbHexCharToValue (HexByte[1], &Local1);
193222544Sjkim    if (ACPI_FAILURE (Status))
194222544Sjkim    {
195222544Sjkim        return (Status);
196222544Sjkim    }
197222544Sjkim
198222544Sjkim    *ReturnValue = (UINT8) ((Local0 << 4) | Local1);
199222544Sjkim    return (AE_OK);
200222544Sjkim}
201222544Sjkim
202222544Sjkim
203222544Sjkim/*******************************************************************************
204222544Sjkim *
205222544Sjkim * FUNCTION:    AcpiDbConvertToBuffer
206222544Sjkim *
207222544Sjkim * PARAMETERS:  String              - Input string to be converted
208222544Sjkim *              Object              - Where the buffer object is returned
209222544Sjkim *
210222544Sjkim * RETURN:      Status
211222544Sjkim *
212222544Sjkim * DESCRIPTION: Convert a string to a buffer object. String is treated a list
213222544Sjkim *              of buffer elements, each separated by a space or comma.
214222544Sjkim *
215222544Sjkim ******************************************************************************/
216222544Sjkim
217222544Sjkimstatic ACPI_STATUS
218222544SjkimAcpiDbConvertToBuffer (
219222544Sjkim    char                    *String,
220222544Sjkim    ACPI_OBJECT             *Object)
221222544Sjkim{
222222544Sjkim    UINT32                  i;
223222544Sjkim    UINT32                  j;
224222544Sjkim    UINT32                  Length;
225222544Sjkim    UINT8                   *Buffer;
226222544Sjkim    ACPI_STATUS             Status;
227222544Sjkim
228222544Sjkim
229222544Sjkim    /* Generate the final buffer length */
230222544Sjkim
231222544Sjkim    for (i = 0, Length = 0; String[i];)
232222544Sjkim    {
233222544Sjkim        i+=2;
234222544Sjkim        Length++;
235222544Sjkim
236222544Sjkim        while (String[i] &&
237222544Sjkim              ((String[i] == ',') || (String[i] == ' ')))
238222544Sjkim        {
239222544Sjkim            i++;
240222544Sjkim        }
241222544Sjkim    }
242222544Sjkim
243222544Sjkim    Buffer = ACPI_ALLOCATE (Length);
244222544Sjkim    if (!Buffer)
245222544Sjkim    {
246222544Sjkim        return (AE_NO_MEMORY);
247222544Sjkim    }
248222544Sjkim
249222544Sjkim    /* Convert the command line bytes to the buffer */
250222544Sjkim
251222544Sjkim    for (i = 0, j = 0; String[i];)
252222544Sjkim    {
253222544Sjkim        Status = AcpiDbHexByteToBinary (&String[i], &Buffer[j]);
254222544Sjkim        if (ACPI_FAILURE (Status))
255222544Sjkim        {
256222544Sjkim            ACPI_FREE (Buffer);
257222544Sjkim            return (Status);
258222544Sjkim        }
259222544Sjkim
260222544Sjkim        j++;
261222544Sjkim        i+=2;
262222544Sjkim        while (String[i] &&
263222544Sjkim              ((String[i] == ',') || (String[i] == ' ')))
264222544Sjkim        {
265222544Sjkim            i++;
266222544Sjkim        }
267222544Sjkim    }
268222544Sjkim
269222544Sjkim    Object->Type = ACPI_TYPE_BUFFER;
270222544Sjkim    Object->Buffer.Pointer = Buffer;
271222544Sjkim    Object->Buffer.Length = Length;
272222544Sjkim    return (AE_OK);
273222544Sjkim}
274222544Sjkim
275222544Sjkim
276222544Sjkim/*******************************************************************************
277222544Sjkim *
278222544Sjkim * FUNCTION:    AcpiDbConvertToPackage
279222544Sjkim *
280222544Sjkim * PARAMETERS:  String              - Input string to be converted
281222544Sjkim *              Object              - Where the package object is returned
282222544Sjkim *
283222544Sjkim * RETURN:      Status
284222544Sjkim *
285222544Sjkim * DESCRIPTION: Convert a string to a package object. Handles nested packages
286222544Sjkim *              via recursion with AcpiDbConvertToObject.
287222544Sjkim *
288222544Sjkim ******************************************************************************/
289222544Sjkim
290222544Sjkimstatic ACPI_STATUS
291222544SjkimAcpiDbConvertToPackage (
292222544Sjkim    char                    *String,
293222544Sjkim    ACPI_OBJECT             *Object)
294222544Sjkim{
295222544Sjkim    char                    *This;
296222544Sjkim    char                    *Next;
297222544Sjkim    UINT32                  i;
298222544Sjkim    ACPI_OBJECT_TYPE        Type;
299222544Sjkim    ACPI_OBJECT             *Elements;
300222544Sjkim    ACPI_STATUS             Status;
301222544Sjkim
302222544Sjkim
303222544Sjkim    Elements = ACPI_ALLOCATE_ZEROED (
304222544Sjkim        DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT));
305222544Sjkim
306222544Sjkim    This = String;
307222544Sjkim    for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++)
308222544Sjkim    {
309222544Sjkim        This = AcpiDbGetNextToken (This, &Next, &Type);
310222544Sjkim        if (!This)
311222544Sjkim        {
312222544Sjkim            break;
313222544Sjkim        }
314222544Sjkim
315222544Sjkim        /* Recursive call to convert each package element */
316222544Sjkim
317222544Sjkim        Status = AcpiDbConvertToObject (Type, This, &Elements[i]);
318222544Sjkim        if (ACPI_FAILURE (Status))
319222544Sjkim        {
320222544Sjkim            AcpiDbDeleteObjects (i + 1, Elements);
321222544Sjkim            ACPI_FREE (Elements);
322222544Sjkim            return (Status);
323222544Sjkim        }
324222544Sjkim
325222544Sjkim        This = Next;
326222544Sjkim    }
327222544Sjkim
328222544Sjkim    Object->Type = ACPI_TYPE_PACKAGE;
329222544Sjkim    Object->Package.Count = i;
330222544Sjkim    Object->Package.Elements = Elements;
331222544Sjkim    return (AE_OK);
332222544Sjkim}
333222544Sjkim
334222544Sjkim
335222544Sjkim/*******************************************************************************
336222544Sjkim *
337222544Sjkim * FUNCTION:    AcpiDbConvertToObject
338222544Sjkim *
339222544Sjkim * PARAMETERS:  Type                - Object type as determined by parser
340222544Sjkim *              String              - Input string to be converted
341222544Sjkim *              Object              - Where the new object is returned
342222544Sjkim *
343222544Sjkim * RETURN:      Status
344222544Sjkim *
345222544Sjkim * DESCRIPTION: Convert a typed and tokenized string to an ACPI_OBJECT. Typing:
346222544Sjkim *              1) String objects were surrounded by quotes.
347222544Sjkim *              2) Buffer objects were surrounded by parentheses.
348222544Sjkim *              3) Package objects were surrounded by brackets "[]".
349222544Sjkim *              4) All standalone tokens are treated as integers.
350222544Sjkim *
351222544Sjkim ******************************************************************************/
352222544Sjkim
353222544Sjkimstatic ACPI_STATUS
354222544SjkimAcpiDbConvertToObject (
355222544Sjkim    ACPI_OBJECT_TYPE        Type,
356222544Sjkim    char                    *String,
357222544Sjkim    ACPI_OBJECT             *Object)
358222544Sjkim{
359222544Sjkim    ACPI_STATUS             Status = AE_OK;
360222544Sjkim
361222544Sjkim
362222544Sjkim    switch (Type)
363222544Sjkim    {
364222544Sjkim    case ACPI_TYPE_STRING:
365222544Sjkim        Object->Type = ACPI_TYPE_STRING;
366222544Sjkim        Object->String.Pointer = String;
367222544Sjkim        Object->String.Length = (UINT32) ACPI_STRLEN (String);
368222544Sjkim        break;
369222544Sjkim
370222544Sjkim    case ACPI_TYPE_BUFFER:
371222544Sjkim        Status = AcpiDbConvertToBuffer (String, Object);
372222544Sjkim        break;
373222544Sjkim
374222544Sjkim    case ACPI_TYPE_PACKAGE:
375222544Sjkim        Status = AcpiDbConvertToPackage (String, Object);
376222544Sjkim        break;
377222544Sjkim
378222544Sjkim    default:
379222544Sjkim        Object->Type = ACPI_TYPE_INTEGER;
380222544Sjkim        Status = AcpiUtStrtoul64 (String, 16, &Object->Integer.Value);
381222544Sjkim        break;
382222544Sjkim    }
383222544Sjkim
384222544Sjkim    return (Status);
385222544Sjkim}
386222544Sjkim
387222544Sjkim
388222544Sjkim/*******************************************************************************
389222544Sjkim *
390222544Sjkim * FUNCTION:    AcpiDbDeleteObjects
391222544Sjkim *
392222544Sjkim * PARAMETERS:  Count               - Count of objects in the list
393222544Sjkim *              Objects             - Array of ACPI_OBJECTs to be deleted
394222544Sjkim *
395222544Sjkim * RETURN:      None
396222544Sjkim *
397222544Sjkim * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested
398222544Sjkim *              packages via recursion.
399222544Sjkim *
400222544Sjkim ******************************************************************************/
401222544Sjkim
402222544Sjkimstatic void
403222544SjkimAcpiDbDeleteObjects (
404222544Sjkim    UINT32                  Count,
405222544Sjkim    ACPI_OBJECT             *Objects)
406222544Sjkim{
407222544Sjkim    UINT32                  i;
408222544Sjkim
409222544Sjkim
410222544Sjkim    for (i = 0; i < Count; i++)
411222544Sjkim    {
412222544Sjkim        switch (Objects[i].Type)
413222544Sjkim        {
414222544Sjkim        case ACPI_TYPE_BUFFER:
415222544Sjkim            ACPI_FREE (Objects[i].Buffer.Pointer);
416222544Sjkim            break;
417222544Sjkim
418222544Sjkim        case ACPI_TYPE_PACKAGE:
419222544Sjkim
420222544Sjkim            /* Recursive call to delete package elements */
421222544Sjkim
422222544Sjkim            AcpiDbDeleteObjects (Objects[i].Package.Count,
423222544Sjkim                Objects[i].Package.Elements);
424222544Sjkim
425222544Sjkim            /* Free the elements array */
426222544Sjkim
427222544Sjkim            ACPI_FREE (Objects[i].Package.Elements);
428222544Sjkim            break;
429222544Sjkim
430222544Sjkim        default:
431222544Sjkim            break;
432222544Sjkim        }
433222544Sjkim    }
434222544Sjkim}
435222544Sjkim
436222544Sjkim
437222544Sjkim/*******************************************************************************
438222544Sjkim *
43967754Smsmith * FUNCTION:    AcpiDbExecuteMethod
44067754Smsmith *
44167754Smsmith * PARAMETERS:  Info            - Valid info segment
44267754Smsmith *              ReturnObj       - Where to put return object
44367754Smsmith *
44467754Smsmith * RETURN:      Status
44567754Smsmith *
44667754Smsmith * DESCRIPTION: Execute a control method.
44767754Smsmith *
44867754Smsmith ******************************************************************************/
44967754Smsmith
450151937Sjkimstatic ACPI_STATUS
45167754SmsmithAcpiDbExecuteMethod (
45291116Smsmith    ACPI_DB_METHOD_INFO     *Info,
45367754Smsmith    ACPI_BUFFER             *ReturnObj)
45467754Smsmith{
45567754Smsmith    ACPI_STATUS             Status;
45667754Smsmith    ACPI_OBJECT_LIST        ParamObjects;
457114237Snjl    ACPI_OBJECT             Params[ACPI_METHOD_NUM_ARGS];
458222544Sjkim    ACPI_DEVICE_INFO        *ObjInfo;
45967754Smsmith    UINT32                  i;
46067754Smsmith
46167754Smsmith
462216471Sjkim    ACPI_FUNCTION_TRACE (DbExecuteMethod);
463216471Sjkim
464216471Sjkim
46583174Smsmith    if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel)
46667754Smsmith    {
46767754Smsmith        AcpiOsPrintf ("Warning: debug output is not enabled!\n");
46867754Smsmith    }
46967754Smsmith
470193267Sjkim    /* Get the object info for number of method parameters */
471193267Sjkim
472239340Sjkim    Status = AcpiGetObjectInfo (Info->Method, &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 *
723239340Sjkim * FUNCTION:    AcpiDbEncodePldBuffer
724239340Sjkim *
725239340Sjkim * PARAMETERS:  PldInfo             - _PLD buffer struct (Using local struct)
726239340Sjkim *
727239340Sjkim * RETURN:      Encode _PLD buffer suitable for return value from _PLD
728239340Sjkim *
729239340Sjkim * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros
730239340Sjkim *
731239340Sjkim ******************************************************************************/
732239340Sjkim
733239340Sjkimstatic UINT8 *
734239340SjkimAcpiDbEncodePldBuffer (
735239340Sjkim    ACPI_PLD_INFO           *PldInfo)
736239340Sjkim{
737239340Sjkim    UINT32                  *Buffer;
738239340Sjkim    UINT32                  Dword;
739239340Sjkim
740239340Sjkim
741239340Sjkim    Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE);
742239340Sjkim    if (!Buffer)
743239340Sjkim    {
744239340Sjkim        return (NULL);
745239340Sjkim    }
746239340Sjkim
747239340Sjkim    /* First 32 bits */
748239340Sjkim
749239340Sjkim    Dword = 0;
750239340Sjkim    ACPI_PLD_SET_REVISION       (&Dword, PldInfo->Revision);
751239340Sjkim    ACPI_PLD_SET_IGNORE_COLOR   (&Dword, PldInfo->IgnoreColor);
752239340Sjkim    ACPI_PLD_SET_COLOR          (&Dword, PldInfo->Color);
753239340Sjkim    ACPI_MOVE_32_TO_32 (&Buffer[0], &Dword);
754239340Sjkim
755239340Sjkim    /* Second 32 bits */
756239340Sjkim
757239340Sjkim    Dword = 0;
758239340Sjkim    ACPI_PLD_SET_WIDTH          (&Dword, PldInfo->Width);
759239340Sjkim    ACPI_PLD_SET_HEIGHT         (&Dword, PldInfo->Height);
760239340Sjkim    ACPI_MOVE_32_TO_32 (&Buffer[1], &Dword);
761239340Sjkim
762239340Sjkim    /* Third 32 bits */
763239340Sjkim
764239340Sjkim    Dword = 0;
765239340Sjkim    ACPI_PLD_SET_USER_VISIBLE   (&Dword, PldInfo->UserVisible);
766239340Sjkim    ACPI_PLD_SET_DOCK           (&Dword, PldInfo->Dock);
767239340Sjkim    ACPI_PLD_SET_LID            (&Dword, PldInfo->Lid);
768239340Sjkim    ACPI_PLD_SET_PANEL          (&Dword, PldInfo->Panel);
769239340Sjkim    ACPI_PLD_SET_VERTICAL       (&Dword, PldInfo->VerticalPosition);
770239340Sjkim    ACPI_PLD_SET_HORIZONTAL     (&Dword, PldInfo->HorizontalPosition);
771239340Sjkim    ACPI_PLD_SET_SHAPE          (&Dword, PldInfo->Shape);
772239340Sjkim    ACPI_PLD_SET_ORIENTATION    (&Dword, PldInfo->GroupOrientation);
773239340Sjkim    ACPI_PLD_SET_TOKEN          (&Dword, PldInfo->GroupToken);
774239340Sjkim    ACPI_PLD_SET_POSITION       (&Dword, PldInfo->GroupPosition);
775239340Sjkim    ACPI_PLD_SET_BAY            (&Dword, PldInfo->Bay);
776239340Sjkim    ACPI_MOVE_32_TO_32 (&Buffer[2], &Dword);
777239340Sjkim
778239340Sjkim    /* Fourth 32 bits */
779239340Sjkim
780239340Sjkim    Dword = 0;
781239340Sjkim    ACPI_PLD_SET_EJECTABLE      (&Dword, PldInfo->Ejectable);
782239340Sjkim    ACPI_PLD_SET_OSPM_EJECT     (&Dword, PldInfo->OspmEjectRequired);
783239340Sjkim    ACPI_PLD_SET_CABINET        (&Dword, PldInfo->CabinetNumber);
784239340Sjkim    ACPI_PLD_SET_CARD_CAGE      (&Dword, PldInfo->CardCageNumber);
785239340Sjkim    ACPI_PLD_SET_REFERENCE      (&Dword, PldInfo->Reference);
786239340Sjkim    ACPI_PLD_SET_ROTATION       (&Dword, PldInfo->Rotation);
787239340Sjkim    ACPI_PLD_SET_ORDER          (&Dword, PldInfo->Order);
788239340Sjkim    ACPI_MOVE_32_TO_32 (&Buffer[3], &Dword);
789239340Sjkim
790239340Sjkim    if (PldInfo->Revision >= 2)
791239340Sjkim    {
792239340Sjkim        /* Fifth 32 bits */
793239340Sjkim
794239340Sjkim        Dword = 0;
795239340Sjkim        ACPI_PLD_SET_VERT_OFFSET    (&Dword, PldInfo->VerticalOffset);
796239340Sjkim        ACPI_PLD_SET_HORIZ_OFFSET   (&Dword, PldInfo->HorizontalOffset);
797239340Sjkim        ACPI_MOVE_32_TO_32 (&Buffer[4], &Dword);
798239340Sjkim    }
799239340Sjkim
800239340Sjkim    return (ACPI_CAST_PTR (UINT8, Buffer));
801239340Sjkim}
802239340Sjkim
803239340Sjkim
804239340Sjkim/*******************************************************************************
805239340Sjkim *
806239340Sjkim * FUNCTION:    AcpiDbDumpPldBuffer
807239340Sjkim *
808239340Sjkim * PARAMETERS:  ObjDesc             - Object returned from _PLD method
809239340Sjkim *
810239340Sjkim * RETURN:      None.
811239340Sjkim *
812239340Sjkim * DESCRIPTION: Dumps formatted contents of a _PLD return buffer.
813239340Sjkim *
814239340Sjkim ******************************************************************************/
815239340Sjkim
816239340Sjkim#define ACPI_PLD_OUTPUT     "%20s : %-6X\n"
817239340Sjkim
818239340Sjkimstatic void
819239340SjkimAcpiDbDumpPldBuffer (
820239340Sjkim    ACPI_OBJECT             *ObjDesc)
821239340Sjkim{
822239340Sjkim    ACPI_OBJECT             *BufferDesc;
823239340Sjkim    ACPI_PLD_INFO           *PldInfo;
824239340Sjkim    UINT8                   *NewBuffer;
825239340Sjkim    ACPI_STATUS             Status;
826239340Sjkim
827239340Sjkim
828239340Sjkim    /* Object must be of type Package with at least one Buffer element */
829239340Sjkim
830239340Sjkim    if (ObjDesc->Type != ACPI_TYPE_PACKAGE)
831239340Sjkim    {
832239340Sjkim        return;
833239340Sjkim    }
834239340Sjkim
835239340Sjkim    BufferDesc = &ObjDesc->Package.Elements[0];
836239340Sjkim    if (BufferDesc->Type != ACPI_TYPE_BUFFER)
837239340Sjkim    {
838239340Sjkim        return;
839239340Sjkim    }
840239340Sjkim
841239340Sjkim    /* Convert _PLD buffer to local _PLD struct */
842239340Sjkim
843239340Sjkim    Status = AcpiDecodePldBuffer (BufferDesc->Buffer.Pointer,
844239340Sjkim        BufferDesc->Buffer.Length, &PldInfo);
845239340Sjkim    if (ACPI_FAILURE (Status))
846239340Sjkim    {
847239340Sjkim        return;
848239340Sjkim    }
849239340Sjkim
850239340Sjkim    /* Encode local _PLD struct back to a _PLD buffer */
851239340Sjkim
852239340Sjkim    NewBuffer = AcpiDbEncodePldBuffer (PldInfo);
853239340Sjkim    if (!NewBuffer)
854239340Sjkim    {
855239340Sjkim        return;
856239340Sjkim    }
857239340Sjkim
858239340Sjkim    /* The two bit-packed buffers should match */
859239340Sjkim
860239340Sjkim    if (ACPI_MEMCMP (NewBuffer, BufferDesc->Buffer.Pointer,
861239340Sjkim        BufferDesc->Buffer.Length))
862239340Sjkim    {
863239340Sjkim        AcpiOsPrintf ("Converted _PLD buffer does not compare. New:\n");
864239340Sjkim
865239340Sjkim        AcpiUtDumpBuffer2 (NewBuffer,
866239340Sjkim            BufferDesc->Buffer.Length, DB_BYTE_DISPLAY);
867239340Sjkim    }
868239340Sjkim
869239340Sjkim    /* First 32-bit dword */
870239340Sjkim
871239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Revision", PldInfo->Revision);
872239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "IgnoreColor", PldInfo->IgnoreColor);
873239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Color", PldInfo->Color);
874239340Sjkim
875239340Sjkim    /* Second 32-bit dword */
876239340Sjkim
877239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Width", PldInfo->Width);
878239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Height", PldInfo->Height);
879239340Sjkim
880239340Sjkim    /* Third 32-bit dword */
881239340Sjkim
882239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "UserVisible", PldInfo->UserVisible);
883239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Dock", PldInfo->Dock);
884239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Lid", PldInfo->Lid);
885239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Panel", PldInfo->Panel);
886239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "VerticalPosition", PldInfo->VerticalPosition);
887239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "HorizontalPosition", PldInfo->HorizontalPosition);
888239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Shape", PldInfo->Shape);
889239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "GroupOrientation", PldInfo->GroupOrientation);
890239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "GroupToken", PldInfo->GroupToken);
891239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "GroupPosition", PldInfo->GroupPosition);
892239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Bay", PldInfo->Bay);
893239340Sjkim
894239340Sjkim    /* Fourth 32-bit dword */
895239340Sjkim
896239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Ejectable", PldInfo->Ejectable);
897239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "OspmEjectRequired", PldInfo->OspmEjectRequired);
898239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "CabinetNumber", PldInfo->CabinetNumber);
899239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "CardCageNumber", PldInfo->CardCageNumber);
900239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Reference", PldInfo->Reference);
901239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Rotation", PldInfo->Rotation);
902239340Sjkim    AcpiOsPrintf (ACPI_PLD_OUTPUT, "Order", PldInfo->Order);
903239340Sjkim
904239340Sjkim    /* Fifth 32-bit dword */
905239340Sjkim
906239340Sjkim    if (BufferDesc->Buffer.Length > 16)
907239340Sjkim    {
908239340Sjkim        AcpiOsPrintf (ACPI_PLD_OUTPUT, "VerticalOffset", PldInfo->VerticalOffset);
909239340Sjkim        AcpiOsPrintf (ACPI_PLD_OUTPUT, "HorizontalOffset", PldInfo->HorizontalOffset);
910239340Sjkim    }
911239340Sjkim
912239340Sjkim    ACPI_FREE (PldInfo);
913239340Sjkim    ACPI_FREE (NewBuffer);
914239340Sjkim}
915239340Sjkim
916239340Sjkim
917239340Sjkim/*******************************************************************************
918239340Sjkim *
91967754Smsmith * FUNCTION:    AcpiDbExecute
92067754Smsmith *
92167754Smsmith * PARAMETERS:  Name                - Name of method to execute
92267754Smsmith *              Args                - Parameters to the method
92367754Smsmith *              Flags               - single step/no single step
92467754Smsmith *
925151937Sjkim * RETURN:      None
92667754Smsmith *
92767754Smsmith * DESCRIPTION: Execute a control method.  Name is relative to the current
92867754Smsmith *              scope.
92967754Smsmith *
93067754Smsmith ******************************************************************************/
93167754Smsmith
93267754Smsmithvoid
93367754SmsmithAcpiDbExecute (
934114237Snjl    char                    *Name,
935114237Snjl    char                    **Args,
936222544Sjkim    ACPI_OBJECT_TYPE        *Types,
93767754Smsmith    UINT32                  Flags)
93867754Smsmith{
93967754Smsmith    ACPI_STATUS             Status;
94069450Smsmith    ACPI_BUFFER             ReturnObj;
941167802Sjkim    char                    *NameString;
94269450Smsmith
94369450Smsmith
944102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT
94567754Smsmith    UINT32                  PreviousAllocations;
94667754Smsmith    UINT32                  Allocations;
94767754Smsmith
94867754Smsmith
94967754Smsmith    /* Memory allocation tracking */
95067754Smsmith
95182367Smsmith    PreviousAllocations = AcpiDbGetOutstandingAllocations ();
95269450Smsmith#endif
95367754Smsmith
954114237Snjl    if (*Name == '*')
955114237Snjl    {
956151937Sjkim        (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT,
957199337Sjkim                    ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL);
958114237Snjl        return;
959114237Snjl    }
960114237Snjl    else
961114237Snjl    {
962167802Sjkim        NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1);
963167802Sjkim        if (!NameString)
964167802Sjkim        {
965167802Sjkim            return;
966167802Sjkim        }
967167802Sjkim
968167802Sjkim        ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
969167802Sjkim
970167802Sjkim        ACPI_STRCPY (NameString, Name);
971167802Sjkim        AcpiUtStrupr (NameString);
972167802Sjkim        AcpiGbl_DbMethodInfo.Name = NameString;
973114237Snjl        AcpiGbl_DbMethodInfo.Args = Args;
974222544Sjkim        AcpiGbl_DbMethodInfo.Types = Types;
975114237Snjl        AcpiGbl_DbMethodInfo.Flags = Flags;
97667754Smsmith
977114237Snjl        ReturnObj.Pointer = NULL;
978114237Snjl        ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
979100966Siwasaki
980114237Snjl        AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
981239340Sjkim
982239340Sjkim        /* Get the NS node, determines existence also */
983239340Sjkim
984239340Sjkim        Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname,
985239340Sjkim            &AcpiGbl_DbMethodInfo.Method);
986239340Sjkim        if (ACPI_FAILURE (Status))
987239340Sjkim        {
988239340Sjkim            return;
989239340Sjkim        }
990239340Sjkim
991114237Snjl        Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj);
992167802Sjkim        ACPI_FREE (NameString);
993114237Snjl    }
99467754Smsmith
99582367Smsmith    /*
99682367Smsmith     * Allow any handlers in separate threads to complete.
99782367Smsmith     * (Such as Notify handlers invoked from AML executed above).
99882367Smsmith     */
999202771Sjkim    AcpiOsSleep ((UINT64) 10);
100067754Smsmith
100182367Smsmith
1002102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT
100369450Smsmith
100467754Smsmith    /* Memory allocation tracking */
100567754Smsmith
100682367Smsmith    Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations;
100767754Smsmith
100891116Smsmith    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
100967754Smsmith
101067754Smsmith    if (Allocations > 0)
101167754Smsmith    {
1012138287Smarks        AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n",
101382367Smsmith                        Allocations);
101467754Smsmith    }
101569450Smsmith#endif
101667754Smsmith
101767754Smsmith    if (ACPI_FAILURE (Status))
101867754Smsmith    {
101983174Smsmith        AcpiOsPrintf ("Execution of %s failed with status %s\n",
102083174Smsmith            AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status));
102167754Smsmith    }
102267754Smsmith    else
102367754Smsmith    {
102467754Smsmith        /* Display a return object, if any */
102567754Smsmith
102667754Smsmith        if (ReturnObj.Length)
102767754Smsmith        {
102877424Smsmith            AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
1029114237Snjl                AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer,
1030104470Siwasaki                (UINT32) ReturnObj.Length);
1031151937Sjkim            AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
1032239340Sjkim
1033239340Sjkim            /* Dump a _PLD buffer if present */
1034239340Sjkim
1035239340Sjkim            if (ACPI_COMPARE_NAME ((ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
1036239340Sjkim                    AcpiGbl_DbMethodInfo.Method)->Name.Ascii), METHOD_NAME__PLD))
1037239340Sjkim            {
1038239340Sjkim                AcpiDbDumpPldBuffer (ReturnObj.Pointer);
1039239340Sjkim            }
104067754Smsmith        }
1041100966Siwasaki        else
1042100966Siwasaki        {
1043102550Siwasaki            AcpiOsPrintf ("No return object from execution of %s\n",
1044100966Siwasaki                AcpiGbl_DbMethodInfo.Pathname);
1045100966Siwasaki        }
104667754Smsmith    }
104767754Smsmith
104891116Smsmith    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
104967754Smsmith}
105067754Smsmith
105167754Smsmith
105267754Smsmith/*******************************************************************************
105367754Smsmith *
105467754Smsmith * FUNCTION:    AcpiDbMethodThread
105567754Smsmith *
105667754Smsmith * PARAMETERS:  Context             - Execution info segment
105767754Smsmith *
105867754Smsmith * RETURN:      None
105967754Smsmith *
106067754Smsmith * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
106167754Smsmith *              simply dispatches it.
106267754Smsmith *
106367754Smsmith ******************************************************************************/
106467754Smsmith
1065151937Sjkimstatic void ACPI_SYSTEM_XFACE
106667754SmsmithAcpiDbMethodThread (
106767754Smsmith    void                    *Context)
106867754Smsmith{
106967754Smsmith    ACPI_STATUS             Status;
107091116Smsmith    ACPI_DB_METHOD_INFO     *Info = Context;
1071193267Sjkim    ACPI_DB_METHOD_INFO     LocalInfo;
107267754Smsmith    UINT32                  i;
1073167802Sjkim    UINT8                   Allow;
107467754Smsmith    ACPI_BUFFER             ReturnObj;
107567754Smsmith
107667754Smsmith
1077193267Sjkim    /*
1078193267Sjkim     * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments.
1079193267Sjkim     * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads
1080193267Sjkim     * concurrently.
1081193267Sjkim     *
1082193267Sjkim     * Note: The arguments we are passing are used by the ASL test suite
1083193267Sjkim     * (aslts). Do not change them without updating the tests.
1084193267Sjkim     */
1085193267Sjkim    (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER);
1086193267Sjkim
1087167802Sjkim    if (Info->InitArgs)
1088167802Sjkim    {
1089237412Sjkim        AcpiDbUint32ToHexString (Info->NumCreated, Info->IndexOfThreadStr);
1090237412Sjkim        AcpiDbUint32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr);
1091167802Sjkim    }
1092167802Sjkim
1093167802Sjkim    if (Info->Threads && (Info->NumCreated < Info->NumThreads))
1094167802Sjkim    {
1095212761Sjkim        Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId();
1096167802Sjkim    }
1097167802Sjkim
1098193267Sjkim    LocalInfo = *Info;
1099193267Sjkim    LocalInfo.Args = LocalInfo.Arguments;
1100193267Sjkim    LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr;
1101193267Sjkim    LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr;
1102193267Sjkim    LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr;
1103193267Sjkim    LocalInfo.Arguments[3] = NULL;
1104193267Sjkim
1105222544Sjkim    LocalInfo.Types = LocalInfo.ArgTypes;
1106222544Sjkim
1107193267Sjkim    (void) AcpiOsSignalSemaphore (Info->InfoGate, 1);
1108193267Sjkim
110967754Smsmith    for (i = 0; i < Info->NumLoops; i++)
111067754Smsmith    {
1111193267Sjkim        Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj);
1112117521Snjl        if (ACPI_FAILURE (Status))
111367754Smsmith        {
1114117521Snjl            AcpiOsPrintf ("%s During execution of %s at iteration %X\n",
1115117521Snjl                AcpiFormatException (Status), Info->Pathname, i);
1116127175Snjl            if (Status == AE_ABORT_METHOD)
1117127175Snjl            {
1118127175Snjl                break;
1119127175Snjl            }
112067754Smsmith        }
1121117521Snjl
1122167802Sjkim#if 0
1123128212Snjl        if ((i % 100) == 0)
1124117521Snjl        {
1125209746Sjkim            AcpiOsPrintf ("%u executions, Thread 0x%x\n", i, AcpiOsGetThreadId ());
1126117521Snjl        }
1127117521Snjl
1128117521Snjl        if (ReturnObj.Length)
1129117521Snjl        {
1130117521Snjl            AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
1131117521Snjl                Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length);
1132151937Sjkim            AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
1133117521Snjl        }
1134117521Snjl#endif
113567754Smsmith    }
113667754Smsmith
113767754Smsmith    /* Signal our completion */
113867754Smsmith
1139167802Sjkim    Allow = 0;
1140193267Sjkim    (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER);
1141167802Sjkim    Info->NumCompleted++;
1142167802Sjkim
1143167802Sjkim    if (Info->NumCompleted == Info->NumThreads)
114499679Siwasaki    {
1145167802Sjkim        /* Do signal for main thread once only */
1146167802Sjkim        Allow = 1;
114799679Siwasaki    }
1148167802Sjkim
1149193267Sjkim    (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1);
1150167802Sjkim
1151167802Sjkim    if (Allow)
1152167802Sjkim    {
1153167802Sjkim        Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1);
1154167802Sjkim        if (ACPI_FAILURE (Status))
1155167802Sjkim        {
1156167802Sjkim            AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n",
1157167802Sjkim                AcpiFormatException (Status));
1158167802Sjkim        }
1159167802Sjkim    }
116067754Smsmith}
116167754Smsmith
116267754Smsmith
116367754Smsmith/*******************************************************************************
116467754Smsmith *
116567754Smsmith * FUNCTION:    AcpiDbCreateExecutionThreads
116667754Smsmith *
116767754Smsmith * PARAMETERS:  NumThreadsArg           - Number of threads to create
116867754Smsmith *              NumLoopsArg             - Loop count for the thread(s)
116967754Smsmith *              MethodNameArg           - Control method to execute
117067754Smsmith *
117167754Smsmith * RETURN:      None
117267754Smsmith *
117367754Smsmith * DESCRIPTION: Create threads to execute method(s)
117467754Smsmith *
117567754Smsmith ******************************************************************************/
117667754Smsmith
117767754Smsmithvoid
117867754SmsmithAcpiDbCreateExecutionThreads (
1179114237Snjl    char                    *NumThreadsArg,
1180114237Snjl    char                    *NumLoopsArg,
1181114237Snjl    char                    *MethodNameArg)
118267754Smsmith{
118367754Smsmith    ACPI_STATUS             Status;
118467754Smsmith    UINT32                  NumThreads;
118567754Smsmith    UINT32                  NumLoops;
118667754Smsmith    UINT32                  i;
1187167802Sjkim    UINT32                  Size;
1188167802Sjkim    ACPI_MUTEX              MainThreadGate;
1189167802Sjkim    ACPI_MUTEX              ThreadCompleteGate;
1190193267Sjkim    ACPI_MUTEX              InfoGate;
119167754Smsmith
1192193267Sjkim
119367754Smsmith    /* Get the arguments */
119467754Smsmith
119591116Smsmith    NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0);
119691116Smsmith    NumLoops   = ACPI_STRTOUL (NumLoopsArg, NULL, 0);
119767754Smsmith
119867754Smsmith    if (!NumThreads || !NumLoops)
119967754Smsmith    {
1200151937Sjkim        AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n",
1201151937Sjkim            NumThreads, NumLoops);
120267754Smsmith        return;
120367754Smsmith    }
120467754Smsmith
1205167802Sjkim    /*
1206167802Sjkim     * Create the semaphore for synchronization of
1207167802Sjkim     * the created threads with the main thread.
1208167802Sjkim     */
1209167802Sjkim    Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate);
1210167802Sjkim    if (ACPI_FAILURE (Status))
1211167802Sjkim    {
1212167802Sjkim        AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n",
1213167802Sjkim            AcpiFormatException (Status));
1214167802Sjkim        return;
1215167802Sjkim    }
121667754Smsmith
1217167802Sjkim    /*
1218167802Sjkim     * Create the semaphore for synchronization
1219167802Sjkim     * between the created threads.
1220167802Sjkim     */
1221167802Sjkim    Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate);
122267754Smsmith    if (ACPI_FAILURE (Status))
122367754Smsmith    {
1224167802Sjkim        AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n",
1225151937Sjkim            AcpiFormatException (Status));
1226167802Sjkim        (void) AcpiOsDeleteSemaphore (MainThreadGate);
122767754Smsmith        return;
122867754Smsmith    }
122967754Smsmith
1230193267Sjkim    Status = AcpiOsCreateSemaphore (1, 1, &InfoGate);
1231193267Sjkim    if (ACPI_FAILURE (Status))
1232193267Sjkim    {
1233193267Sjkim        AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n",
1234193267Sjkim            AcpiFormatException (Status));
1235193267Sjkim        (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
1236193267Sjkim        (void) AcpiOsDeleteSemaphore (MainThreadGate);
1237193267Sjkim        return;
1238193267Sjkim    }
1239193267Sjkim
1240167802Sjkim    ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
1241167802Sjkim
1242167802Sjkim    /* Array to store IDs of threads */
1243167802Sjkim
1244167802Sjkim    AcpiGbl_DbMethodInfo.NumThreads = NumThreads;
1245212761Sjkim    Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads;
1246212761Sjkim    AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size);
1247167802Sjkim    if (AcpiGbl_DbMethodInfo.Threads == NULL)
1248167802Sjkim    {
1249167802Sjkim        AcpiOsPrintf ("No memory for thread IDs array\n");
1250167802Sjkim        (void) AcpiOsDeleteSemaphore (MainThreadGate);
1251167802Sjkim        (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
1252193267Sjkim        (void) AcpiOsDeleteSemaphore (InfoGate);
1253167802Sjkim        return;
1254167802Sjkim    }
1255167802Sjkim    ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size);
1256167802Sjkim
125767754Smsmith    /* Setup the context to be passed to each thread */
125867754Smsmith
125983174Smsmith    AcpiGbl_DbMethodInfo.Name = MethodNameArg;
126083174Smsmith    AcpiGbl_DbMethodInfo.Flags = 0;
126183174Smsmith    AcpiGbl_DbMethodInfo.NumLoops = NumLoops;
1262167802Sjkim    AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate;
1263167802Sjkim    AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate;
1264193267Sjkim    AcpiGbl_DbMethodInfo.InfoGate = InfoGate;
126567754Smsmith
1266167802Sjkim    /* Init arguments to be passed to method */
1267167802Sjkim
1268167802Sjkim    AcpiGbl_DbMethodInfo.InitArgs = 1;
1269167802Sjkim    AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments;
1270167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr;
1271167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr;
1272167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr;
1273167802Sjkim    AcpiGbl_DbMethodInfo.Arguments[3] = NULL;
1274222544Sjkim
1275222544Sjkim    AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes;
1276222544Sjkim    AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER;
1277222544Sjkim    AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER;
1278222544Sjkim    AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER;
1279222544Sjkim
1280237412Sjkim    AcpiDbUint32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr);
1281167802Sjkim
128283174Smsmith    AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
128367754Smsmith
1284239340Sjkim    /* Get the NS node, determines existence also */
1285239340Sjkim
1286239340Sjkim    Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname,
1287239340Sjkim        &AcpiGbl_DbMethodInfo.Method);
1288239340Sjkim    if (ACPI_FAILURE (Status))
1289239340Sjkim    {
1290239340Sjkim        AcpiOsPrintf ("%s Could not get handle for %s\n",
1291239340Sjkim            AcpiFormatException (Status), AcpiGbl_DbMethodInfo.Pathname);
1292239340Sjkim        goto CleanupAndExit;
1293239340Sjkim    }
1294239340Sjkim
129567754Smsmith    /* Create the threads */
129667754Smsmith
1297151937Sjkim    AcpiOsPrintf ("Creating %X threads to execute %X times each\n",
1298151937Sjkim        NumThreads, NumLoops);
129967754Smsmith
130067754Smsmith    for (i = 0; i < (NumThreads); i++)
130167754Smsmith    {
1302167802Sjkim        Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread,
1303151937Sjkim            &AcpiGbl_DbMethodInfo);
130499679Siwasaki        if (ACPI_FAILURE (Status))
130599679Siwasaki        {
130699679Siwasaki            break;
130799679Siwasaki        }
130867754Smsmith    }
130967754Smsmith
131067754Smsmith    /* Wait for all threads to complete */
131167754Smsmith
1312193267Sjkim    (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER);
131367754Smsmith
1314167802Sjkim    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1315167802Sjkim    AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads);
1316167802Sjkim    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1317167802Sjkim
1318239340SjkimCleanupAndExit:
1319239340Sjkim
132067754Smsmith    /* Cleanup and exit */
132167754Smsmith
1322167802Sjkim    (void) AcpiOsDeleteSemaphore (MainThreadGate);
1323167802Sjkim    (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
1324193267Sjkim    (void) AcpiOsDeleteSemaphore (InfoGate);
132567754Smsmith
1326167802Sjkim    AcpiOsFree (AcpiGbl_DbMethodInfo.Threads);
1327167802Sjkim    AcpiGbl_DbMethodInfo.Threads = NULL;
132867754Smsmith}
132967754Smsmith
1330102550Siwasaki#endif /* ACPI_DEBUGGER */
133167754Smsmith
133267754Smsmith
1333