Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: dbexec - debugger control method execution
  4.  *
  5.  ******************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  12.  * All rights reserved.
  13.  *
  14.  * 2. License
  15.  *
  16.  * 2.1. This is your license from Intel Corp. under its intellectual property
  17.  * rights.  You may have additional license terms from the party that provided
  18.  * you this software, covering your right to use that party's intellectual
  19.  * property rights.
  20.  *
  21.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  22.  * copy of the source code appearing in this file ("Covered Code") an
  23.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  24.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  25.  * make derivatives, distribute, use and display any portion of the Covered
  26.  * Code in any form, with the right to sublicense such rights; and
  27.  *
  28.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  29.  * license (with the right to sublicense), under only those claims of Intel
  30.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  31.  * offer to sell, and import the Covered Code and derivative works thereof
  32.  * solely to the minimum extent necessary to exercise the above copyright
  33.  * license, and in no event shall the patent license extend to any additions
  34.  * to or modifications of the Original Intel Code.  No other license or right
  35.  * is granted directly or by implication, estoppel or otherwise;
  36.  *
  37.  * The above copyright and patent license is granted only if the following
  38.  * conditions are met:
  39.  *
  40.  * 3. Conditions
  41.  *
  42.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  43.  * Redistribution of source code of any substantial portion of the Covered
  44.  * Code or modification with rights to further distribute source must include
  45.  * the above Copyright Notice, the above License, this list of Conditions,
  46.  * and the following Disclaimer and Export Compliance provision.  In addition,
  47.  * Licensee must cause all Covered Code to which Licensee contributes to
  48.  * contain a file documenting the changes Licensee made to create that Covered
  49.  * Code and the date of any change.  Licensee must include in that file the
  50.  * documentation of any changes made by any predecessor Licensee.  Licensee
  51.  * must include a prominent statement that the modification is derived,
  52.  * directly or indirectly, from Original Intel Code.
  53.  *
  54.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  55.  * Redistribution of source code of any substantial portion of the Covered
  56.  * Code or modification without rights to further distribute source must
  57.  * include the following Disclaimer and Export Compliance provision in the
  58.  * documentation and/or other materials provided with distribution.  In
  59.  * addition, Licensee may not authorize further sublicense of source of any
  60.  * portion of the Covered Code, and must include terms to the effect that the
  61.  * license from Licensee to its licensee is limited to the intellectual
  62.  * property embodied in the software Licensee provides to its licensee, and
  63.  * not to intellectual property embodied in modifications its licensee may
  64.  * make.
  65.  *
  66.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  67.  * substantial portion of the Covered Code or modification must reproduce the
  68.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  69.  * provision in the documentation and/or other materials provided with the
  70.  * distribution.
  71.  *
  72.  * 3.4. Intel retains all right, title, and interest in and to the Original
  73.  * Intel Code.
  74.  *
  75.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  76.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  77.  * other dealings in products derived from or relating to the Covered Code
  78.  * without prior written authorization from Intel.
  79.  *
  80.  * 4. Disclaimer and Export Compliance
  81.  *
  82.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  83.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  84.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  85.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  86.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  87.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  88.  * PARTICULAR PURPOSE.
  89.  *
  90.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  91.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  92.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  93.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  94.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  95.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  96.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  97.  * LIMITED REMEDY.
  98.  *
  99.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100.  * software or system incorporating such software without first obtaining any
  101.  * required license or other approval from the U. S. Department of Commerce or
  102.  * any other agency or department of the United States Government.  In the
  103.  * event Licensee exports any such software from the United States or
  104.  * re-exports any such software from a foreign destination, Licensee shall
  105.  * ensure that the distribution and export/re-export of the software is in
  106.  * compliance with all laws, regulations, orders, or other restrictions of the
  107.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108.  * any of its subsidiaries will export/re-export any technical data, process,
  109.  * software, or service, directly or indirectly, to any country for which the
  110.  * United States government or any agency thereof requires an export license,
  111.  * other governmental approval, or letter of assurance, without first obtaining
  112.  * such license, approval or letter.
  113.  *
  114.  *****************************************************************************/
  115.  
  116.  
  117. #include "acpi.h"
  118. #include "accommon.h"
  119. #include "acdebug.h"
  120. #include "acnamesp.h"
  121.  
  122. #ifdef ACPI_DEBUGGER
  123.  
  124. #define _COMPONENT          ACPI_CA_DEBUGGER
  125.         ACPI_MODULE_NAME    ("dbexec")
  126.  
  127.  
  128. static ACPI_DB_METHOD_INFO          AcpiGbl_DbMethodInfo;
  129. #define DB_DEFAULT_PKG_ELEMENTS     33
  130.  
  131. /* Local prototypes */
  132.  
  133. static ACPI_STATUS
  134. AcpiDbExecuteMethod (
  135.     ACPI_DB_METHOD_INFO     *Info,
  136.     ACPI_BUFFER             *ReturnObj);
  137.  
  138. static void
  139. AcpiDbExecuteSetup (
  140.     ACPI_DB_METHOD_INFO     *Info);
  141.  
  142. static UINT32
  143. AcpiDbGetOutstandingAllocations (
  144.     void);
  145.  
  146. static void ACPI_SYSTEM_XFACE
  147. AcpiDbMethodThread (
  148.     void                    *Context);
  149.  
  150. static ACPI_STATUS
  151. AcpiDbExecutionWalk (
  152.     ACPI_HANDLE             ObjHandle,
  153.     UINT32                  NestingLevel,
  154.     void                    *Context,
  155.     void                    **ReturnValue);
  156.  
  157. static ACPI_STATUS
  158. AcpiDbHexCharToValue (
  159.     int                     HexChar,
  160.     UINT8                   *ReturnValue);
  161.  
  162. static ACPI_STATUS
  163. AcpiDbConvertToPackage (
  164.     char                    *String,
  165.     ACPI_OBJECT             *Object);
  166.  
  167. static ACPI_STATUS
  168. AcpiDbConvertToObject (
  169.     ACPI_OBJECT_TYPE        Type,
  170.     char                    *String,
  171.     ACPI_OBJECT             *Object);
  172.  
  173. static void
  174. AcpiDbDeleteObjects (
  175.     UINT32                  Count,
  176.     ACPI_OBJECT             *Objects);
  177.  
  178.  
  179. /*******************************************************************************
  180.  *
  181.  * FUNCTION:    AcpiDbHexCharToValue
  182.  *
  183.  * PARAMETERS:  HexChar             - Ascii Hex digit, 0-9|a-f|A-F
  184.  *              ReturnValue         - Where the converted value is returned
  185.  *
  186.  * RETURN:      Status
  187.  *
  188.  * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16).
  189.  *
  190.  ******************************************************************************/
  191.  
  192. static ACPI_STATUS
  193. AcpiDbHexCharToValue (
  194.     int                     HexChar,
  195.     UINT8                   *ReturnValue)
  196. {
  197.     UINT8                   Value;
  198.  
  199.  
  200.     /* Digit must be ascii [0-9a-fA-F] */
  201.  
  202.     if (!ACPI_IS_XDIGIT (HexChar))
  203.     {
  204.         return (AE_BAD_HEX_CONSTANT);
  205.     }
  206.  
  207.     if (HexChar <= 0x39)
  208.     {
  209.         Value = (UINT8) (HexChar - 0x30);
  210.     }
  211.     else
  212.     {
  213.         Value = (UINT8) (ACPI_TOUPPER (HexChar) - 0x37);
  214.     }
  215.  
  216.     *ReturnValue = Value;
  217.     return (AE_OK);
  218. }
  219.  
  220.  
  221. /*******************************************************************************
  222.  *
  223.  * FUNCTION:    AcpiDbHexByteToBinary
  224.  *
  225.  * PARAMETERS:  HexByte             - Double hex digit (0x00 - 0xFF) in format:
  226.  *                                    HiByte then LoByte.
  227.  *              ReturnValue         - Where the converted value is returned
  228.  *
  229.  * RETURN:      Status
  230.  *
  231.  * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255).
  232.  *
  233.  ******************************************************************************/
  234.  
  235. static ACPI_STATUS
  236. AcpiDbHexByteToBinary (
  237.     char                    *HexByte,
  238.     UINT8                   *ReturnValue)
  239. {
  240.     UINT8                   Local0;
  241.     UINT8                   Local1;
  242.     ACPI_STATUS             Status;
  243.  
  244.  
  245.     /* High byte */
  246.  
  247.     Status = AcpiDbHexCharToValue (HexByte[0], &Local0);
  248.     if (ACPI_FAILURE (Status))
  249.     {
  250.         return (Status);
  251.     }
  252.  
  253.     /* Low byte */
  254.  
  255.     Status = AcpiDbHexCharToValue (HexByte[1], &Local1);
  256.     if (ACPI_FAILURE (Status))
  257.     {
  258.         return (Status);
  259.     }
  260.  
  261.     *ReturnValue = (UINT8) ((Local0 << 4) | Local1);
  262.     return (AE_OK);
  263. }
  264.  
  265.  
  266. /*******************************************************************************
  267.  *
  268.  * FUNCTION:    AcpiDbConvertToBuffer
  269.  *
  270.  * PARAMETERS:  String              - Input string to be converted
  271.  *              Object              - Where the buffer object is returned
  272.  *
  273.  * RETURN:      Status
  274.  *
  275.  * DESCRIPTION: Convert a string to a buffer object. String is treated a list
  276.  *              of buffer elements, each separated by a space or comma.
  277.  *
  278.  ******************************************************************************/
  279.  
  280. static ACPI_STATUS
  281. AcpiDbConvertToBuffer (
  282.     char                    *String,
  283.     ACPI_OBJECT             *Object)
  284. {
  285.     UINT32                  i;
  286.     UINT32                  j;
  287.     UINT32                  Length;
  288.     UINT8                   *Buffer;
  289.     ACPI_STATUS             Status;
  290.  
  291.  
  292.     /* Generate the final buffer length */
  293.  
  294.     for (i = 0, Length = 0; String[i];)
  295.     {
  296.         i+=2;
  297.         Length++;
  298.  
  299.         while (String[i] &&
  300.               ((String[i] == ',') || (String[i] == ' ')))
  301.         {
  302.             i++;
  303.         }
  304.     }
  305.  
  306.     Buffer = ACPI_ALLOCATE (Length);
  307.     if (!Buffer)
  308.     {
  309.         return (AE_NO_MEMORY);
  310.     }
  311.  
  312.     /* Convert the command line bytes to the buffer */
  313.  
  314.     for (i = 0, j = 0; String[i];)
  315.     {
  316.         Status = AcpiDbHexByteToBinary (&String[i], &Buffer[j]);
  317.         if (ACPI_FAILURE (Status))
  318.         {
  319.             ACPI_FREE (Buffer);
  320.             return (Status);
  321.         }
  322.  
  323.         j++;
  324.         i+=2;
  325.         while (String[i] &&
  326.               ((String[i] == ',') || (String[i] == ' ')))
  327.         {
  328.             i++;
  329.         }
  330.     }
  331.  
  332.     Object->Type = ACPI_TYPE_BUFFER;
  333.     Object->Buffer.Pointer = Buffer;
  334.     Object->Buffer.Length = Length;
  335.     return (AE_OK);
  336. }
  337.  
  338.  
  339. /*******************************************************************************
  340.  *
  341.  * FUNCTION:    AcpiDbConvertToPackage
  342.  *
  343.  * PARAMETERS:  String              - Input string to be converted
  344.  *              Object              - Where the package object is returned
  345.  *
  346.  * RETURN:      Status
  347.  *
  348.  * DESCRIPTION: Convert a string to a package object. Handles nested packages
  349.  *              via recursion with AcpiDbConvertToObject.
  350.  *
  351.  ******************************************************************************/
  352.  
  353. static ACPI_STATUS
  354. AcpiDbConvertToPackage (
  355.     char                    *String,
  356.     ACPI_OBJECT             *Object)
  357. {
  358.     char                    *This;
  359.     char                    *Next;
  360.     UINT32                  i;
  361.     ACPI_OBJECT_TYPE        Type;
  362.     ACPI_OBJECT             *Elements;
  363.     ACPI_STATUS             Status;
  364.  
  365.  
  366.     Elements = ACPI_ALLOCATE_ZEROED (
  367.         DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT));
  368.  
  369.     This = String;
  370.     for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++)
  371.     {
  372.         This = AcpiDbGetNextToken (This, &Next, &Type);
  373.         if (!This)
  374.         {
  375.             break;
  376.         }
  377.  
  378.         /* Recursive call to convert each package element */
  379.  
  380.         Status = AcpiDbConvertToObject (Type, This, &Elements[i]);
  381.         if (ACPI_FAILURE (Status))
  382.         {
  383.             AcpiDbDeleteObjects (i + 1, Elements);
  384.             ACPI_FREE (Elements);
  385.             return (Status);
  386.         }
  387.  
  388.         This = Next;
  389.     }
  390.  
  391.     Object->Type = ACPI_TYPE_PACKAGE;
  392.     Object->Package.Count = i;
  393.     Object->Package.Elements = Elements;
  394.     return (AE_OK);
  395. }
  396.  
  397.  
  398. /*******************************************************************************
  399.  *
  400.  * FUNCTION:    AcpiDbConvertToObject
  401.  *
  402.  * PARAMETERS:  Type                - Object type as determined by parser
  403.  *              String              - Input string to be converted
  404.  *              Object              - Where the new object is returned
  405.  *
  406.  * RETURN:      Status
  407.  *
  408.  * DESCRIPTION: Convert a typed and tokenized string to an ACPI_OBJECT. Typing:
  409.  *              1) String objects were surrounded by quotes.
  410.  *              2) Buffer objects were surrounded by parentheses.
  411.  *              3) Package objects were surrounded by brackets "[]".
  412.  *              4) All standalone tokens are treated as integers.
  413.  *
  414.  ******************************************************************************/
  415.  
  416. static ACPI_STATUS
  417. AcpiDbConvertToObject (
  418.     ACPI_OBJECT_TYPE        Type,
  419.     char                    *String,
  420.     ACPI_OBJECT             *Object)
  421. {
  422.     ACPI_STATUS             Status = AE_OK;
  423.  
  424.  
  425.     switch (Type)
  426.     {
  427.     case ACPI_TYPE_STRING:
  428.         Object->Type = ACPI_TYPE_STRING;
  429.         Object->String.Pointer = String;
  430.         Object->String.Length = (UINT32) ACPI_STRLEN (String);
  431.         break;
  432.  
  433.     case ACPI_TYPE_BUFFER:
  434.         Status = AcpiDbConvertToBuffer (String, Object);
  435.         break;
  436.  
  437.     case ACPI_TYPE_PACKAGE:
  438.         Status = AcpiDbConvertToPackage (String, Object);
  439.         break;
  440.  
  441.     default:
  442.         Object->Type = ACPI_TYPE_INTEGER;
  443.         Status = AcpiUtStrtoul64 (String, 16, &Object->Integer.Value);
  444.         break;
  445.     }
  446.  
  447.     return (Status);
  448. }
  449.  
  450.  
  451. /*******************************************************************************
  452.  *
  453.  * FUNCTION:    AcpiDbDeleteObjects
  454.  *
  455.  * PARAMETERS:  Count               - Count of objects in the list
  456.  *              Objects             - Array of ACPI_OBJECTs to be deleted
  457.  *
  458.  * RETURN:      None
  459.  *
  460.  * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested
  461.  *              packages via recursion.
  462.  *
  463.  ******************************************************************************/
  464.  
  465. static void
  466. AcpiDbDeleteObjects (
  467.     UINT32                  Count,
  468.     ACPI_OBJECT             *Objects)
  469. {
  470.     UINT32                  i;
  471.  
  472.  
  473.     for (i = 0; i < Count; i++)
  474.     {
  475.         switch (Objects[i].Type)
  476.         {
  477.         case ACPI_TYPE_BUFFER:
  478.             ACPI_FREE (Objects[i].Buffer.Pointer);
  479.             break;
  480.  
  481.         case ACPI_TYPE_PACKAGE:
  482.  
  483.             /* Recursive call to delete package elements */
  484.  
  485.             AcpiDbDeleteObjects (Objects[i].Package.Count,
  486.                 Objects[i].Package.Elements);
  487.  
  488.             /* Free the elements array */
  489.  
  490.             ACPI_FREE (Objects[i].Package.Elements);
  491.             break;
  492.  
  493.         default:
  494.             break;
  495.         }
  496.     }
  497. }
  498.  
  499.  
  500. /*******************************************************************************
  501.  *
  502.  * FUNCTION:    AcpiDbExecuteMethod
  503.  *
  504.  * PARAMETERS:  Info            - Valid info segment
  505.  *              ReturnObj       - Where to put return object
  506.  *
  507.  * RETURN:      Status
  508.  *
  509.  * DESCRIPTION: Execute a control method.
  510.  *
  511.  ******************************************************************************/
  512.  
  513. static ACPI_STATUS
  514. AcpiDbExecuteMethod (
  515.     ACPI_DB_METHOD_INFO     *Info,
  516.     ACPI_BUFFER             *ReturnObj)
  517. {
  518.     ACPI_STATUS             Status;
  519.     ACPI_OBJECT_LIST        ParamObjects;
  520.     ACPI_OBJECT             Params[ACPI_METHOD_NUM_ARGS];
  521.     ACPI_HANDLE             Handle;
  522.     ACPI_DEVICE_INFO        *ObjInfo;
  523.     UINT32                  i;
  524.  
  525.  
  526.     ACPI_FUNCTION_TRACE (DbExecuteMethod);
  527.  
  528.  
  529.     if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel)
  530.     {
  531.         AcpiOsPrintf ("Warning: debug output is not enabled!\n");
  532.     }
  533.  
  534.     /* Get the NS node, determines existence also */
  535.  
  536.     Status = AcpiGetHandle (NULL, Info->Pathname, &Handle);
  537.     if (ACPI_FAILURE (Status))
  538.     {
  539.         return_ACPI_STATUS (Status);
  540.     }
  541.  
  542.     /* Get the object info for number of method parameters */
  543.  
  544.     Status = AcpiGetObjectInfo (Handle, &ObjInfo);
  545.     if (ACPI_FAILURE (Status))
  546.     {
  547.         return_ACPI_STATUS (Status);
  548.     }
  549.  
  550.     ParamObjects.Pointer = NULL;
  551.     ParamObjects.Count   = 0;
  552.  
  553.     if (ObjInfo->Type == ACPI_TYPE_METHOD)
  554.     {
  555.         /* Are there arguments to the method? */
  556.  
  557.         i = 0;
  558.         if (Info->Args && Info->Args[0])
  559.         {
  560.             /* Get arguments passed on the command line */
  561.  
  562.             for (; Info->Args[i] &&
  563.                 (i < ACPI_METHOD_NUM_ARGS) &&
  564.                 (i < ObjInfo->ParamCount);
  565.                 i++)
  566.             {
  567.                 /* Convert input string (token) to an actual ACPI_OBJECT */
  568.  
  569.                 Status = AcpiDbConvertToObject (Info->Types[i],
  570.                     Info->Args[i], &Params[i]);
  571.                 if (ACPI_FAILURE (Status))
  572.                 {
  573.                     ACPI_EXCEPTION ((AE_INFO, Status,
  574.                         "While parsing method arguments"));
  575.                     goto Cleanup;
  576.                 }
  577.             }
  578.         }
  579.  
  580.         /* Create additional "default" parameters as needed */
  581.  
  582.         if (i < ObjInfo->ParamCount)
  583.         {
  584.             AcpiOsPrintf ("Adding %u arguments containing default values\n",
  585.                 ObjInfo->ParamCount - i);
  586.  
  587.             for (; i < ObjInfo->ParamCount; i++)
  588.             {
  589.                 switch (i)
  590.                 {
  591.                 case 0:
  592.  
  593.                     Params[0].Type           = ACPI_TYPE_INTEGER;
  594.                     Params[0].Integer.Value  = 0x01020304;
  595.                     break;
  596.  
  597.                 case 1:
  598.  
  599.                     Params[1].Type           = ACPI_TYPE_STRING;
  600.                     Params[1].String.Length  = 12;
  601.                     Params[1].String.Pointer = "AML Debugger";
  602.                     break;
  603.  
  604.                 default:
  605.  
  606.                     Params[i].Type           = ACPI_TYPE_INTEGER;
  607.                     Params[i].Integer.Value  = i * (UINT64) 0x1000;
  608.                     break;
  609.                 }
  610.             }
  611.         }
  612.  
  613.         ParamObjects.Count = ObjInfo->ParamCount;
  614.         ParamObjects.Pointer = Params;
  615.     }
  616.  
  617.     /* Prepare for a return object of arbitrary size */
  618.  
  619.     ReturnObj->Pointer = AcpiGbl_DbBuffer;
  620.     ReturnObj->Length  = ACPI_DEBUG_BUFFER_SIZE;
  621.  
  622.     /* Do the actual method execution */
  623.  
  624.     AcpiGbl_MethodExecuting = TRUE;
  625.     Status = AcpiEvaluateObject (NULL,
  626.         Info->Pathname, &ParamObjects, ReturnObj);
  627.  
  628.     AcpiGbl_CmSingleStep = FALSE;
  629.     AcpiGbl_MethodExecuting = FALSE;
  630.  
  631.     if (ACPI_FAILURE (Status))
  632.     {
  633.         ACPI_EXCEPTION ((AE_INFO, Status,
  634.             "while executing %s from debugger", Info->Pathname));
  635.  
  636.         if (Status == AE_BUFFER_OVERFLOW)
  637.         {
  638.             ACPI_ERROR ((AE_INFO,
  639.                 "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)",
  640.                 ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length));
  641.         }
  642.     }
  643.  
  644. Cleanup:
  645.     AcpiDbDeleteObjects (ObjInfo->ParamCount, Params);
  646.     ACPI_FREE (ObjInfo);
  647.  
  648.     return_ACPI_STATUS (Status);
  649. }
  650.  
  651.  
  652. /*******************************************************************************
  653.  *
  654.  * FUNCTION:    AcpiDbExecuteSetup
  655.  *
  656.  * PARAMETERS:  Info            - Valid method info
  657.  *
  658.  * RETURN:      None
  659.  *
  660.  * DESCRIPTION: Setup info segment prior to method execution
  661.  *
  662.  ******************************************************************************/
  663.  
  664. static void
  665. AcpiDbExecuteSetup (
  666.     ACPI_DB_METHOD_INFO     *Info)
  667. {
  668.  
  669.     /* Catenate the current scope to the supplied name */
  670.  
  671.     Info->Pathname[0] = 0;
  672.     if ((Info->Name[0] != '\\') &&
  673.         (Info->Name[0] != '/'))
  674.     {
  675.         ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf);
  676.     }
  677.  
  678.     ACPI_STRCAT (Info->Pathname, Info->Name);
  679.     AcpiDbPrepNamestring (Info->Pathname);
  680.  
  681.     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
  682.     AcpiOsPrintf ("Executing %s\n", Info->Pathname);
  683.  
  684.     if (Info->Flags & EX_SINGLE_STEP)
  685.     {
  686.         AcpiGbl_CmSingleStep = TRUE;
  687.         AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
  688.     }
  689.  
  690.     else
  691.     {
  692.         /* No single step, allow redirection to a file */
  693.  
  694.         AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
  695.     }
  696. }
  697.  
  698.  
  699. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  700. UINT32
  701. AcpiDbGetCacheInfo (
  702.     ACPI_MEMORY_LIST        *Cache)
  703. {
  704.  
  705.     return (Cache->TotalAllocated - Cache->TotalFreed - Cache->CurrentDepth);
  706. }
  707. #endif
  708.  
  709. /*******************************************************************************
  710.  *
  711.  * FUNCTION:    AcpiDbGetOutstandingAllocations
  712.  *
  713.  * PARAMETERS:  None
  714.  *
  715.  * RETURN:      Current global allocation count minus cache entries
  716.  *
  717.  * DESCRIPTION: Determine the current number of "outstanding" allocations --
  718.  *              those allocations that have not been freed and also are not
  719.  *              in one of the various object caches.
  720.  *
  721.  ******************************************************************************/
  722.  
  723. static UINT32
  724. AcpiDbGetOutstandingAllocations (
  725.     void)
  726. {
  727.     UINT32                  Outstanding = 0;
  728.  
  729. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  730.  
  731.     Outstanding += AcpiDbGetCacheInfo (AcpiGbl_StateCache);
  732.     Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeCache);
  733.     Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeExtCache);
  734.     Outstanding += AcpiDbGetCacheInfo (AcpiGbl_OperandCache);
  735. #endif
  736.  
  737.     return (Outstanding);
  738. }
  739.  
  740.  
  741. /*******************************************************************************
  742.  *
  743.  * FUNCTION:    AcpiDbExecutionWalk
  744.  *
  745.  * PARAMETERS:  WALK_CALLBACK
  746.  *
  747.  * RETURN:      Status
  748.  *
  749.  * DESCRIPTION: Execute a control method.  Name is relative to the current
  750.  *              scope.
  751.  *
  752.  ******************************************************************************/
  753.  
  754. static ACPI_STATUS
  755. AcpiDbExecutionWalk (
  756.     ACPI_HANDLE             ObjHandle,
  757.     UINT32                  NestingLevel,
  758.     void                    *Context,
  759.     void                    **ReturnValue)
  760. {
  761.     ACPI_OPERAND_OBJECT     *ObjDesc;
  762.     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
  763.     ACPI_BUFFER             ReturnObj;
  764.     ACPI_STATUS             Status;
  765.  
  766.  
  767.     ObjDesc = AcpiNsGetAttachedObject (Node);
  768.     if (ObjDesc->Method.ParamCount)
  769.     {
  770.         return (AE_OK);
  771.     }
  772.  
  773.     ReturnObj.Pointer = NULL;
  774.     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
  775.  
  776.     AcpiNsPrintNodePathname (Node, "Execute");
  777.  
  778.     /* Do the actual method execution */
  779.  
  780.     AcpiOsPrintf ("\n");
  781.     AcpiGbl_MethodExecuting = TRUE;
  782.  
  783.     Status = AcpiEvaluateObject (Node, NULL, NULL, &ReturnObj);
  784.  
  785.     AcpiOsPrintf ("[%4.4s] returned %s\n", AcpiUtGetNodeName (Node),
  786.             AcpiFormatException (Status));
  787.     AcpiGbl_MethodExecuting = FALSE;
  788.  
  789.     return (AE_OK);
  790. }
  791.  
  792.  
  793. /*******************************************************************************
  794.  *
  795.  * FUNCTION:    AcpiDbExecute
  796.  *
  797.  * PARAMETERS:  Name                - Name of method to execute
  798.  *              Args                - Parameters to the method
  799.  *              Flags               - single step/no single step
  800.  *
  801.  * RETURN:      None
  802.  *
  803.  * DESCRIPTION: Execute a control method.  Name is relative to the current
  804.  *              scope.
  805.  *
  806.  ******************************************************************************/
  807.  
  808. void
  809. AcpiDbExecute (
  810.     char                    *Name,
  811.     char                    **Args,
  812.     ACPI_OBJECT_TYPE        *Types,
  813.     UINT32                  Flags)
  814. {
  815.     ACPI_STATUS             Status;
  816.     ACPI_BUFFER             ReturnObj;
  817.     char                    *NameString;
  818.  
  819.  
  820. #ifdef ACPI_DEBUG_OUTPUT
  821.     UINT32                  PreviousAllocations;
  822.     UINT32                  Allocations;
  823.  
  824.  
  825.     /* Memory allocation tracking */
  826.  
  827.     PreviousAllocations = AcpiDbGetOutstandingAllocations ();
  828. #endif
  829.  
  830.     if (*Name == '*')
  831.     {
  832.         (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT,
  833.                     ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL);
  834.         return;
  835.     }
  836.     else
  837.     {
  838.         NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1);
  839.         if (!NameString)
  840.         {
  841.             return;
  842.         }
  843.  
  844.         ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
  845.  
  846.         ACPI_STRCPY (NameString, Name);
  847.         AcpiUtStrupr (NameString);
  848.         AcpiGbl_DbMethodInfo.Name = NameString;
  849.         AcpiGbl_DbMethodInfo.Args = Args;
  850.         AcpiGbl_DbMethodInfo.Types = Types;
  851.         AcpiGbl_DbMethodInfo.Flags = Flags;
  852.  
  853.         ReturnObj.Pointer = NULL;
  854.         ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
  855.  
  856.         AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
  857.         Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj);
  858.         ACPI_FREE (NameString);
  859.     }
  860.  
  861.     /*
  862.      * Allow any handlers in separate threads to complete.
  863.      * (Such as Notify handlers invoked from AML executed above).
  864.      */
  865.     AcpiOsSleep ((UINT64) 10);
  866.  
  867.  
  868. #ifdef ACPI_DEBUG_OUTPUT
  869.  
  870.     /* Memory allocation tracking */
  871.  
  872.     Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations;
  873.  
  874.     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
  875.  
  876.     if (Allocations > 0)
  877.     {
  878.         AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n",
  879.                         Allocations);
  880.     }
  881. #endif
  882.  
  883.     if (ACPI_FAILURE (Status))
  884.     {
  885.         AcpiOsPrintf ("Execution of %s failed with status %s\n",
  886.             AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status));
  887.     }
  888.     else
  889.     {
  890.         /* Display a return object, if any */
  891.  
  892.         if (ReturnObj.Length)
  893.         {
  894.             AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
  895.                 AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer,
  896.                 (UINT32) ReturnObj.Length);
  897.             AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
  898.         }
  899.         else
  900.         {
  901.             AcpiOsPrintf ("No return object from execution of %s\n",
  902.                 AcpiGbl_DbMethodInfo.Pathname);
  903.         }
  904.     }
  905.  
  906.     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
  907. }
  908.  
  909.  
  910. /*******************************************************************************
  911.  *
  912.  * FUNCTION:    AcpiDbMethodThread
  913.  *
  914.  * PARAMETERS:  Context             - Execution info segment
  915.  *
  916.  * RETURN:      None
  917.  *
  918.  * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
  919.  *              simply dispatches it.
  920.  *
  921.  ******************************************************************************/
  922.  
  923. static void ACPI_SYSTEM_XFACE
  924. AcpiDbMethodThread (
  925.     void                    *Context)
  926. {
  927.     ACPI_STATUS             Status;
  928.     ACPI_DB_METHOD_INFO     *Info = Context;
  929.     ACPI_DB_METHOD_INFO     LocalInfo;
  930.     UINT32                  i;
  931.     UINT8                   Allow;
  932.     ACPI_BUFFER             ReturnObj;
  933.  
  934.  
  935.     /*
  936.      * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments.
  937.      * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads
  938.      * concurrently.
  939.      *
  940.      * Note: The arguments we are passing are used by the ASL test suite
  941.      * (aslts). Do not change them without updating the tests.
  942.      */
  943.     (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER);
  944.  
  945.     if (Info->InitArgs)
  946.     {
  947.         AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr);
  948.         AcpiDbUInt32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr);
  949.     }
  950.  
  951.     if (Info->Threads && (Info->NumCreated < Info->NumThreads))
  952.     {
  953.         Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId();
  954.     }
  955.  
  956.     LocalInfo = *Info;
  957.     LocalInfo.Args = LocalInfo.Arguments;
  958.     LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr;
  959.     LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr;
  960.     LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr;
  961.     LocalInfo.Arguments[3] = NULL;
  962.  
  963.     LocalInfo.Types = LocalInfo.ArgTypes;
  964.  
  965.     (void) AcpiOsSignalSemaphore (Info->InfoGate, 1);
  966.  
  967.     for (i = 0; i < Info->NumLoops; i++)
  968.     {
  969.         Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj);
  970.         if (ACPI_FAILURE (Status))
  971.         {
  972.             AcpiOsPrintf ("%s During execution of %s at iteration %X\n",
  973.                 AcpiFormatException (Status), Info->Pathname, i);
  974.             if (Status == AE_ABORT_METHOD)
  975.             {
  976.                 break;
  977.             }
  978.         }
  979.  
  980. #if 0
  981.         if ((i % 100) == 0)
  982.         {
  983.             AcpiOsPrintf ("%u executions, Thread 0x%x\n", i, AcpiOsGetThreadId ());
  984.         }
  985.  
  986.         if (ReturnObj.Length)
  987.         {
  988.             AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
  989.                 Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length);
  990.             AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
  991.         }
  992. #endif
  993.     }
  994.  
  995.     /* Signal our completion */
  996.  
  997.     Allow = 0;
  998.     (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER);
  999.     Info->NumCompleted++;
  1000.  
  1001.     if (Info->NumCompleted == Info->NumThreads)
  1002.     {
  1003.         /* Do signal for main thread once only */
  1004.         Allow = 1;
  1005.     }
  1006.  
  1007.     (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1);
  1008.  
  1009.     if (Allow)
  1010.     {
  1011.         Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1);
  1012.         if (ACPI_FAILURE (Status))
  1013.         {
  1014.             AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n",
  1015.                 AcpiFormatException (Status));
  1016.         }
  1017.     }
  1018. }
  1019.  
  1020.  
  1021. /*******************************************************************************
  1022.  *
  1023.  * FUNCTION:    AcpiDbCreateExecutionThreads
  1024.  *
  1025.  * PARAMETERS:  NumThreadsArg           - Number of threads to create
  1026.  *              NumLoopsArg             - Loop count for the thread(s)
  1027.  *              MethodNameArg           - Control method to execute
  1028.  *
  1029.  * RETURN:      None
  1030.  *
  1031.  * DESCRIPTION: Create threads to execute method(s)
  1032.  *
  1033.  ******************************************************************************/
  1034.  
  1035. void
  1036. AcpiDbCreateExecutionThreads (
  1037.     char                    *NumThreadsArg,
  1038.     char                    *NumLoopsArg,
  1039.     char                    *MethodNameArg)
  1040. {
  1041.     ACPI_STATUS             Status;
  1042.     UINT32                  NumThreads;
  1043.     UINT32                  NumLoops;
  1044.     UINT32                  i;
  1045.     UINT32                  Size;
  1046.     ACPI_MUTEX              MainThreadGate;
  1047.     ACPI_MUTEX              ThreadCompleteGate;
  1048.     ACPI_MUTEX              InfoGate;
  1049.  
  1050.  
  1051.     /* Get the arguments */
  1052.  
  1053.     NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0);
  1054.     NumLoops   = ACPI_STRTOUL (NumLoopsArg, NULL, 0);
  1055.  
  1056.     if (!NumThreads || !NumLoops)
  1057.     {
  1058.         AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n",
  1059.             NumThreads, NumLoops);
  1060.         return;
  1061.     }
  1062.  
  1063.     /*
  1064.      * Create the semaphore for synchronization of
  1065.      * the created threads with the main thread.
  1066.      */
  1067.     Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate);
  1068.     if (ACPI_FAILURE (Status))
  1069.     {
  1070.         AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n",
  1071.             AcpiFormatException (Status));
  1072.         return;
  1073.     }
  1074.  
  1075.     /*
  1076.      * Create the semaphore for synchronization
  1077.      * between the created threads.
  1078.      */
  1079.     Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate);
  1080.     if (ACPI_FAILURE (Status))
  1081.     {
  1082.         AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n",
  1083.             AcpiFormatException (Status));
  1084.         (void) AcpiOsDeleteSemaphore (MainThreadGate);
  1085.         return;
  1086.     }
  1087.  
  1088.     Status = AcpiOsCreateSemaphore (1, 1, &InfoGate);
  1089.     if (ACPI_FAILURE (Status))
  1090.     {
  1091.         AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n",
  1092.             AcpiFormatException (Status));
  1093.         (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
  1094.         (void) AcpiOsDeleteSemaphore (MainThreadGate);
  1095.         return;
  1096.     }
  1097.  
  1098.     ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
  1099.  
  1100.     /* Array to store IDs of threads */
  1101.  
  1102.     AcpiGbl_DbMethodInfo.NumThreads = NumThreads;
  1103.     Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads;
  1104.     AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size);
  1105.     if (AcpiGbl_DbMethodInfo.Threads == NULL)
  1106.     {
  1107.         AcpiOsPrintf ("No memory for thread IDs array\n");
  1108.         (void) AcpiOsDeleteSemaphore (MainThreadGate);
  1109.         (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
  1110.         (void) AcpiOsDeleteSemaphore (InfoGate);
  1111.         return;
  1112.     }
  1113.     ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size);
  1114.  
  1115.     /* Setup the context to be passed to each thread */
  1116.  
  1117.     AcpiGbl_DbMethodInfo.Name = MethodNameArg;
  1118.     AcpiGbl_DbMethodInfo.Flags = 0;
  1119.     AcpiGbl_DbMethodInfo.NumLoops = NumLoops;
  1120.     AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate;
  1121.     AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate;
  1122.     AcpiGbl_DbMethodInfo.InfoGate = InfoGate;
  1123.  
  1124.     /* Init arguments to be passed to method */
  1125.  
  1126.     AcpiGbl_DbMethodInfo.InitArgs = 1;
  1127.     AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments;
  1128.     AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr;
  1129.     AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr;
  1130.     AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr;
  1131.     AcpiGbl_DbMethodInfo.Arguments[3] = NULL;
  1132.  
  1133.     AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes;
  1134.     AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER;
  1135.     AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER;
  1136.     AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER;
  1137.  
  1138.     AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr);
  1139.  
  1140.     AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
  1141.  
  1142.     /* Create the threads */
  1143.  
  1144.     AcpiOsPrintf ("Creating %X threads to execute %X times each\n",
  1145.         NumThreads, NumLoops);
  1146.  
  1147.     for (i = 0; i < (NumThreads); i++)
  1148.     {
  1149.         Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread,
  1150.             &AcpiGbl_DbMethodInfo);
  1151.         if (ACPI_FAILURE (Status))
  1152.         {
  1153.             break;
  1154.         }
  1155.     }
  1156.  
  1157.     /* Wait for all threads to complete */
  1158.  
  1159.     (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER);
  1160.  
  1161.     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
  1162.     AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads);
  1163.     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
  1164.  
  1165.     /* Cleanup and exit */
  1166.  
  1167.     (void) AcpiOsDeleteSemaphore (MainThreadGate);
  1168.     (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
  1169.     (void) AcpiOsDeleteSemaphore (InfoGate);
  1170.  
  1171.     AcpiOsFree (AcpiGbl_DbMethodInfo.Threads);
  1172.     AcpiGbl_DbMethodInfo.Threads = NULL;
  1173. }
  1174.  
  1175. #endif /* ACPI_DEBUGGER */
  1176.  
  1177.  
  1178.