linux/drivers/acpi/acpica/dbtest.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/*******************************************************************************
   3 *
   4 * Module Name: dbtest - Various debug-related tests
   5 *
   6 ******************************************************************************/
   7
   8#include <acpi/acpi.h>
   9#include "accommon.h"
  10#include "acdebug.h"
  11#include "acnamesp.h"
  12#include "acpredef.h"
  13
  14#define _COMPONENT          ACPI_CA_DEBUGGER
  15ACPI_MODULE_NAME("dbtest")
  16
  17/* Local prototypes */
  18static void acpi_db_test_all_objects(void);
  19
  20static acpi_status
  21acpi_db_test_one_object(acpi_handle obj_handle,
  22                        u32 nesting_level, void *context, void **return_value);
  23
  24static acpi_status
  25acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length);
  26
  27static acpi_status
  28acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length);
  29
  30static acpi_status
  31acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length);
  32
  33static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node);
  34
  35static acpi_status
  36acpi_db_read_from_object(struct acpi_namespace_node *node,
  37                         acpi_object_type expected_type,
  38                         union acpi_object **value);
  39
  40static acpi_status
  41acpi_db_write_to_object(struct acpi_namespace_node *node,
  42                        union acpi_object *value);
  43
  44static void acpi_db_evaluate_all_predefined_names(char *count_arg);
  45
  46static acpi_status
  47acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
  48                                     u32 nesting_level,
  49                                     void *context, void **return_value);
  50
  51/*
  52 * Test subcommands
  53 */
  54static struct acpi_db_argument_info acpi_db_test_types[] = {
  55        {"OBJECTS"},
  56        {"PREDEFINED"},
  57        {NULL}                  /* Must be null terminated */
  58};
  59
  60#define CMD_TEST_OBJECTS        0
  61#define CMD_TEST_PREDEFINED     1
  62
  63#define BUFFER_FILL_VALUE       0xFF
  64
  65/*
  66 * Support for the special debugger read/write control methods.
  67 * These methods are installed into the current namespace and are
  68 * used to read and write the various namespace objects. The point
  69 * is to force the AML interpreter do all of the work.
  70 */
  71#define ACPI_DB_READ_METHOD     "\\_T98"
  72#define ACPI_DB_WRITE_METHOD    "\\_T99"
  73
  74static acpi_handle read_handle = NULL;
  75static acpi_handle write_handle = NULL;
  76
  77/* ASL Definitions of the debugger read/write control methods */
  78
  79#if 0
  80definition_block("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
  81{
  82        method(_T98, 1, not_serialized) {       /* Read */
  83                return (de_ref_of(arg0))
  84        }
  85}
  86
  87definition_block("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
  88{
  89        method(_T99, 2, not_serialized) {       /* Write */
  90                store(arg1, arg0)
  91        }
  92}
  93#endif
  94
  95static unsigned char read_method_code[] = {
  96        0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000    "SSDT...." */
  97        0x02, 0xC9, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008    "..Intel." */
  98        0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010    "DEBUG..." */
  99        0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018    "....INTL" */
 100        0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020    "... .._T" */
 101        0x39, 0x38, 0x01, 0xA4, 0x83, 0x68      /* 00000028    "98...h"   */
 102};
 103
 104static unsigned char write_method_code[] = {
 105        0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000    "SSDT...." */
 106        0x02, 0x15, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008    "..Intel." */
 107        0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010    "DEBUG..." */
 108        0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018    "....INTL" */
 109        0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020    "... .._T" */
 110        0x39, 0x39, 0x02, 0x70, 0x69, 0x68      /* 00000028    "99.pih"   */
 111};
 112
 113/*******************************************************************************
 114 *
 115 * FUNCTION:    acpi_db_execute_test
 116 *
 117 * PARAMETERS:  type_arg        - Subcommand
 118 *
 119 * RETURN:      None
 120 *
 121 * DESCRIPTION: Execute various debug tests.
 122 *
 123 * Note: Code is prepared for future expansion of the TEST command.
 124 *
 125 ******************************************************************************/
 126
 127void acpi_db_execute_test(char *type_arg)
 128{
 129        u32 temp;
 130
 131        acpi_ut_strupr(type_arg);
 132        temp = acpi_db_match_argument(type_arg, acpi_db_test_types);
 133        if (temp == ACPI_TYPE_NOT_FOUND) {
 134                acpi_os_printf("Invalid or unsupported argument\n");
 135                return;
 136        }
 137
 138        switch (temp) {
 139        case CMD_TEST_OBJECTS:
 140
 141                acpi_db_test_all_objects();
 142                break;
 143
 144        case CMD_TEST_PREDEFINED:
 145
 146                acpi_db_evaluate_all_predefined_names(NULL);
 147                break;
 148
 149        default:
 150                break;
 151        }
 152}
 153
 154/*******************************************************************************
 155 *
 156 * FUNCTION:    acpi_db_test_all_objects
 157 *
 158 * PARAMETERS:  None
 159 *
 160 * RETURN:      None
 161 *
 162 * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
 163 *              namespace by reading/writing/comparing all data objects such
 164 *              as integers, strings, buffers, fields, buffer fields, etc.
 165 *
 166 ******************************************************************************/
 167
 168static void acpi_db_test_all_objects(void)
 169{
 170        acpi_status status;
 171
 172        /* Install the debugger read-object control method if necessary */
 173
 174        if (!read_handle) {
 175                status = acpi_install_method(read_method_code);
 176                if (ACPI_FAILURE(status)) {
 177                        acpi_os_printf
 178                            ("%s, Could not install debugger read method\n",
 179                             acpi_format_exception(status));
 180                        return;
 181                }
 182
 183                status =
 184                    acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle);
 185                if (ACPI_FAILURE(status)) {
 186                        acpi_os_printf
 187                            ("Could not obtain handle for debug method %s\n",
 188                             ACPI_DB_READ_METHOD);
 189                        return;
 190                }
 191        }
 192
 193        /* Install the debugger write-object control method if necessary */
 194
 195        if (!write_handle) {
 196                status = acpi_install_method(write_method_code);
 197                if (ACPI_FAILURE(status)) {
 198                        acpi_os_printf
 199                            ("%s, Could not install debugger write method\n",
 200                             acpi_format_exception(status));
 201                        return;
 202                }
 203
 204                status =
 205                    acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle);
 206                if (ACPI_FAILURE(status)) {
 207                        acpi_os_printf
 208                            ("Could not obtain handle for debug method %s\n",
 209                             ACPI_DB_WRITE_METHOD);
 210                        return;
 211                }
 212        }
 213
 214        /* Walk the entire namespace, testing each supported named data object */
 215
 216        (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 217                                  ACPI_UINT32_MAX, acpi_db_test_one_object,
 218                                  NULL, NULL, NULL);
 219}
 220
 221/*******************************************************************************
 222 *
 223 * FUNCTION:    acpi_db_test_one_object
 224 *
 225 * PARAMETERS:  acpi_walk_callback
 226 *
 227 * RETURN:      Status
 228 *
 229 * DESCRIPTION: Test one namespace object. Supported types are Integer,
 230 *              String, Buffer, buffer_field, and field_unit. All other object
 231 *              types are simply ignored.
 232 *
 233 *              Note: Support for Packages is not implemented.
 234 *
 235 ******************************************************************************/
 236
 237static acpi_status
 238acpi_db_test_one_object(acpi_handle obj_handle,
 239                        u32 nesting_level, void *context, void **return_value)
 240{
 241        struct acpi_namespace_node *node;
 242        union acpi_operand_object *obj_desc;
 243        union acpi_operand_object *region_obj;
 244        acpi_object_type local_type;
 245        u32 bit_length = 0;
 246        u32 byte_length = 0;
 247        acpi_status status = AE_OK;
 248
 249        node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
 250        obj_desc = node->object;
 251
 252        /*
 253         * For the supported types, get the actual bit length or
 254         * byte length. Map the type to one of Integer/String/Buffer.
 255         */
 256        switch (node->type) {
 257        case ACPI_TYPE_INTEGER:
 258
 259                /* Integer width is either 32 or 64 */
 260
 261                local_type = ACPI_TYPE_INTEGER;
 262                bit_length = acpi_gbl_integer_bit_width;
 263                break;
 264
 265        case ACPI_TYPE_STRING:
 266
 267                local_type = ACPI_TYPE_STRING;
 268                byte_length = obj_desc->string.length;
 269                break;
 270
 271        case ACPI_TYPE_BUFFER:
 272
 273                local_type = ACPI_TYPE_BUFFER;
 274                byte_length = obj_desc->buffer.length;
 275                bit_length = byte_length * 8;
 276                break;
 277
 278        case ACPI_TYPE_PACKAGE:
 279
 280                local_type = ACPI_TYPE_PACKAGE;
 281                break;
 282
 283        case ACPI_TYPE_FIELD_UNIT:
 284        case ACPI_TYPE_BUFFER_FIELD:
 285        case ACPI_TYPE_LOCAL_REGION_FIELD:
 286        case ACPI_TYPE_LOCAL_INDEX_FIELD:
 287        case ACPI_TYPE_LOCAL_BANK_FIELD:
 288
 289                local_type = ACPI_TYPE_INTEGER;
 290                if (obj_desc) {
 291                        /*
 292                         * Returned object will be a Buffer if the field length
 293                         * is larger than the size of an Integer (32 or 64 bits
 294                         * depending on the DSDT version).
 295                         */
 296                        bit_length = obj_desc->common_field.bit_length;
 297                        byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
 298                        if (bit_length > acpi_gbl_integer_bit_width) {
 299                                local_type = ACPI_TYPE_BUFFER;
 300                        }
 301                }
 302                break;
 303
 304        default:
 305
 306                /* Ignore all other types */
 307
 308                return (AE_OK);
 309        }
 310
 311        /* Emit the common prefix: Type:Name */
 312
 313        acpi_os_printf("%14s: %4.4s",
 314                       acpi_ut_get_type_name(node->type), node->name.ascii);
 315
 316        if (!obj_desc) {
 317                acpi_os_printf(" Ignoring, no attached object\n");
 318                return (AE_OK);
 319        }
 320
 321        /*
 322         * Check for unsupported region types. Note: acpi_exec simulates
 323         * access to system_memory, system_IO, PCI_Config, and EC.
 324         */
 325        switch (node->type) {
 326        case ACPI_TYPE_LOCAL_REGION_FIELD:
 327
 328                region_obj = obj_desc->field.region_obj;
 329                switch (region_obj->region.space_id) {
 330                case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 331                case ACPI_ADR_SPACE_SYSTEM_IO:
 332                case ACPI_ADR_SPACE_PCI_CONFIG:
 333
 334                        break;
 335
 336                default:
 337
 338                        acpi_os_printf
 339                            ("    %s space is not supported in this command [%4.4s]\n",
 340                             acpi_ut_get_region_name(region_obj->region.
 341                                                     space_id),
 342                             region_obj->region.node->name.ascii);
 343                        return (AE_OK);
 344                }
 345                break;
 346
 347        default:
 348                break;
 349        }
 350
 351        /* At this point, we have resolved the object to one of the major types */
 352
 353        switch (local_type) {
 354        case ACPI_TYPE_INTEGER:
 355
 356                status = acpi_db_test_integer_type(node, bit_length);
 357                break;
 358
 359        case ACPI_TYPE_STRING:
 360
 361                status = acpi_db_test_string_type(node, byte_length);
 362                break;
 363
 364        case ACPI_TYPE_BUFFER:
 365
 366                status = acpi_db_test_buffer_type(node, bit_length);
 367                break;
 368
 369        case ACPI_TYPE_PACKAGE:
 370
 371                status = acpi_db_test_package_type(node);
 372                break;
 373
 374        default:
 375
 376                acpi_os_printf(" Ignoring, type not implemented (%2.2X)",
 377                               local_type);
 378                break;
 379        }
 380
 381        /* Exit on error, but don't abort the namespace walk */
 382
 383        if (ACPI_FAILURE(status)) {
 384                status = AE_OK;
 385                goto exit;
 386        }
 387
 388        switch (node->type) {
 389        case ACPI_TYPE_LOCAL_REGION_FIELD:
 390
 391                region_obj = obj_desc->field.region_obj;
 392                acpi_os_printf(" (%s)",
 393                               acpi_ut_get_region_name(region_obj->region.
 394                                                       space_id));
 395
 396                break;
 397
 398        default:
 399                break;
 400        }
 401
 402exit:
 403        acpi_os_printf("\n");
 404        return (status);
 405}
 406
 407/*******************************************************************************
 408 *
 409 * FUNCTION:    acpi_db_test_integer_type
 410 *
 411 * PARAMETERS:  node                - Parent NS node for the object
 412 *              bit_length          - Actual length of the object. Used for
 413 *                                    support of arbitrary length field_unit
 414 *                                    and buffer_field objects.
 415 *
 416 * RETURN:      Status
 417 *
 418 * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
 419 *              write/read/compare of an arbitrary new value, then performs
 420 *              a write/read/compare of the original value.
 421 *
 422 ******************************************************************************/
 423
 424static acpi_status
 425acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length)
 426{
 427        union acpi_object *temp1 = NULL;
 428        union acpi_object *temp2 = NULL;
 429        union acpi_object *temp3 = NULL;
 430        union acpi_object write_value;
 431        u64 value_to_write;
 432        acpi_status status;
 433
 434        if (bit_length > 64) {
 435                acpi_os_printf(" Invalid length for an Integer: %u",
 436                               bit_length);
 437                return (AE_OK);
 438        }
 439
 440        /* Read the original value */
 441
 442        status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1);
 443        if (ACPI_FAILURE(status)) {
 444                return (status);
 445        }
 446
 447        acpi_os_printf(" (%4.4X/%3.3X) %8.8X%8.8X",
 448                       bit_length, ACPI_ROUND_BITS_UP_TO_BYTES(bit_length),
 449                       ACPI_FORMAT_UINT64(temp1->integer.value));
 450
 451        value_to_write = ACPI_UINT64_MAX >> (64 - bit_length);
 452        if (temp1->integer.value == value_to_write) {
 453                value_to_write = 0;
 454        }
 455        /* Write a new value */
 456
 457        write_value.type = ACPI_TYPE_INTEGER;
 458        write_value.integer.value = value_to_write;
 459        status = acpi_db_write_to_object(node, &write_value);
 460        if (ACPI_FAILURE(status)) {
 461                goto exit;
 462        }
 463
 464        /* Ensure that we can read back the new value */
 465
 466        status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp2);
 467        if (ACPI_FAILURE(status)) {
 468                goto exit;
 469        }
 470
 471        if (temp2->integer.value != value_to_write) {
 472                acpi_os_printf(" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
 473                               ACPI_FORMAT_UINT64(temp2->integer.value),
 474                               ACPI_FORMAT_UINT64(value_to_write));
 475        }
 476
 477        /* Write back the original value */
 478
 479        write_value.integer.value = temp1->integer.value;
 480        status = acpi_db_write_to_object(node, &write_value);
 481        if (ACPI_FAILURE(status)) {
 482                goto exit;
 483        }
 484
 485        /* Ensure that we can read back the original value */
 486
 487        status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp3);
 488        if (ACPI_FAILURE(status)) {
 489                goto exit;
 490        }
 491
 492        if (temp3->integer.value != temp1->integer.value) {
 493                acpi_os_printf(" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
 494                               ACPI_FORMAT_UINT64(temp3->integer.value),
 495                               ACPI_FORMAT_UINT64(temp1->integer.value));
 496        }
 497
 498exit:
 499        if (temp1) {
 500                acpi_os_free(temp1);
 501        }
 502        if (temp2) {
 503                acpi_os_free(temp2);
 504        }
 505        if (temp3) {
 506                acpi_os_free(temp3);
 507        }
 508        return (AE_OK);
 509}
 510
 511/*******************************************************************************
 512 *
 513 * FUNCTION:    acpi_db_test_buffer_type
 514 *
 515 * PARAMETERS:  node                - Parent NS node for the object
 516 *              bit_length          - Actual length of the object.
 517 *
 518 * RETURN:      Status
 519 *
 520 * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
 521 *              write/read/compare of an arbitrary new value, then performs
 522 *              a write/read/compare of the original value.
 523 *
 524 ******************************************************************************/
 525
 526static acpi_status
 527acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length)
 528{
 529        union acpi_object *temp1 = NULL;
 530        union acpi_object *temp2 = NULL;
 531        union acpi_object *temp3 = NULL;
 532        u8 *buffer;
 533        union acpi_object write_value;
 534        acpi_status status;
 535        u32 byte_length;
 536        u32 i;
 537        u8 extra_bits;
 538
 539        byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
 540        if (byte_length == 0) {
 541                acpi_os_printf(" Ignoring zero length buffer");
 542                return (AE_OK);
 543        }
 544
 545        /* Allocate a local buffer */
 546
 547        buffer = ACPI_ALLOCATE_ZEROED(byte_length);
 548        if (!buffer) {
 549                return (AE_NO_MEMORY);
 550        }
 551
 552        /* Read the original value */
 553
 554        status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1);
 555        if (ACPI_FAILURE(status)) {
 556                goto exit;
 557        }
 558
 559        /* Emit a few bytes of the buffer */
 560
 561        acpi_os_printf(" (%4.4X/%3.3X)", bit_length, temp1->buffer.length);
 562        for (i = 0; ((i < 4) && (i < byte_length)); i++) {
 563                acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]);
 564        }
 565        acpi_os_printf("... ");
 566
 567        /*
 568         * Write a new value.
 569         *
 570         * Handle possible extra bits at the end of the buffer. Can
 571         * happen for field_units larger than an integer, but the bit
 572         * count is not an integral number of bytes. Zero out the
 573         * unused bits.
 574         */
 575        memset(buffer, BUFFER_FILL_VALUE, byte_length);
 576        extra_bits = bit_length % 8;
 577        if (extra_bits) {
 578                buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits);
 579        }
 580
 581        write_value.type = ACPI_TYPE_BUFFER;
 582        write_value.buffer.length = byte_length;
 583        write_value.buffer.pointer = buffer;
 584
 585        status = acpi_db_write_to_object(node, &write_value);
 586        if (ACPI_FAILURE(status)) {
 587                goto exit;
 588        }
 589
 590        /* Ensure that we can read back the new value */
 591
 592        status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp2);
 593        if (ACPI_FAILURE(status)) {
 594                goto exit;
 595        }
 596
 597        if (memcmp(temp2->buffer.pointer, buffer, byte_length)) {
 598                acpi_os_printf(" MISMATCH 2: New buffer value");
 599        }
 600
 601        /* Write back the original value */
 602
 603        write_value.buffer.length = byte_length;
 604        write_value.buffer.pointer = temp1->buffer.pointer;
 605
 606        status = acpi_db_write_to_object(node, &write_value);
 607        if (ACPI_FAILURE(status)) {
 608                goto exit;
 609        }
 610
 611        /* Ensure that we can read back the original value */
 612
 613        status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3);
 614        if (ACPI_FAILURE(status)) {
 615                goto exit;
 616        }
 617
 618        if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) {
 619                acpi_os_printf(" MISMATCH 3: While restoring original buffer");
 620        }
 621
 622exit:
 623        ACPI_FREE(buffer);
 624        if (temp1) {
 625                acpi_os_free(temp1);
 626        }
 627        if (temp2) {
 628                acpi_os_free(temp2);
 629        }
 630        if (temp3) {
 631                acpi_os_free(temp3);
 632        }
 633        return (status);
 634}
 635
 636/*******************************************************************************
 637 *
 638 * FUNCTION:    acpi_db_test_string_type
 639 *
 640 * PARAMETERS:  node                - Parent NS node for the object
 641 *              byte_length         - Actual length of the object.
 642 *
 643 * RETURN:      Status
 644 *
 645 * DESCRIPTION: Test read/write for an String-valued object. Performs a
 646 *              write/read/compare of an arbitrary new value, then performs
 647 *              a write/read/compare of the original value.
 648 *
 649 ******************************************************************************/
 650
 651static acpi_status
 652acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length)
 653{
 654        union acpi_object *temp1 = NULL;
 655        union acpi_object *temp2 = NULL;
 656        union acpi_object *temp3 = NULL;
 657        char *value_to_write = "Test String from AML Debugger";
 658        union acpi_object write_value;
 659        acpi_status status;
 660
 661        /* Read the original value */
 662
 663        status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1);
 664        if (ACPI_FAILURE(status)) {
 665                return (status);
 666        }
 667
 668        acpi_os_printf(" (%4.4X/%3.3X) \"%s\"", (temp1->string.length * 8),
 669                       temp1->string.length, temp1->string.pointer);
 670
 671        /* Write a new value */
 672
 673        write_value.type = ACPI_TYPE_STRING;
 674        write_value.string.length = strlen(value_to_write);
 675        write_value.string.pointer = value_to_write;
 676
 677        status = acpi_db_write_to_object(node, &write_value);
 678        if (ACPI_FAILURE(status)) {
 679                goto exit;
 680        }
 681
 682        /* Ensure that we can read back the new value */
 683
 684        status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp2);
 685        if (ACPI_FAILURE(status)) {
 686                goto exit;
 687        }
 688
 689        if (strcmp(temp2->string.pointer, value_to_write)) {
 690                acpi_os_printf(" MISMATCH 2: %s, expecting %s",
 691                               temp2->string.pointer, value_to_write);
 692        }
 693
 694        /* Write back the original value */
 695
 696        write_value.string.length = strlen(temp1->string.pointer);
 697        write_value.string.pointer = temp1->string.pointer;
 698
 699        status = acpi_db_write_to_object(node, &write_value);
 700        if (ACPI_FAILURE(status)) {
 701                goto exit;
 702        }
 703
 704        /* Ensure that we can read back the original value */
 705
 706        status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp3);
 707        if (ACPI_FAILURE(status)) {
 708                goto exit;
 709        }
 710
 711        if (strcmp(temp1->string.pointer, temp3->string.pointer)) {
 712                acpi_os_printf(" MISMATCH 3: %s, expecting %s",
 713                               temp3->string.pointer, temp1->string.pointer);
 714        }
 715
 716exit:
 717        if (temp1) {
 718                acpi_os_free(temp1);
 719        }
 720        if (temp2) {
 721                acpi_os_free(temp2);
 722        }
 723        if (temp3) {
 724                acpi_os_free(temp3);
 725        }
 726        return (status);
 727}
 728
 729/*******************************************************************************
 730 *
 731 * FUNCTION:    acpi_db_test_package_type
 732 *
 733 * PARAMETERS:  node                - Parent NS node for the object
 734 *
 735 * RETURN:      Status
 736 *
 737 * DESCRIPTION: Test read for a Package object.
 738 *
 739 ******************************************************************************/
 740
 741static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node)
 742{
 743        union acpi_object *temp1 = NULL;
 744        acpi_status status;
 745
 746        /* Read the original value */
 747
 748        status = acpi_db_read_from_object(node, ACPI_TYPE_PACKAGE, &temp1);
 749        if (ACPI_FAILURE(status)) {
 750                return (status);
 751        }
 752
 753        acpi_os_printf(" %8.8X Elements", temp1->package.count);
 754        acpi_os_free(temp1);
 755        return (status);
 756}
 757
 758/*******************************************************************************
 759 *
 760 * FUNCTION:    acpi_db_read_from_object
 761 *
 762 * PARAMETERS:  node                - Parent NS node for the object
 763 *              expected_type       - Object type expected from the read
 764 *              value               - Where the value read is returned
 765 *
 766 * RETURN:      Status
 767 *
 768 * DESCRIPTION: Performs a read from the specified object by invoking the
 769 *              special debugger control method that reads the object. Thus,
 770 *              the AML interpreter is doing all of the work, increasing the
 771 *              validity of the test.
 772 *
 773 ******************************************************************************/
 774
 775static acpi_status
 776acpi_db_read_from_object(struct acpi_namespace_node *node,
 777                         acpi_object_type expected_type,
 778                         union acpi_object **value)
 779{
 780        union acpi_object *ret_value;
 781        struct acpi_object_list param_objects;
 782        union acpi_object params[2];
 783        struct acpi_buffer return_obj;
 784        acpi_status status;
 785
 786        params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
 787        params[0].reference.actual_type = node->type;
 788        params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
 789
 790        param_objects.count = 1;
 791        param_objects.pointer = params;
 792
 793        return_obj.length = ACPI_ALLOCATE_BUFFER;
 794
 795        acpi_gbl_method_executing = TRUE;
 796        status = acpi_evaluate_object(read_handle, NULL,
 797                                      &param_objects, &return_obj);
 798
 799        acpi_gbl_method_executing = FALSE;
 800        if (ACPI_FAILURE(status)) {
 801                acpi_os_printf("Could not read from object, %s",
 802                               acpi_format_exception(status));
 803                return (status);
 804        }
 805
 806        ret_value = (union acpi_object *)return_obj.pointer;
 807
 808        switch (ret_value->type) {
 809        case ACPI_TYPE_INTEGER:
 810        case ACPI_TYPE_BUFFER:
 811        case ACPI_TYPE_STRING:
 812        case ACPI_TYPE_PACKAGE:
 813                /*
 814                 * Did we receive the type we wanted? Most important for the
 815                 * Integer/Buffer case (when a field is larger than an Integer,
 816                 * it should return a Buffer).
 817                 */
 818                if (ret_value->type != expected_type) {
 819                        acpi_os_printf
 820                            (" Type mismatch: Expected %s, Received %s",
 821                             acpi_ut_get_type_name(expected_type),
 822                             acpi_ut_get_type_name(ret_value->type));
 823
 824                        acpi_os_free(return_obj.pointer);
 825                        return (AE_TYPE);
 826                }
 827
 828                *value = ret_value;
 829                break;
 830
 831        default:
 832
 833                acpi_os_printf(" Unsupported return object type, %s",
 834                               acpi_ut_get_type_name(ret_value->type));
 835
 836                acpi_os_free(return_obj.pointer);
 837                return (AE_TYPE);
 838        }
 839
 840        return (status);
 841}
 842
 843/*******************************************************************************
 844 *
 845 * FUNCTION:    acpi_db_write_to_object
 846 *
 847 * PARAMETERS:  node                - Parent NS node for the object
 848 *              value               - Value to be written
 849 *
 850 * RETURN:      Status
 851 *
 852 * DESCRIPTION: Performs a write to the specified object by invoking the
 853 *              special debugger control method that writes the object. Thus,
 854 *              the AML interpreter is doing all of the work, increasing the
 855 *              validity of the test.
 856 *
 857 ******************************************************************************/
 858
 859static acpi_status
 860acpi_db_write_to_object(struct acpi_namespace_node *node,
 861                        union acpi_object *value)
 862{
 863        struct acpi_object_list param_objects;
 864        union acpi_object params[2];
 865        acpi_status status;
 866
 867        params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
 868        params[0].reference.actual_type = node->type;
 869        params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
 870
 871        /* Copy the incoming user parameter */
 872
 873        memcpy(&params[1], value, sizeof(union acpi_object));
 874
 875        param_objects.count = 2;
 876        param_objects.pointer = params;
 877
 878        acpi_gbl_method_executing = TRUE;
 879        status = acpi_evaluate_object(write_handle, NULL, &param_objects, NULL);
 880        acpi_gbl_method_executing = FALSE;
 881
 882        if (ACPI_FAILURE(status)) {
 883                acpi_os_printf("Could not write to object, %s",
 884                               acpi_format_exception(status));
 885        }
 886
 887        return (status);
 888}
 889
 890/*******************************************************************************
 891 *
 892 * FUNCTION:    acpi_db_evaluate_all_predefined_names
 893 *
 894 * PARAMETERS:  count_arg           - Max number of methods to execute
 895 *
 896 * RETURN:      None
 897 *
 898 * DESCRIPTION: Namespace batch execution. Execute predefined names in the
 899 *              namespace, up to the max count, if specified.
 900 *
 901 ******************************************************************************/
 902
 903static void acpi_db_evaluate_all_predefined_names(char *count_arg)
 904{
 905        struct acpi_db_execute_walk info;
 906
 907        info.count = 0;
 908        info.max_count = ACPI_UINT32_MAX;
 909
 910        if (count_arg) {
 911                info.max_count = strtoul(count_arg, NULL, 0);
 912        }
 913
 914        /* Search all nodes in namespace */
 915
 916        (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 917                                  ACPI_UINT32_MAX,
 918                                  acpi_db_evaluate_one_predefined_name, NULL,
 919                                  (void *)&info, NULL);
 920
 921        acpi_os_printf("Evaluated %u predefined names in the namespace\n",
 922                       info.count);
 923}
 924
 925/*******************************************************************************
 926 *
 927 * FUNCTION:    acpi_db_evaluate_one_predefined_name
 928 *
 929 * PARAMETERS:  Callback from walk_namespace
 930 *
 931 * RETURN:      Status
 932 *
 933 * DESCRIPTION: Batch execution module. Currently only executes predefined
 934 *              ACPI names.
 935 *
 936 ******************************************************************************/
 937
 938static acpi_status
 939acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
 940                                     u32 nesting_level,
 941                                     void *context, void **return_value)
 942{
 943        struct acpi_namespace_node *node =
 944            (struct acpi_namespace_node *)obj_handle;
 945        struct acpi_db_execute_walk *info =
 946            (struct acpi_db_execute_walk *)context;
 947        char *pathname;
 948        const union acpi_predefined_info *predefined;
 949        struct acpi_device_info *obj_info;
 950        struct acpi_object_list param_objects;
 951        union acpi_object params[ACPI_METHOD_NUM_ARGS];
 952        union acpi_object *this_param;
 953        struct acpi_buffer return_obj;
 954        acpi_status status;
 955        u16 arg_type_list;
 956        u8 arg_count;
 957        u8 arg_type;
 958        u32 i;
 959
 960        /* The name must be a predefined ACPI name */
 961
 962        predefined = acpi_ut_match_predefined_method(node->name.ascii);
 963        if (!predefined) {
 964                return (AE_OK);
 965        }
 966
 967        if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
 968                return (AE_OK);
 969        }
 970
 971        pathname = acpi_ns_get_normalized_pathname(node, TRUE);
 972        if (!pathname) {
 973                return (AE_OK);
 974        }
 975
 976        /* Get the object info for number of method parameters */
 977
 978        status = acpi_get_object_info(obj_handle, &obj_info);
 979        if (ACPI_FAILURE(status)) {
 980                ACPI_FREE(pathname);
 981                return (status);
 982        }
 983
 984        param_objects.count = 0;
 985        param_objects.pointer = NULL;
 986
 987        if (obj_info->type == ACPI_TYPE_METHOD) {
 988
 989                /* Setup default parameters (with proper types) */
 990
 991                arg_type_list = predefined->info.argument_list;
 992                arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
 993
 994                /*
 995                 * Setup the ACPI-required number of arguments, regardless of what
 996                 * the actual method defines. If there is a difference, then the
 997                 * method is wrong and a warning will be issued during execution.
 998                 */
 999                this_param = params;
1000                for (i = 0; i < arg_count; i++) {
1001                        arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
1002                        this_param->type = arg_type;
1003
1004                        switch (arg_type) {
1005                        case ACPI_TYPE_INTEGER:
1006
1007                                this_param->integer.value = 1;
1008                                break;
1009
1010                        case ACPI_TYPE_STRING:
1011
1012                                this_param->string.pointer =
1013                                    "This is the default argument string";
1014                                this_param->string.length =
1015                                    strlen(this_param->string.pointer);
1016                                break;
1017
1018                        case ACPI_TYPE_BUFFER:
1019
1020                                this_param->buffer.pointer = (u8 *)params;      /* just a garbage buffer */
1021                                this_param->buffer.length = 48;
1022                                break;
1023
1024                        case ACPI_TYPE_PACKAGE:
1025
1026                                this_param->package.elements = NULL;
1027                                this_param->package.count = 0;
1028                                break;
1029
1030                        default:
1031
1032                                acpi_os_printf
1033                                    ("%s: Unsupported argument type: %u\n",
1034                                     pathname, arg_type);
1035                                break;
1036                        }
1037
1038                        this_param++;
1039                }
1040
1041                param_objects.count = arg_count;
1042                param_objects.pointer = params;
1043        }
1044
1045        ACPI_FREE(obj_info);
1046        return_obj.pointer = NULL;
1047        return_obj.length = ACPI_ALLOCATE_BUFFER;
1048
1049        /* Do the actual method execution */
1050
1051        acpi_gbl_method_executing = TRUE;
1052
1053        status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
1054
1055        acpi_os_printf("%-32s returned %s\n",
1056                       pathname, acpi_format_exception(status));
1057        acpi_gbl_method_executing = FALSE;
1058        ACPI_FREE(pathname);
1059
1060        /* Ignore status from method execution */
1061
1062        status = AE_OK;
1063
1064        /* Update count, check if we have executed enough methods */
1065
1066        info->count++;
1067        if (info->count >= info->max_count) {
1068                status = AE_CTRL_TERMINATE;
1069        }
1070
1071        return (status);
1072}
1073