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