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