1 /*******************************************************************************
   2  *
   3  * Module Name: dbtest - Various debug-related tests
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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         return (Status);
1046     }
1047 
1048     ParamObjects.Count = 0;
1049     ParamObjects.Pointer = NULL;
1050 
1051     if (ObjInfo->Type == ACPI_TYPE_METHOD)
1052     {
1053         /* Setup default parameters (with proper types) */
1054 
1055         ArgTypeList = Predefined->Info.ArgumentList;
1056         ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
1057 
1058         /*
1059          * Setup the ACPI-required number of arguments, regardless of what
1060          * the actual method defines. If there is a difference, then the
1061          * method is wrong and a warning will be issued during execution.
1062          */
1063         ThisParam = Params;
1064         for (i = 0; i < ArgCount; i++)
1065         {
1066             ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
1067             ThisParam->Type = ArgType;
1068 
1069             switch (ArgType)
1070             {
1071             case ACPI_TYPE_INTEGER:
1072 
1073                 ThisParam->Integer.Value = 1;
1074                 break;
1075 
1076             case ACPI_TYPE_STRING:
1077 
1078                 ThisParam->String.Pointer = "This is the default argument string";
1079                 ThisParam->String.Length = ACPI_STRLEN (ThisParam->String.Pointer);
1080                 break;
1081 
1082             case ACPI_TYPE_BUFFER:
1083 
1084                 ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */
1085                 ThisParam->Buffer.Length = 48;
1086                 break;
1087 
1088              case ACPI_TYPE_PACKAGE:
1089 
1090                 ThisParam->Package.Elements = NULL;
1091                 ThisParam->Package.Count = 0;
1092                 break;
1093 
1094            default:
1095 
1096                 AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
1097                     Pathname, ArgType);
1098                 break;
1099             }
1100 
1101             ThisParam++;
1102         }
1103 
1104         ParamObjects.Count = ArgCount;
1105         ParamObjects.Pointer = Params;
1106     }
1107 
1108     ACPI_FREE (ObjInfo);
1109     ReturnObj.Pointer = NULL;
1110     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
1111 
1112     /* Do the actual method execution */
1113 
1114     AcpiGbl_MethodExecuting = TRUE;
1115 
1116     Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
1117 
1118     AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status));
1119     AcpiGbl_MethodExecuting = FALSE;
1120     ACPI_FREE (Pathname);
1121 
1122     /* Ignore status from method execution */
1123 
1124     Status = AE_OK;
1125 
1126     /* Update count, check if we have executed enough methods */
1127 
1128     Info->Count++;
1129     if (Info->Count >= Info->MaxCount)
1130     {
1131         Status = AE_CTRL_TERMINATE;
1132     }
1133 
1134     return (Status);
1135 }
1136 
1137 #endif /* ACPI_DEBUGGER */