Home | History | Annotate | Line # | Download | only in debugger
dbtest.c revision 1.1.1.2
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbtest - Various debug-related tests
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2015, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "acdebug.h"
     47 #include "acnamesp.h"
     48 #include "acpredef.h"
     49 
     50 #ifdef ACPI_DEBUGGER
     51 
     52 #define _COMPONENT          ACPI_CA_DEBUGGER
     53         ACPI_MODULE_NAME    ("dbtest")
     54 
     55 
     56 /* Local prototypes */
     57 
     58 static void
     59 AcpiDbTestAllObjects (
     60     void);
     61 
     62 static ACPI_STATUS
     63 AcpiDbTestOneObject (
     64     ACPI_HANDLE             ObjHandle,
     65     UINT32                  NestingLevel,
     66     void                    *Context,
     67     void                    **ReturnValue);
     68 
     69 static ACPI_STATUS
     70 AcpiDbTestIntegerType (
     71     ACPI_NAMESPACE_NODE     *Node,
     72     UINT32                  BitLength);
     73 
     74 static ACPI_STATUS
     75 AcpiDbTestBufferType (
     76     ACPI_NAMESPACE_NODE     *Node,
     77     UINT32                  BitLength);
     78 
     79 static ACPI_STATUS
     80 AcpiDbTestStringType (
     81     ACPI_NAMESPACE_NODE     *Node,
     82     UINT32                  ByteLength);
     83 
     84 static ACPI_STATUS
     85 AcpiDbReadFromObject (
     86     ACPI_NAMESPACE_NODE     *Node,
     87     ACPI_OBJECT_TYPE        ExpectedType,
     88     ACPI_OBJECT             **Value);
     89 
     90 static ACPI_STATUS
     91 AcpiDbWriteToObject (
     92     ACPI_NAMESPACE_NODE     *Node,
     93     ACPI_OBJECT             *Value);
     94 
     95 static void
     96 AcpiDbEvaluateAllPredefinedNames (
     97     char                    *CountArg);
     98 
     99 static ACPI_STATUS
    100 AcpiDbEvaluateOnePredefinedName (
    101     ACPI_HANDLE             ObjHandle,
    102     UINT32                  NestingLevel,
    103     void                    *Context,
    104     void                    **ReturnValue);
    105 
    106 /*
    107  * Test subcommands
    108  */
    109 static ACPI_DB_ARGUMENT_INFO    AcpiDbTestTypes [] =
    110 {
    111     {"OBJECTS"},
    112     {"PREDEFINED"},
    113     {NULL}           /* Must be null terminated */
    114 };
    115 
    116 #define CMD_TEST_OBJECTS        0
    117 #define CMD_TEST_PREDEFINED     1
    118 
    119 #define BUFFER_FILL_VALUE       0xFF
    120 
    121 /*
    122  * Support for the special debugger read/write control methods.
    123  * These methods are installed into the current namespace and are
    124  * used to read and write the various namespace objects. The point
    125  * is to force the AML interpreter do all of the work.
    126  */
    127 #define                     ACPI_DB_READ_METHOD     "\\_T98"
    128 #define                     ACPI_DB_WRITE_METHOD    "\\_T99"
    129 
    130 static ACPI_HANDLE          ReadHandle = NULL;
    131 static ACPI_HANDLE          WriteHandle = NULL;
    132 
    133 /* ASL Definitions of the debugger read/write control methods */
    134 
    135 #if 0
    136 DefinitionBlock ("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
    137 {
    138     Method (_T98, 1, NotSerialized)     /* Read */
    139     {
    140         Return (DeRefOf (Arg0))
    141     }
    142 }
    143 DefinitionBlock ("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
    144 {
    145     Method (_T99, 2, NotSerialized)     /* Write */
    146     {
    147         Store (Arg1, Arg0)
    148     }
    149 }
    150 #endif
    151 
    152 static unsigned char ReadMethodCode[] =
    153 {
    154     0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00,  /* 00000000    "SSDT...." */
    155     0x02,0xC9,0x49,0x6E,0x74,0x65,0x6C,0x00,  /* 00000008    "..Intel." */
    156     0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00,  /* 00000010    "DEBUG..." */
    157     0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
    158     0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54,  /* 00000020    "... .._T" */
    159     0x39,0x38,0x01,0xA4,0x83,0x68             /* 00000028    "98...h"   */
    160 };
    161 
    162 static unsigned char WriteMethodCode[] =
    163 {
    164     0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00,  /* 00000000    "SSDT...." */
    165     0x02,0x15,0x49,0x6E,0x74,0x65,0x6C,0x00,  /* 00000008    "..Intel." */
    166     0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00,  /* 00000010    "DEBUG..." */
    167     0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
    168     0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54,  /* 00000020    "... .._T" */
    169     0x39,0x39,0x02,0x70,0x69,0x68             /* 00000028    "99.pih"   */
    170 };
    171 
    172 
    173 /*******************************************************************************
    174  *
    175  * FUNCTION:    AcpiDbExecuteTest
    176  *
    177  * PARAMETERS:  TypeArg         - Subcommand
    178  *
    179  * RETURN:      None
    180  *
    181  * DESCRIPTION: Execute various debug tests.
    182  *
    183  * Note: Code is prepared for future expansion of the TEST command.
    184  *
    185  ******************************************************************************/
    186 
    187 void
    188 AcpiDbExecuteTest (
    189     char                    *TypeArg)
    190 {
    191     UINT32                  Temp;
    192 
    193 
    194     AcpiUtStrupr (TypeArg);
    195     Temp = AcpiDbMatchArgument (TypeArg, AcpiDbTestTypes);
    196     if (Temp == ACPI_TYPE_NOT_FOUND)
    197     {
    198         AcpiOsPrintf ("Invalid or unsupported argument\n");
    199         return;
    200     }
    201 
    202     switch (Temp)
    203     {
    204     case CMD_TEST_OBJECTS:
    205 
    206         AcpiDbTestAllObjects ();
    207         break;
    208 
    209     case CMD_TEST_PREDEFINED:
    210 
    211         AcpiDbEvaluateAllPredefinedNames (NULL);
    212         break;
    213 
    214     default:
    215         break;
    216     }
    217 }
    218 
    219 
    220 /*******************************************************************************
    221  *
    222  * FUNCTION:    AcpiDbTestAllObjects
    223  *
    224  * PARAMETERS:  None
    225  *
    226  * RETURN:      None
    227  *
    228  * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
    229  *              namespace by reading/writing/comparing all data objects such
    230  *              as integers, strings, buffers, fields, buffer fields, etc.
    231  *
    232  ******************************************************************************/
    233 
    234 static void
    235 AcpiDbTestAllObjects (
    236     void)
    237 {
    238     ACPI_STATUS             Status;
    239 
    240 
    241     /* Install the debugger read-object control method if necessary */
    242 
    243     if (!ReadHandle)
    244     {
    245         Status = AcpiInstallMethod (ReadMethodCode);
    246         if (ACPI_FAILURE (Status))
    247         {
    248             AcpiOsPrintf ("%s, Could not install debugger read method\n",
    249                 AcpiFormatException (Status));
    250             return;
    251         }
    252 
    253         Status = AcpiGetHandle (NULL, ACPI_DB_READ_METHOD, &ReadHandle);
    254         if (ACPI_FAILURE (Status))
    255         {
    256             AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
    257                 ACPI_DB_READ_METHOD);
    258             return;
    259         }
    260     }
    261 
    262     /* Install the debugger write-object control method if necessary */
    263 
    264     if (!WriteHandle)
    265     {
    266         Status = AcpiInstallMethod (WriteMethodCode);
    267         if (ACPI_FAILURE (Status))
    268         {
    269             AcpiOsPrintf ("%s, Could not install debugger write method\n",
    270                 AcpiFormatException (Status));
    271             return;
    272         }
    273 
    274         Status = AcpiGetHandle (NULL, ACPI_DB_WRITE_METHOD, &WriteHandle);
    275         if (ACPI_FAILURE (Status))
    276         {
    277             AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
    278                 ACPI_DB_WRITE_METHOD);
    279             return;
    280         }
    281     }
    282 
    283     /* Walk the entire namespace, testing each supported named data object */
    284 
    285     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    286                 ACPI_UINT32_MAX, AcpiDbTestOneObject, NULL, NULL, NULL);
    287 }
    288 
    289 
    290 /*******************************************************************************
    291  *
    292  * FUNCTION:    AcpiDbTestOneObject
    293  *
    294  * PARAMETERS:  ACPI_WALK_CALLBACK
    295  *
    296  * RETURN:      Status
    297  *
    298  * DESCRIPTION: Test one namespace object. Supported types are Integer,
    299  *              String, Buffer, BufferField, and FieldUnit. All other object
    300  *              types are simply ignored.
    301  *
    302  *              Note: Support for Packages is not implemented.
    303  *
    304  ******************************************************************************/
    305 
    306 static ACPI_STATUS
    307 AcpiDbTestOneObject (
    308     ACPI_HANDLE             ObjHandle,
    309     UINT32                  NestingLevel,
    310     void                    *Context,
    311     void                    **ReturnValue)
    312 {
    313     ACPI_NAMESPACE_NODE     *Node;
    314     ACPI_OPERAND_OBJECT     *ObjDesc;
    315     ACPI_OPERAND_OBJECT     *RegionObj;
    316     ACPI_OBJECT_TYPE        LocalType;
    317     UINT32                  BitLength = 0;
    318     UINT32                  ByteLength = 0;
    319     ACPI_STATUS             Status = AE_OK;
    320 
    321 
    322     Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
    323     ObjDesc = Node->Object;
    324 
    325     /*
    326      * For the supported types, get the actual bit length or
    327      * byte length. Map the type to one of Integer/String/Buffer.
    328      */
    329     switch (Node->Type)
    330     {
    331     case ACPI_TYPE_INTEGER:
    332 
    333         /* Integer width is either 32 or 64 */
    334 
    335         LocalType = ACPI_TYPE_INTEGER;
    336         BitLength = AcpiGbl_IntegerBitWidth;
    337         break;
    338 
    339     case ACPI_TYPE_STRING:
    340 
    341         LocalType = ACPI_TYPE_STRING;
    342         ByteLength = ObjDesc->String.Length;
    343         break;
    344 
    345     case ACPI_TYPE_BUFFER:
    346 
    347         LocalType = ACPI_TYPE_BUFFER;
    348         ByteLength = ObjDesc->Buffer.Length;
    349         BitLength = ByteLength * 8;
    350         break;
    351 
    352     case ACPI_TYPE_FIELD_UNIT:
    353     case ACPI_TYPE_BUFFER_FIELD:
    354     case ACPI_TYPE_LOCAL_REGION_FIELD:
    355     case ACPI_TYPE_LOCAL_INDEX_FIELD:
    356     case ACPI_TYPE_LOCAL_BANK_FIELD:
    357 
    358         LocalType = ACPI_TYPE_INTEGER;
    359         if (ObjDesc)
    360         {
    361             /*
    362              * Returned object will be a Buffer if the field length
    363              * is larger than the size of an Integer (32 or 64 bits
    364              * depending on the DSDT version).
    365              */
    366             BitLength = ObjDesc->CommonField.BitLength;
    367             ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
    368             if (BitLength > AcpiGbl_IntegerBitWidth)
    369             {
    370                 LocalType = ACPI_TYPE_BUFFER;
    371             }
    372         }
    373         break;
    374 
    375     default:
    376 
    377         /* Ignore all other types */
    378 
    379         return (AE_OK);
    380     }
    381 
    382     /* Emit the common prefix: Type:Name */
    383 
    384     AcpiOsPrintf ("%14s: %4.4s",
    385         AcpiUtGetTypeName (Node->Type), Node->Name.Ascii);
    386     if (!ObjDesc)
    387     {
    388         AcpiOsPrintf (" Ignoring, no attached object\n");
    389         return (AE_OK);
    390     }
    391 
    392     /*
    393      * Check for unsupported region types. Note: AcpiExec simulates
    394      * access to SystemMemory, SystemIO, PCI_Config, and EC.
    395      */
    396     switch (Node->Type)
    397     {
    398     case ACPI_TYPE_LOCAL_REGION_FIELD:
    399 
    400         RegionObj = ObjDesc->Field.RegionObj;
    401         switch (RegionObj->Region.SpaceId)
    402         {
    403         case ACPI_ADR_SPACE_SYSTEM_MEMORY:
    404         case ACPI_ADR_SPACE_SYSTEM_IO:
    405         case ACPI_ADR_SPACE_PCI_CONFIG:
    406         case ACPI_ADR_SPACE_EC:
    407 
    408             break;
    409 
    410         default:
    411 
    412             AcpiOsPrintf ("      %s space is not supported [%4.4s]\n",
    413                 AcpiUtGetRegionName (RegionObj->Region.SpaceId),
    414                 RegionObj->Region.Node->Name.Ascii);
    415             return (AE_OK);
    416         }
    417         break;
    418 
    419     default:
    420         break;
    421     }
    422 
    423     /* At this point, we have resolved the object to one of the major types */
    424 
    425     switch (LocalType)
    426     {
    427     case ACPI_TYPE_INTEGER:
    428 
    429         Status = AcpiDbTestIntegerType (Node, BitLength);
    430         break;
    431 
    432     case ACPI_TYPE_STRING:
    433 
    434         Status = AcpiDbTestStringType (Node, ByteLength);
    435         break;
    436 
    437     case ACPI_TYPE_BUFFER:
    438 
    439         Status = AcpiDbTestBufferType (Node, BitLength);
    440         break;
    441 
    442     default:
    443 
    444         AcpiOsPrintf (" Ignoring, type not implemented (%2.2X)",
    445             LocalType);
    446         break;
    447     }
    448 
    449     switch (Node->Type)
    450     {
    451     case ACPI_TYPE_LOCAL_REGION_FIELD:
    452 
    453         RegionObj = ObjDesc->Field.RegionObj;
    454         AcpiOsPrintf (" (%s)",
    455             AcpiUtGetRegionName (RegionObj->Region.SpaceId));
    456         break;
    457 
    458     default:
    459         break;
    460     }
    461 
    462     AcpiOsPrintf ("\n");
    463     return (Status);
    464 }
    465 
    466 
    467 /*******************************************************************************
    468  *
    469  * FUNCTION:    AcpiDbTestIntegerType
    470  *
    471  * PARAMETERS:  Node                - Parent NS node for the object
    472  *              BitLength           - Actual length of the object. Used for
    473  *                                    support of arbitrary length FieldUnit
    474  *                                    and BufferField objects.
    475  *
    476  * RETURN:      Status
    477  *
    478  * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
    479  *              write/read/compare of an arbitrary new value, then performs
    480  *              a write/read/compare of the original value.
    481  *
    482  ******************************************************************************/
    483 
    484 static ACPI_STATUS
    485 AcpiDbTestIntegerType (
    486     ACPI_NAMESPACE_NODE     *Node,
    487     UINT32                  BitLength)
    488 {
    489     ACPI_OBJECT             *Temp1 = NULL;
    490     ACPI_OBJECT             *Temp2 = NULL;
    491     ACPI_OBJECT             *Temp3 = NULL;
    492     ACPI_OBJECT             WriteValue;
    493     UINT64                  ValueToWrite;
    494     ACPI_STATUS             Status;
    495 
    496 
    497     if (BitLength > 64)
    498     {
    499         AcpiOsPrintf (" Invalid length for an Integer: %u", BitLength);
    500         return (AE_OK);
    501     }
    502 
    503     /* Read the original value */
    504 
    505     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp1);
    506     if (ACPI_FAILURE (Status))
    507     {
    508         return (Status);
    509     }
    510 
    511     AcpiOsPrintf (" (%4.4X/%3.3X) %8.8X%8.8X",
    512         BitLength, ACPI_ROUND_BITS_UP_TO_BYTES (BitLength),
    513         ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
    514 
    515     ValueToWrite = ACPI_UINT64_MAX >> (64 - BitLength);
    516     if (Temp1->Integer.Value == ValueToWrite)
    517     {
    518         ValueToWrite = 0;
    519     }
    520 
    521     /* Write a new value */
    522 
    523     WriteValue.Type = ACPI_TYPE_INTEGER;
    524     WriteValue.Integer.Value = ValueToWrite;
    525     Status = AcpiDbWriteToObject (Node, &WriteValue);
    526     if (ACPI_FAILURE (Status))
    527     {
    528         goto Exit;
    529     }
    530 
    531     /* Ensure that we can read back the new value */
    532 
    533     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp2);
    534     if (ACPI_FAILURE (Status))
    535     {
    536         goto Exit;
    537     }
    538 
    539     if (Temp2->Integer.Value != ValueToWrite)
    540     {
    541         AcpiOsPrintf (" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
    542             ACPI_FORMAT_UINT64 (Temp2->Integer.Value),
    543             ACPI_FORMAT_UINT64 (ValueToWrite));
    544     }
    545 
    546     /* Write back the original value */
    547 
    548     WriteValue.Integer.Value = Temp1->Integer.Value;
    549     Status = AcpiDbWriteToObject (Node, &WriteValue);
    550     if (ACPI_FAILURE (Status))
    551     {
    552         goto Exit;
    553     }
    554 
    555     /* Ensure that we can read back the original value */
    556 
    557     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp3);
    558     if (ACPI_FAILURE (Status))
    559     {
    560         goto Exit;
    561     }
    562 
    563     if (Temp3->Integer.Value != Temp1->Integer.Value)
    564     {
    565         AcpiOsPrintf (" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
    566             ACPI_FORMAT_UINT64 (Temp3->Integer.Value),
    567             ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
    568     }
    569 
    570 Exit:
    571     if (Temp1) {AcpiOsFree (Temp1);}
    572     if (Temp2) {AcpiOsFree (Temp2);}
    573     if (Temp3) {AcpiOsFree (Temp3);}
    574     return (AE_OK);
    575 }
    576 
    577 
    578 /*******************************************************************************
    579  *
    580  * FUNCTION:    AcpiDbTestBufferType
    581  *
    582  * PARAMETERS:  Node                - Parent NS node for the object
    583  *              BitLength           - Actual length of the object.
    584  *
    585  * RETURN:      Status
    586  *
    587  * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
    588  *              write/read/compare of an arbitrary new value, then performs
    589  *              a write/read/compare of the original value.
    590  *
    591  ******************************************************************************/
    592 
    593 static ACPI_STATUS
    594 AcpiDbTestBufferType (
    595     ACPI_NAMESPACE_NODE     *Node,
    596     UINT32                  BitLength)
    597 {
    598     ACPI_OBJECT             *Temp1 = NULL;
    599     ACPI_OBJECT             *Temp2 = NULL;
    600     ACPI_OBJECT             *Temp3 = NULL;
    601     UINT8                   *Buffer;
    602     ACPI_OBJECT             WriteValue;
    603     ACPI_STATUS             Status;
    604     UINT32                  ByteLength;
    605     UINT32                  i;
    606     UINT8                   ExtraBits;
    607 
    608 
    609     ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
    610     if (ByteLength == 0)
    611     {
    612         AcpiOsPrintf (" Ignoring zero length buffer");
    613         return (AE_OK);
    614     }
    615 
    616     /* Allocate a local buffer */
    617 
    618     Buffer = ACPI_ALLOCATE_ZEROED (ByteLength);
    619     if (!Buffer)
    620     {
    621         return (AE_NO_MEMORY);
    622     }
    623 
    624     /* Read the original value */
    625 
    626     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp1);
    627     if (ACPI_FAILURE (Status))
    628     {
    629         goto Exit;
    630     }
    631 
    632     /* Emit a few bytes of the buffer */
    633 
    634     AcpiOsPrintf (" (%4.4X/%3.3X)", BitLength, Temp1->Buffer.Length);
    635     for (i = 0; ((i < 4) && (i < ByteLength)); i++)
    636     {
    637         AcpiOsPrintf (" %2.2X", Temp1->Buffer.Pointer[i]);
    638     }
    639     AcpiOsPrintf ("...  ");
    640 
    641     /*
    642      * Write a new value.
    643      *
    644      * Handle possible extra bits at the end of the buffer. Can
    645      * happen for FieldUnits larger than an integer, but the bit
    646      * count is not an integral number of bytes. Zero out the
    647      * unused bits.
    648      */
    649     ACPI_MEMSET (Buffer, BUFFER_FILL_VALUE, ByteLength);
    650     ExtraBits = BitLength % 8;
    651     if (ExtraBits)
    652     {
    653         Buffer [ByteLength - 1] = ACPI_MASK_BITS_ABOVE (ExtraBits);
    654     }
    655 
    656     WriteValue.Type = ACPI_TYPE_BUFFER;
    657     WriteValue.Buffer.Length = ByteLength;
    658     WriteValue.Buffer.Pointer = Buffer;
    659 
    660     Status = AcpiDbWriteToObject (Node, &WriteValue);
    661     if (ACPI_FAILURE (Status))
    662     {
    663         goto Exit;
    664     }
    665 
    666     /* Ensure that we can read back the new value */
    667 
    668     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp2);
    669     if (ACPI_FAILURE (Status))
    670     {
    671         goto Exit;
    672     }
    673 
    674     if (ACPI_MEMCMP (Temp2->Buffer.Pointer, Buffer, ByteLength))
    675     {
    676         AcpiOsPrintf (" MISMATCH 2: New buffer value");
    677     }
    678 
    679     /* Write back the original value */
    680 
    681     WriteValue.Buffer.Length = ByteLength;
    682     WriteValue.Buffer.Pointer = Temp1->Buffer.Pointer;
    683 
    684     Status = AcpiDbWriteToObject (Node, &WriteValue);
    685     if (ACPI_FAILURE (Status))
    686     {
    687         goto Exit;
    688     }
    689 
    690     /* Ensure that we can read back the original value */
    691 
    692     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp3);
    693     if (ACPI_FAILURE (Status))
    694     {
    695         goto Exit;
    696     }
    697 
    698     if (ACPI_MEMCMP (Temp1->Buffer.Pointer, Temp3->Buffer.Pointer, ByteLength))
    699     {
    700         AcpiOsPrintf (" MISMATCH 3: While restoring original buffer");
    701     }
    702 
    703 Exit:
    704     ACPI_FREE (Buffer);
    705     if (Temp1) {AcpiOsFree (Temp1);}
    706     if (Temp2) {AcpiOsFree (Temp2);}
    707     if (Temp3) {AcpiOsFree (Temp3);}
    708     return (Status);
    709 }
    710 
    711 
    712 /*******************************************************************************
    713  *
    714  * FUNCTION:    AcpiDbTestStringType
    715  *
    716  * PARAMETERS:  Node                - Parent NS node for the object
    717  *              ByteLength          - Actual length of the object.
    718  *
    719  * RETURN:      Status
    720  *
    721  * DESCRIPTION: Test read/write for an String-valued object. Performs a
    722  *              write/read/compare of an arbitrary new value, then performs
    723  *              a write/read/compare of the original value.
    724  *
    725  ******************************************************************************/
    726 
    727 static ACPI_STATUS
    728 AcpiDbTestStringType (
    729     ACPI_NAMESPACE_NODE     *Node,
    730     UINT32                  ByteLength)
    731 {
    732     ACPI_OBJECT             *Temp1 = NULL;
    733     ACPI_OBJECT             *Temp2 = NULL;
    734     ACPI_OBJECT             *Temp3 = NULL;
    735     char                    *ValueToWrite = "Test String from AML Debugger";
    736     ACPI_OBJECT             WriteValue;
    737     ACPI_STATUS             Status;
    738 
    739 
    740     /* Read the original value */
    741 
    742     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp1);
    743     if (ACPI_FAILURE (Status))
    744     {
    745         return (Status);
    746     }
    747 
    748     AcpiOsPrintf (" (%4.4X/%3.3X) \"%s\"", (Temp1->String.Length * 8),
    749         Temp1->String.Length, Temp1->String.Pointer);
    750 
    751     /* Write a new value */
    752 
    753     WriteValue.Type = ACPI_TYPE_STRING;
    754     WriteValue.String.Length = ACPI_STRLEN (ValueToWrite);
    755     WriteValue.String.Pointer = ValueToWrite;
    756 
    757     Status = AcpiDbWriteToObject (Node, &WriteValue);
    758     if (ACPI_FAILURE (Status))
    759     {
    760         goto Exit;
    761     }
    762 
    763     /* Ensure that we can read back the new value */
    764 
    765     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp2);
    766     if (ACPI_FAILURE (Status))
    767     {
    768         goto Exit;
    769     }
    770 
    771     if (ACPI_STRCMP (Temp2->String.Pointer, ValueToWrite))
    772     {
    773         AcpiOsPrintf (" MISMATCH 2: %s, expecting %s",
    774             Temp2->String.Pointer, ValueToWrite);
    775     }
    776 
    777     /* Write back the original value */
    778 
    779     WriteValue.String.Length = ACPI_STRLEN (Temp1->String.Pointer);
    780     WriteValue.String.Pointer = Temp1->String.Pointer;
    781 
    782     Status = AcpiDbWriteToObject (Node, &WriteValue);
    783     if (ACPI_FAILURE (Status))
    784     {
    785         goto Exit;
    786     }
    787 
    788     /* Ensure that we can read back the original value */
    789 
    790     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp3);
    791     if (ACPI_FAILURE (Status))
    792     {
    793         goto Exit;
    794     }
    795 
    796     if (ACPI_STRCMP (Temp1->String.Pointer, Temp3->String.Pointer))
    797     {
    798         AcpiOsPrintf (" MISMATCH 3: %s, expecting %s",
    799             Temp3->String.Pointer, Temp1->String.Pointer);
    800     }
    801 
    802 Exit:
    803     if (Temp1) {AcpiOsFree (Temp1);}
    804     if (Temp2) {AcpiOsFree (Temp2);}
    805     if (Temp3) {AcpiOsFree (Temp3);}
    806     return (Status);
    807 }
    808 
    809 
    810 /*******************************************************************************
    811  *
    812  * FUNCTION:    AcpiDbReadFromObject
    813  *
    814  * PARAMETERS:  Node                - Parent NS node for the object
    815  *              ExpectedType        - Object type expected from the read
    816  *              Value               - Where the value read is returned
    817  *
    818  * RETURN:      Status
    819  *
    820  * DESCRIPTION: Performs a read from the specified object by invoking the
    821  *              special debugger control method that reads the object. Thus,
    822  *              the AML interpreter is doing all of the work, increasing the
    823  *              validity of the test.
    824  *
    825  ******************************************************************************/
    826 
    827 static ACPI_STATUS
    828 AcpiDbReadFromObject (
    829     ACPI_NAMESPACE_NODE     *Node,
    830     ACPI_OBJECT_TYPE        ExpectedType,
    831     ACPI_OBJECT             **Value)
    832 {
    833     ACPI_OBJECT             *RetValue;
    834     ACPI_OBJECT_LIST        ParamObjects;
    835     ACPI_OBJECT             Params[2];
    836     ACPI_BUFFER             ReturnObj;
    837     ACPI_STATUS             Status;
    838 
    839 
    840     Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
    841     Params[0].Reference.ActualType = Node->Type;
    842     Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
    843 
    844     ParamObjects.Count = 1;
    845     ParamObjects.Pointer = Params;
    846 
    847     ReturnObj.Length  = ACPI_ALLOCATE_BUFFER;
    848 
    849     AcpiGbl_MethodExecuting = TRUE;
    850     Status = AcpiEvaluateObject (ReadHandle, NULL, &ParamObjects, &ReturnObj);
    851     AcpiGbl_MethodExecuting = FALSE;
    852 
    853     if (ACPI_FAILURE (Status))
    854     {
    855         AcpiOsPrintf ("Could not read from object, %s",
    856             AcpiFormatException (Status));
    857         return (Status);
    858     }
    859 
    860     RetValue = (ACPI_OBJECT *) ReturnObj.Pointer;
    861 
    862     switch (RetValue->Type)
    863     {
    864     case ACPI_TYPE_INTEGER:
    865     case ACPI_TYPE_BUFFER:
    866     case ACPI_TYPE_STRING:
    867         /*
    868          * Did we receive the type we wanted? Most important for the
    869          * Integer/Buffer case (when a field is larger than an Integer,
    870          * it should return a Buffer).
    871          */
    872         if (RetValue->Type != ExpectedType)
    873         {
    874             AcpiOsPrintf (" Type mismatch:  Expected %s, Received %s",
    875                 AcpiUtGetTypeName (ExpectedType),
    876                 AcpiUtGetTypeName (RetValue->Type));
    877 
    878             return (AE_TYPE);
    879         }
    880 
    881         *Value = RetValue;
    882         break;
    883 
    884     default:
    885 
    886         AcpiOsPrintf (" Unsupported return object type, %s",
    887             AcpiUtGetTypeName (RetValue->Type));
    888         AcpiOsFree (ReturnObj.Pointer);
    889 
    890         return (AE_TYPE);
    891     }
    892 
    893     return (Status);
    894 }
    895 
    896 
    897 /*******************************************************************************
    898  *
    899  * FUNCTION:    AcpiDbWriteToObject
    900  *
    901  * PARAMETERS:  Node                - Parent NS node for the object
    902  *              Value               - Value to be written
    903  *
    904  * RETURN:      Status
    905  *
    906  * DESCRIPTION: Performs a write to the specified object by invoking the
    907  *              special debugger control method that writes the object. Thus,
    908  *              the AML interpreter is doing all of the work, increasing the
    909  *              validity of the test.
    910  *
    911  ******************************************************************************/
    912 
    913 static ACPI_STATUS
    914 AcpiDbWriteToObject (
    915     ACPI_NAMESPACE_NODE     *Node,
    916     ACPI_OBJECT             *Value)
    917 {
    918     ACPI_OBJECT_LIST        ParamObjects;
    919     ACPI_OBJECT             Params[2];
    920     ACPI_STATUS             Status;
    921 
    922 
    923     Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
    924     Params[0].Reference.ActualType = Node->Type;
    925     Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
    926 
    927     /* Copy the incoming user parameter */
    928 
    929     ACPI_MEMCPY (&Params[1], Value, sizeof (ACPI_OBJECT));
    930 
    931     ParamObjects.Count = 2;
    932     ParamObjects.Pointer = Params;
    933 
    934     AcpiGbl_MethodExecuting = TRUE;
    935     Status = AcpiEvaluateObject (WriteHandle, NULL, &ParamObjects, NULL);
    936     AcpiGbl_MethodExecuting = FALSE;
    937 
    938     if (ACPI_FAILURE (Status))
    939     {
    940         AcpiOsPrintf ("Could not write to object, %s",
    941             AcpiFormatException (Status));
    942     }
    943 
    944     return (Status);
    945 }
    946 
    947 
    948 /*******************************************************************************
    949  *
    950  * FUNCTION:    AcpiDbEvaluateAllPredefinedNames
    951  *
    952  * PARAMETERS:  CountArg            - Max number of methods to execute
    953  *
    954  * RETURN:      None
    955  *
    956  * DESCRIPTION: Namespace batch execution. Execute predefined names in the
    957  *              namespace, up to the max count, if specified.
    958  *
    959  ******************************************************************************/
    960 
    961 static void
    962 AcpiDbEvaluateAllPredefinedNames (
    963     char                    *CountArg)
    964 {
    965     ACPI_DB_EXECUTE_WALK    Info;
    966 
    967 
    968     Info.Count = 0;
    969     Info.MaxCount = ACPI_UINT32_MAX;
    970 
    971     if (CountArg)
    972     {
    973         Info.MaxCount = ACPI_STRTOUL (CountArg, NULL, 0);
    974     }
    975 
    976     /* Search all nodes in namespace */
    977 
    978     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
    979                 AcpiDbEvaluateOnePredefinedName, NULL, (void *) &Info, NULL);
    980 
    981     AcpiOsPrintf ("Evaluated %u predefined names in the namespace\n", Info.Count);
    982 }
    983 
    984 
    985 /*******************************************************************************
    986  *
    987  * FUNCTION:    AcpiDbEvaluateOnePredefinedName
    988  *
    989  * PARAMETERS:  Callback from WalkNamespace
    990  *
    991  * RETURN:      Status
    992  *
    993  * DESCRIPTION: Batch execution module. Currently only executes predefined
    994  *              ACPI names.
    995  *
    996  ******************************************************************************/
    997 
    998 static ACPI_STATUS
    999 AcpiDbEvaluateOnePredefinedName (
   1000     ACPI_HANDLE             ObjHandle,
   1001     UINT32                  NestingLevel,
   1002     void                    *Context,
   1003     void                    **ReturnValue)
   1004 {
   1005     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
   1006     ACPI_DB_EXECUTE_WALK        *Info = (ACPI_DB_EXECUTE_WALK *) Context;
   1007     char                        *Pathname;
   1008     const ACPI_PREDEFINED_INFO  *Predefined;
   1009     ACPI_DEVICE_INFO            *ObjInfo;
   1010     ACPI_OBJECT_LIST            ParamObjects;
   1011     ACPI_OBJECT                 Params[ACPI_METHOD_NUM_ARGS];
   1012     ACPI_OBJECT                 *ThisParam;
   1013     ACPI_BUFFER                 ReturnObj;
   1014     ACPI_STATUS                 Status;
   1015     UINT16                      ArgTypeList;
   1016     UINT8                       ArgCount;
   1017     UINT8                       ArgType;
   1018     UINT32                      i;
   1019 
   1020 
   1021     /* The name must be a predefined ACPI name */
   1022 
   1023     Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
   1024     if (!Predefined)
   1025     {
   1026         return (AE_OK);
   1027     }
   1028 
   1029     if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
   1030     {
   1031         return (AE_OK);
   1032     }
   1033 
   1034     Pathname = AcpiNsGetExternalPathname (Node);
   1035     if (!Pathname)
   1036     {
   1037         return (AE_OK);
   1038     }
   1039 
   1040     /* Get the object info for number of method parameters */
   1041 
   1042     Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
   1043     if (ACPI_FAILURE (Status))
   1044     {
   1045         ACPI_FREE (Pathname);
   1046         return (Status);
   1047     }
   1048 
   1049     ParamObjects.Count = 0;
   1050     ParamObjects.Pointer = NULL;
   1051 
   1052     if (ObjInfo->Type == ACPI_TYPE_METHOD)
   1053     {
   1054         /* Setup default parameters (with proper types) */
   1055 
   1056         ArgTypeList = Predefined->Info.ArgumentList;
   1057         ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
   1058 
   1059         /*
   1060          * Setup the ACPI-required number of arguments, regardless of what
   1061          * the actual method defines. If there is a difference, then the
   1062          * method is wrong and a warning will be issued during execution.
   1063          */
   1064         ThisParam = Params;
   1065         for (i = 0; i < ArgCount; i++)
   1066         {
   1067             ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
   1068             ThisParam->Type = ArgType;
   1069 
   1070             switch (ArgType)
   1071             {
   1072             case ACPI_TYPE_INTEGER:
   1073 
   1074                 ThisParam->Integer.Value = 1;
   1075                 break;
   1076 
   1077             case ACPI_TYPE_STRING:
   1078 
   1079                 ThisParam->String.Pointer = "This is the default argument string";
   1080                 ThisParam->String.Length = ACPI_STRLEN (ThisParam->String.Pointer);
   1081                 break;
   1082 
   1083             case ACPI_TYPE_BUFFER:
   1084 
   1085                 ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */
   1086                 ThisParam->Buffer.Length = 48;
   1087                 break;
   1088 
   1089              case ACPI_TYPE_PACKAGE:
   1090 
   1091                 ThisParam->Package.Elements = NULL;
   1092                 ThisParam->Package.Count = 0;
   1093                 break;
   1094 
   1095            default:
   1096 
   1097                 AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
   1098                     Pathname, ArgType);
   1099                 break;
   1100             }
   1101 
   1102             ThisParam++;
   1103         }
   1104 
   1105         ParamObjects.Count = ArgCount;
   1106         ParamObjects.Pointer = Params;
   1107     }
   1108 
   1109     ACPI_FREE (ObjInfo);
   1110     ReturnObj.Pointer = NULL;
   1111     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
   1112 
   1113     /* Do the actual method execution */
   1114 
   1115     AcpiGbl_MethodExecuting = TRUE;
   1116 
   1117     Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
   1118 
   1119     AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status));
   1120     AcpiGbl_MethodExecuting = FALSE;
   1121     ACPI_FREE (Pathname);
   1122 
   1123     /* Ignore status from method execution */
   1124 
   1125     Status = AE_OK;
   1126 
   1127     /* Update count, check if we have executed enough methods */
   1128 
   1129     Info->Count++;
   1130     if (Info->Count >= Info->MaxCount)
   1131     {
   1132         Status = AE_CTRL_TERMINATE;
   1133     }
   1134 
   1135     return (Status);
   1136 }
   1137 
   1138 #endif /* ACPI_DEBUGGER */
   1139