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