Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /*******************************************************************************
0003  *
0004  * Module Name: dbtest - Various debug-related tests
0005  *
0006  ******************************************************************************/
0007 
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acdebug.h"
0011 #include "acnamesp.h"
0012 #include "acpredef.h"
0013 #include "acinterp.h"
0014 
0015 #define _COMPONENT          ACPI_CA_DEBUGGER
0016 ACPI_MODULE_NAME("dbtest")
0017 
0018 /* Local prototypes */
0019 static void acpi_db_test_all_objects(void);
0020 
0021 static acpi_status
0022 acpi_db_test_one_object(acpi_handle obj_handle,
0023             u32 nesting_level, void *context, void **return_value);
0024 
0025 static acpi_status
0026 acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length);
0027 
0028 static acpi_status
0029 acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length);
0030 
0031 static acpi_status
0032 acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length);
0033 
0034 static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node);
0035 
0036 static acpi_status
0037 acpi_db_test_field_unit_type(union acpi_operand_object *obj_desc);
0038 
0039 static acpi_status
0040 acpi_db_read_from_object(struct acpi_namespace_node *node,
0041              acpi_object_type expected_type,
0042              union acpi_object **value);
0043 
0044 static acpi_status
0045 acpi_db_write_to_object(struct acpi_namespace_node *node,
0046             union acpi_object *value);
0047 
0048 static void acpi_db_evaluate_all_predefined_names(char *count_arg);
0049 
0050 static acpi_status
0051 acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
0052                      u32 nesting_level,
0053                      void *context, void **return_value);
0054 
0055 /*
0056  * Test subcommands
0057  */
0058 static struct acpi_db_argument_info acpi_db_test_types[] = {
0059     {"OBJECTS"},
0060     {"PREDEFINED"},
0061     {NULL}          /* Must be null terminated */
0062 };
0063 
0064 #define CMD_TEST_OBJECTS        0
0065 #define CMD_TEST_PREDEFINED     1
0066 
0067 #define BUFFER_FILL_VALUE       0xFF
0068 
0069 /*
0070  * Support for the special debugger read/write control methods.
0071  * These methods are installed into the current namespace and are
0072  * used to read and write the various namespace objects. The point
0073  * is to force the AML interpreter do all of the work.
0074  */
0075 #define ACPI_DB_READ_METHOD     "\\_T98"
0076 #define ACPI_DB_WRITE_METHOD    "\\_T99"
0077 
0078 static acpi_handle read_handle = NULL;
0079 static acpi_handle write_handle = NULL;
0080 
0081 /* ASL Definitions of the debugger read/write control methods. AML below. */
0082 
0083 #if 0
0084 definition_block("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
0085 {
0086     method(_T98, 1, not_serialized) {   /* Read */
0087         return (de_ref_of(arg0))
0088     }
0089 }
0090 
0091 definition_block("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
0092 {
0093     method(_T99, 2, not_serialized) {   /* Write */
0094         store(arg1, arg0)
0095     }
0096 }
0097 #endif
0098 
0099 static unsigned char read_method_code[] = {
0100     0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000    "SSDT...." */
0101     0x02, 0xC9, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008    "..Intel." */
0102     0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010    "DEBUG..." */
0103     0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018    "....INTL" */
0104     0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020    "... .._T" */
0105     0x39, 0x38, 0x01, 0xA4, 0x83, 0x68  /* 00000028    "98...h"   */
0106 };
0107 
0108 static unsigned char write_method_code[] = {
0109     0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000    "SSDT...." */
0110     0x02, 0x15, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008    "..Intel." */
0111     0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010    "DEBUG..." */
0112     0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018    "....INTL" */
0113     0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020    "... .._T" */
0114     0x39, 0x39, 0x02, 0x70, 0x69, 0x68  /* 00000028    "99.pih"   */
0115 };
0116 
0117 /*******************************************************************************
0118  *
0119  * FUNCTION:    acpi_db_execute_test
0120  *
0121  * PARAMETERS:  type_arg        - Subcommand
0122  *
0123  * RETURN:      None
0124  *
0125  * DESCRIPTION: Execute various debug tests.
0126  *
0127  * Note: Code is prepared for future expansion of the TEST command.
0128  *
0129  ******************************************************************************/
0130 
0131 void acpi_db_execute_test(char *type_arg)
0132 {
0133     u32 temp;
0134 
0135     acpi_ut_strupr(type_arg);
0136     temp = acpi_db_match_argument(type_arg, acpi_db_test_types);
0137     if (temp == ACPI_TYPE_NOT_FOUND) {
0138         acpi_os_printf("Invalid or unsupported argument\n");
0139         return;
0140     }
0141 
0142     switch (temp) {
0143     case CMD_TEST_OBJECTS:
0144 
0145         acpi_db_test_all_objects();
0146         break;
0147 
0148     case CMD_TEST_PREDEFINED:
0149 
0150         acpi_db_evaluate_all_predefined_names(NULL);
0151         break;
0152 
0153     default:
0154         break;
0155     }
0156 }
0157 
0158 /*******************************************************************************
0159  *
0160  * FUNCTION:    acpi_db_test_all_objects
0161  *
0162  * PARAMETERS:  None
0163  *
0164  * RETURN:      None
0165  *
0166  * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
0167  *              namespace by reading/writing/comparing all data objects such
0168  *              as integers, strings, buffers, fields, buffer fields, etc.
0169  *
0170  ******************************************************************************/
0171 
0172 static void acpi_db_test_all_objects(void)
0173 {
0174     acpi_status status;
0175 
0176     /* Install the debugger read-object control method if necessary */
0177 
0178     if (!read_handle) {
0179         status = acpi_install_method(read_method_code);
0180         if (ACPI_FAILURE(status)) {
0181             acpi_os_printf
0182                 ("%s, Could not install debugger read method\n",
0183                  acpi_format_exception(status));
0184             return;
0185         }
0186 
0187         status =
0188             acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle);
0189         if (ACPI_FAILURE(status)) {
0190             acpi_os_printf
0191                 ("Could not obtain handle for debug method %s\n",
0192                  ACPI_DB_READ_METHOD);
0193             return;
0194         }
0195     }
0196 
0197     /* Install the debugger write-object control method if necessary */
0198 
0199     if (!write_handle) {
0200         status = acpi_install_method(write_method_code);
0201         if (ACPI_FAILURE(status)) {
0202             acpi_os_printf
0203                 ("%s, Could not install debugger write method\n",
0204                  acpi_format_exception(status));
0205             return;
0206         }
0207 
0208         status =
0209             acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle);
0210         if (ACPI_FAILURE(status)) {
0211             acpi_os_printf
0212                 ("Could not obtain handle for debug method %s\n",
0213                  ACPI_DB_WRITE_METHOD);
0214             return;
0215         }
0216     }
0217 
0218     /* Walk the entire namespace, testing each supported named data object */
0219 
0220     (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0221                   ACPI_UINT32_MAX, acpi_db_test_one_object,
0222                   NULL, NULL, NULL);
0223 }
0224 
0225 /*******************************************************************************
0226  *
0227  * FUNCTION:    acpi_db_test_one_object
0228  *
0229  * PARAMETERS:  acpi_walk_callback
0230  *
0231  * RETURN:      Status
0232  *
0233  * DESCRIPTION: Test one namespace object. Supported types are Integer,
0234  *              String, Buffer, Package, buffer_field, and field_unit.
0235  *              All other object types are simply ignored.
0236  *
0237  ******************************************************************************/
0238 
0239 static acpi_status
0240 acpi_db_test_one_object(acpi_handle obj_handle,
0241             u32 nesting_level, void *context, void **return_value)
0242 {
0243     struct acpi_namespace_node *node;
0244     union acpi_operand_object *obj_desc;
0245     acpi_object_type local_type;
0246     u32 bit_length = 0;
0247     u32 byte_length = 0;
0248     acpi_status status = AE_OK;
0249 
0250     node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
0251     obj_desc = node->object;
0252 
0253     /*
0254      * For the supported types, get the actual bit length or
0255      * byte length. Map the type to one of Integer/String/Buffer.
0256      */
0257     switch (node->type) {
0258     case ACPI_TYPE_INTEGER:
0259 
0260         /* Integer width is either 32 or 64 */
0261 
0262         local_type = ACPI_TYPE_INTEGER;
0263         bit_length = acpi_gbl_integer_bit_width;
0264         break;
0265 
0266     case ACPI_TYPE_STRING:
0267 
0268         local_type = ACPI_TYPE_STRING;
0269         byte_length = obj_desc->string.length;
0270         break;
0271 
0272     case ACPI_TYPE_BUFFER:
0273 
0274         local_type = ACPI_TYPE_BUFFER;
0275         byte_length = obj_desc->buffer.length;
0276         bit_length = byte_length * 8;
0277         break;
0278 
0279     case ACPI_TYPE_PACKAGE:
0280 
0281         local_type = ACPI_TYPE_PACKAGE;
0282         break;
0283 
0284     case ACPI_TYPE_FIELD_UNIT:
0285     case ACPI_TYPE_LOCAL_REGION_FIELD:
0286     case ACPI_TYPE_LOCAL_INDEX_FIELD:
0287     case ACPI_TYPE_LOCAL_BANK_FIELD:
0288 
0289         local_type = ACPI_TYPE_FIELD_UNIT;
0290         break;
0291 
0292     case ACPI_TYPE_BUFFER_FIELD:
0293         /*
0294          * The returned object will be a Buffer if the field length
0295          * is larger than the size of an Integer (32 or 64 bits
0296          * depending on the DSDT version).
0297          */
0298         local_type = ACPI_TYPE_INTEGER;
0299         if (obj_desc) {
0300             bit_length = obj_desc->common_field.bit_length;
0301             byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
0302             if (bit_length > acpi_gbl_integer_bit_width) {
0303                 local_type = ACPI_TYPE_BUFFER;
0304             }
0305         }
0306         break;
0307 
0308     default:
0309 
0310         /* Ignore all non-data types - Methods, Devices, Scopes, etc. */
0311 
0312         return (AE_OK);
0313     }
0314 
0315     /* Emit the common prefix: Type:Name */
0316 
0317     acpi_os_printf("%14s: %4.4s",
0318                acpi_ut_get_type_name(node->type), node->name.ascii);
0319 
0320     if (!obj_desc) {
0321         acpi_os_printf(" No attached sub-object, ignoring\n");
0322         return (AE_OK);
0323     }
0324 
0325     /* At this point, we have resolved the object to one of the major types */
0326 
0327     switch (local_type) {
0328     case ACPI_TYPE_INTEGER:
0329 
0330         status = acpi_db_test_integer_type(node, bit_length);
0331         break;
0332 
0333     case ACPI_TYPE_STRING:
0334 
0335         status = acpi_db_test_string_type(node, byte_length);
0336         break;
0337 
0338     case ACPI_TYPE_BUFFER:
0339 
0340         status = acpi_db_test_buffer_type(node, bit_length);
0341         break;
0342 
0343     case ACPI_TYPE_PACKAGE:
0344 
0345         status = acpi_db_test_package_type(node);
0346         break;
0347 
0348     case ACPI_TYPE_FIELD_UNIT:
0349 
0350         status = acpi_db_test_field_unit_type(obj_desc);
0351         break;
0352 
0353     default:
0354 
0355         acpi_os_printf(" Ignoring, type not implemented (%2.2X)",
0356                    local_type);
0357         break;
0358     }
0359 
0360     /* Exit on error, but don't abort the namespace walk */
0361 
0362     if (ACPI_FAILURE(status)) {
0363         status = AE_OK;
0364     }
0365 
0366     acpi_os_printf("\n");
0367     return (status);
0368 }
0369 
0370 /*******************************************************************************
0371  *
0372  * FUNCTION:    acpi_db_test_integer_type
0373  *
0374  * PARAMETERS:  node                - Parent NS node for the object
0375  *              bit_length          - Actual length of the object. Used for
0376  *                                    support of arbitrary length field_unit
0377  *                                    and buffer_field objects.
0378  *
0379  * RETURN:      Status
0380  *
0381  * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
0382  *              write/read/compare of an arbitrary new value, then performs
0383  *              a write/read/compare of the original value.
0384  *
0385  ******************************************************************************/
0386 
0387 static acpi_status
0388 acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length)
0389 {
0390     union acpi_object *temp1 = NULL;
0391     union acpi_object *temp2 = NULL;
0392     union acpi_object *temp3 = NULL;
0393     union acpi_object write_value;
0394     u64 value_to_write;
0395     acpi_status status;
0396 
0397     if (bit_length > 64) {
0398         acpi_os_printf(" Invalid length for an Integer: %u",
0399                    bit_length);
0400         return (AE_OK);
0401     }
0402 
0403     /* Read the original value */
0404 
0405     status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1);
0406     if (ACPI_FAILURE(status)) {
0407         return (status);
0408     }
0409 
0410     acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT " %8.8X%8.8X",
0411                bit_length, ACPI_ROUND_BITS_UP_TO_BYTES(bit_length),
0412                ACPI_FORMAT_UINT64(temp1->integer.value));
0413 
0414     value_to_write = ACPI_UINT64_MAX >> (64 - bit_length);
0415     if (temp1->integer.value == value_to_write) {
0416         value_to_write = 0;
0417     }
0418     /* Write a new value */
0419 
0420     write_value.type = ACPI_TYPE_INTEGER;
0421     write_value.integer.value = value_to_write;
0422     status = acpi_db_write_to_object(node, &write_value);
0423     if (ACPI_FAILURE(status)) {
0424         goto exit;
0425     }
0426 
0427     /* Ensure that we can read back the new value */
0428 
0429     status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp2);
0430     if (ACPI_FAILURE(status)) {
0431         goto exit;
0432     }
0433 
0434     if (temp2->integer.value != value_to_write) {
0435         acpi_os_printf(" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
0436                    ACPI_FORMAT_UINT64(temp2->integer.value),
0437                    ACPI_FORMAT_UINT64(value_to_write));
0438     }
0439 
0440     /* Write back the original value */
0441 
0442     write_value.integer.value = temp1->integer.value;
0443     status = acpi_db_write_to_object(node, &write_value);
0444     if (ACPI_FAILURE(status)) {
0445         goto exit;
0446     }
0447 
0448     /* Ensure that we can read back the original value */
0449 
0450     status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp3);
0451     if (ACPI_FAILURE(status)) {
0452         goto exit;
0453     }
0454 
0455     if (temp3->integer.value != temp1->integer.value) {
0456         acpi_os_printf(" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
0457                    ACPI_FORMAT_UINT64(temp3->integer.value),
0458                    ACPI_FORMAT_UINT64(temp1->integer.value));
0459     }
0460 
0461 exit:
0462     if (temp1) {
0463         acpi_os_free(temp1);
0464     }
0465     if (temp2) {
0466         acpi_os_free(temp2);
0467     }
0468     if (temp3) {
0469         acpi_os_free(temp3);
0470     }
0471     return (AE_OK);
0472 }
0473 
0474 /*******************************************************************************
0475  *
0476  * FUNCTION:    acpi_db_test_buffer_type
0477  *
0478  * PARAMETERS:  node                - Parent NS node for the object
0479  *              bit_length          - Actual length of the object.
0480  *
0481  * RETURN:      Status
0482  *
0483  * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
0484  *              write/read/compare of an arbitrary new value, then performs
0485  *              a write/read/compare of the original value.
0486  *
0487  ******************************************************************************/
0488 
0489 static acpi_status
0490 acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length)
0491 {
0492     union acpi_object *temp1 = NULL;
0493     union acpi_object *temp2 = NULL;
0494     union acpi_object *temp3 = NULL;
0495     u8 *buffer;
0496     union acpi_object write_value;
0497     acpi_status status;
0498     u32 byte_length;
0499     u32 i;
0500     u8 extra_bits;
0501 
0502     byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
0503     if (byte_length == 0) {
0504         acpi_os_printf(" Ignoring zero length buffer");
0505         return (AE_OK);
0506     }
0507 
0508     /* Allocate a local buffer */
0509 
0510     buffer = ACPI_ALLOCATE_ZEROED(byte_length);
0511     if (!buffer) {
0512         return (AE_NO_MEMORY);
0513     }
0514 
0515     /* Read the original value */
0516 
0517     status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1);
0518     if (ACPI_FAILURE(status)) {
0519         goto exit;
0520     }
0521 
0522     /* Emit a few bytes of the buffer */
0523 
0524     acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT, bit_length,
0525                temp1->buffer.length);
0526     for (i = 0; ((i < 8) && (i < byte_length)); i++) {
0527         acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]);
0528     }
0529     acpi_os_printf("... ");
0530 
0531     /*
0532      * Write a new value.
0533      *
0534      * Handle possible extra bits at the end of the buffer. Can
0535      * happen for field_units larger than an integer, but the bit
0536      * count is not an integral number of bytes. Zero out the
0537      * unused bits.
0538      */
0539     memset(buffer, BUFFER_FILL_VALUE, byte_length);
0540     extra_bits = bit_length % 8;
0541     if (extra_bits) {
0542         buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits);
0543     }
0544 
0545     write_value.type = ACPI_TYPE_BUFFER;
0546     write_value.buffer.length = byte_length;
0547     write_value.buffer.pointer = buffer;
0548 
0549     status = acpi_db_write_to_object(node, &write_value);
0550     if (ACPI_FAILURE(status)) {
0551         goto exit;
0552     }
0553 
0554     /* Ensure that we can read back the new value */
0555 
0556     status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp2);
0557     if (ACPI_FAILURE(status)) {
0558         goto exit;
0559     }
0560 
0561     if (memcmp(temp2->buffer.pointer, buffer, byte_length)) {
0562         acpi_os_printf(" MISMATCH 2: New buffer value");
0563     }
0564 
0565     /* Write back the original value */
0566 
0567     write_value.buffer.length = byte_length;
0568     write_value.buffer.pointer = temp1->buffer.pointer;
0569 
0570     status = acpi_db_write_to_object(node, &write_value);
0571     if (ACPI_FAILURE(status)) {
0572         goto exit;
0573     }
0574 
0575     /* Ensure that we can read back the original value */
0576 
0577     status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3);
0578     if (ACPI_FAILURE(status)) {
0579         goto exit;
0580     }
0581 
0582     if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) {
0583         acpi_os_printf(" MISMATCH 3: While restoring original buffer");
0584     }
0585 
0586 exit:
0587     ACPI_FREE(buffer);
0588     if (temp1) {
0589         acpi_os_free(temp1);
0590     }
0591     if (temp2) {
0592         acpi_os_free(temp2);
0593     }
0594     if (temp3) {
0595         acpi_os_free(temp3);
0596     }
0597     return (status);
0598 }
0599 
0600 /*******************************************************************************
0601  *
0602  * FUNCTION:    acpi_db_test_string_type
0603  *
0604  * PARAMETERS:  node                - Parent NS node for the object
0605  *              byte_length         - Actual length of the object.
0606  *
0607  * RETURN:      Status
0608  *
0609  * DESCRIPTION: Test read/write for an String-valued object. Performs a
0610  *              write/read/compare of an arbitrary new value, then performs
0611  *              a write/read/compare of the original value.
0612  *
0613  ******************************************************************************/
0614 
0615 static acpi_status
0616 acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length)
0617 {
0618     union acpi_object *temp1 = NULL;
0619     union acpi_object *temp2 = NULL;
0620     union acpi_object *temp3 = NULL;
0621     char *value_to_write = "Test String from AML Debugger";
0622     union acpi_object write_value;
0623     acpi_status status;
0624 
0625     /* Read the original value */
0626 
0627     status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1);
0628     if (ACPI_FAILURE(status)) {
0629         return (status);
0630     }
0631 
0632     acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT " \"%s\"",
0633                (temp1->string.length * 8), temp1->string.length,
0634                temp1->string.pointer);
0635 
0636     /* Write a new value */
0637 
0638     write_value.type = ACPI_TYPE_STRING;
0639     write_value.string.length = strlen(value_to_write);
0640     write_value.string.pointer = value_to_write;
0641 
0642     status = acpi_db_write_to_object(node, &write_value);
0643     if (ACPI_FAILURE(status)) {
0644         goto exit;
0645     }
0646 
0647     /* Ensure that we can read back the new value */
0648 
0649     status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp2);
0650     if (ACPI_FAILURE(status)) {
0651         goto exit;
0652     }
0653 
0654     if (strcmp(temp2->string.pointer, value_to_write)) {
0655         acpi_os_printf(" MISMATCH 2: %s, expecting %s",
0656                    temp2->string.pointer, value_to_write);
0657     }
0658 
0659     /* Write back the original value */
0660 
0661     write_value.string.length = strlen(temp1->string.pointer);
0662     write_value.string.pointer = temp1->string.pointer;
0663 
0664     status = acpi_db_write_to_object(node, &write_value);
0665     if (ACPI_FAILURE(status)) {
0666         goto exit;
0667     }
0668 
0669     /* Ensure that we can read back the original value */
0670 
0671     status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp3);
0672     if (ACPI_FAILURE(status)) {
0673         goto exit;
0674     }
0675 
0676     if (strcmp(temp1->string.pointer, temp3->string.pointer)) {
0677         acpi_os_printf(" MISMATCH 3: %s, expecting %s",
0678                    temp3->string.pointer, temp1->string.pointer);
0679     }
0680 
0681 exit:
0682     if (temp1) {
0683         acpi_os_free(temp1);
0684     }
0685     if (temp2) {
0686         acpi_os_free(temp2);
0687     }
0688     if (temp3) {
0689         acpi_os_free(temp3);
0690     }
0691     return (status);
0692 }
0693 
0694 /*******************************************************************************
0695  *
0696  * FUNCTION:    acpi_db_test_package_type
0697  *
0698  * PARAMETERS:  node                - Parent NS node for the object
0699  *
0700  * RETURN:      Status
0701  *
0702  * DESCRIPTION: Test read for a Package object.
0703  *
0704  ******************************************************************************/
0705 
0706 static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node)
0707 {
0708     union acpi_object *temp1 = NULL;
0709     acpi_status status;
0710 
0711     /* Read the original value */
0712 
0713     status = acpi_db_read_from_object(node, ACPI_TYPE_PACKAGE, &temp1);
0714     if (ACPI_FAILURE(status)) {
0715         return (status);
0716     }
0717 
0718     acpi_os_printf(" %.2X Elements", temp1->package.count);
0719     acpi_os_free(temp1);
0720     return (status);
0721 }
0722 
0723 /*******************************************************************************
0724  *
0725  * FUNCTION:    acpi_db_test_field_unit_type
0726  *
0727  * PARAMETERS:  obj_desc                - A field unit object
0728  *
0729  * RETURN:      Status
0730  *
0731  * DESCRIPTION: Test read/write on a named field unit.
0732  *
0733  ******************************************************************************/
0734 
0735 static acpi_status
0736 acpi_db_test_field_unit_type(union acpi_operand_object *obj_desc)
0737 {
0738     union acpi_operand_object *region_obj;
0739     u32 bit_length = 0;
0740     u32 byte_length = 0;
0741     acpi_status status = AE_OK;
0742     union acpi_operand_object *ret_buffer_desc;
0743 
0744     /* Supported spaces are memory/io/pci_config */
0745 
0746     region_obj = obj_desc->field.region_obj;
0747     switch (region_obj->region.space_id) {
0748     case ACPI_ADR_SPACE_SYSTEM_MEMORY:
0749     case ACPI_ADR_SPACE_SYSTEM_IO:
0750     case ACPI_ADR_SPACE_PCI_CONFIG:
0751 
0752         /* Need the interpreter to execute */
0753 
0754         acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
0755         acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0756 
0757         /* Exercise read-then-write */
0758 
0759         status =
0760             acpi_ex_read_data_from_field(NULL, obj_desc,
0761                          &ret_buffer_desc);
0762         if (status == AE_OK) {
0763             acpi_ex_write_data_to_field(ret_buffer_desc, obj_desc,
0764                             NULL);
0765             acpi_ut_remove_reference(ret_buffer_desc);
0766         }
0767 
0768         acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0769         acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
0770 
0771         bit_length = obj_desc->common_field.bit_length;
0772         byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
0773 
0774         acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT " [%s]", bit_length,
0775                    byte_length,
0776                    acpi_ut_get_region_name(region_obj->region.
0777                                space_id));
0778         return (status);
0779 
0780     default:
0781 
0782         acpi_os_printf
0783             ("      %s address space is not supported in this command [%4.4s]",
0784              acpi_ut_get_region_name(region_obj->region.space_id),
0785              region_obj->region.node->name.ascii);
0786         return (AE_OK);
0787     }
0788 }
0789 
0790 /*******************************************************************************
0791  *
0792  * FUNCTION:    acpi_db_read_from_object
0793  *
0794  * PARAMETERS:  node                - Parent NS node for the object
0795  *              expected_type       - Object type expected from the read
0796  *              value               - Where the value read is returned
0797  *
0798  * RETURN:      Status
0799  *
0800  * DESCRIPTION: Performs a read from the specified object by invoking the
0801  *              special debugger control method that reads the object. Thus,
0802  *              the AML interpreter is doing all of the work, increasing the
0803  *              validity of the test.
0804  *
0805  ******************************************************************************/
0806 
0807 static acpi_status
0808 acpi_db_read_from_object(struct acpi_namespace_node *node,
0809              acpi_object_type expected_type,
0810              union acpi_object **value)
0811 {
0812     union acpi_object *ret_value;
0813     struct acpi_object_list param_objects;
0814     union acpi_object params[2];
0815     struct acpi_buffer return_obj;
0816     acpi_status status;
0817 
0818     params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
0819     params[0].reference.actual_type = node->type;
0820     params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
0821 
0822     param_objects.count = 1;
0823     param_objects.pointer = params;
0824 
0825     return_obj.length = ACPI_ALLOCATE_BUFFER;
0826 
0827     acpi_gbl_method_executing = TRUE;
0828     status = acpi_evaluate_object(read_handle, NULL,
0829                       &param_objects, &return_obj);
0830 
0831     acpi_gbl_method_executing = FALSE;
0832     if (ACPI_FAILURE(status)) {
0833         acpi_os_printf("Could not read from object, %s",
0834                    acpi_format_exception(status));
0835         return (status);
0836     }
0837 
0838     ret_value = (union acpi_object *)return_obj.pointer;
0839 
0840     switch (ret_value->type) {
0841     case ACPI_TYPE_INTEGER:
0842     case ACPI_TYPE_BUFFER:
0843     case ACPI_TYPE_STRING:
0844     case ACPI_TYPE_PACKAGE:
0845         /*
0846          * Did we receive the type we wanted? Most important for the
0847          * Integer/Buffer case (when a field is larger than an Integer,
0848          * it should return a Buffer).
0849          */
0850         if (ret_value->type != expected_type) {
0851             acpi_os_printf
0852                 (" Type mismatch: Expected %s, Received %s",
0853                  acpi_ut_get_type_name(expected_type),
0854                  acpi_ut_get_type_name(ret_value->type));
0855 
0856             acpi_os_free(return_obj.pointer);
0857             return (AE_TYPE);
0858         }
0859 
0860         *value = ret_value;
0861         break;
0862 
0863     default:
0864 
0865         acpi_os_printf(" Unsupported return object type, %s",
0866                    acpi_ut_get_type_name(ret_value->type));
0867 
0868         acpi_os_free(return_obj.pointer);
0869         return (AE_TYPE);
0870     }
0871 
0872     return (status);
0873 }
0874 
0875 /*******************************************************************************
0876  *
0877  * FUNCTION:    acpi_db_write_to_object
0878  *
0879  * PARAMETERS:  node                - Parent NS node for the object
0880  *              value               - Value to be written
0881  *
0882  * RETURN:      Status
0883  *
0884  * DESCRIPTION: Performs a write to the specified object by invoking the
0885  *              special debugger control method that writes the object. Thus,
0886  *              the AML interpreter is doing all of the work, increasing the
0887  *              validity of the test.
0888  *
0889  ******************************************************************************/
0890 
0891 static acpi_status
0892 acpi_db_write_to_object(struct acpi_namespace_node *node,
0893             union acpi_object *value)
0894 {
0895     struct acpi_object_list param_objects;
0896     union acpi_object params[2];
0897     acpi_status status;
0898 
0899     params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
0900     params[0].reference.actual_type = node->type;
0901     params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
0902 
0903     /* Copy the incoming user parameter */
0904 
0905     memcpy(&params[1], value, sizeof(union acpi_object));
0906 
0907     param_objects.count = 2;
0908     param_objects.pointer = params;
0909 
0910     acpi_gbl_method_executing = TRUE;
0911     status = acpi_evaluate_object(write_handle, NULL, &param_objects, NULL);
0912     acpi_gbl_method_executing = FALSE;
0913 
0914     if (ACPI_FAILURE(status)) {
0915         acpi_os_printf("Could not write to object, %s",
0916                    acpi_format_exception(status));
0917     }
0918 
0919     return (status);
0920 }
0921 
0922 /*******************************************************************************
0923  *
0924  * FUNCTION:    acpi_db_evaluate_all_predefined_names
0925  *
0926  * PARAMETERS:  count_arg           - Max number of methods to execute
0927  *
0928  * RETURN:      None
0929  *
0930  * DESCRIPTION: Namespace batch execution. Execute predefined names in the
0931  *              namespace, up to the max count, if specified.
0932  *
0933  ******************************************************************************/
0934 
0935 static void acpi_db_evaluate_all_predefined_names(char *count_arg)
0936 {
0937     struct acpi_db_execute_walk info;
0938 
0939     info.count = 0;
0940     info.max_count = ACPI_UINT32_MAX;
0941 
0942     if (count_arg) {
0943         info.max_count = strtoul(count_arg, NULL, 0);
0944     }
0945 
0946     /* Search all nodes in namespace */
0947 
0948     (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0949                   ACPI_UINT32_MAX,
0950                   acpi_db_evaluate_one_predefined_name, NULL,
0951                   (void *)&info, NULL);
0952 
0953     acpi_os_printf("Evaluated %u predefined names in the namespace\n",
0954                info.count);
0955 }
0956 
0957 /*******************************************************************************
0958  *
0959  * FUNCTION:    acpi_db_evaluate_one_predefined_name
0960  *
0961  * PARAMETERS:  Callback from walk_namespace
0962  *
0963  * RETURN:      Status
0964  *
0965  * DESCRIPTION: Batch execution module. Currently only executes predefined
0966  *              ACPI names.
0967  *
0968  ******************************************************************************/
0969 
0970 static acpi_status
0971 acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
0972                      u32 nesting_level,
0973                      void *context, void **return_value)
0974 {
0975     struct acpi_namespace_node *node =
0976         (struct acpi_namespace_node *)obj_handle;
0977     struct acpi_db_execute_walk *info =
0978         (struct acpi_db_execute_walk *)context;
0979     char *pathname;
0980     const union acpi_predefined_info *predefined;
0981     struct acpi_device_info *obj_info;
0982     struct acpi_object_list param_objects;
0983     union acpi_object params[ACPI_METHOD_NUM_ARGS];
0984     union acpi_object *this_param;
0985     struct acpi_buffer return_obj;
0986     acpi_status status;
0987     u16 arg_type_list;
0988     u8 arg_count;
0989     u8 arg_type;
0990     u32 i;
0991 
0992     /* The name must be a predefined ACPI name */
0993 
0994     predefined = acpi_ut_match_predefined_method(node->name.ascii);
0995     if (!predefined) {
0996         return (AE_OK);
0997     }
0998 
0999     if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
1000         return (AE_OK);
1001     }
1002 
1003     pathname = acpi_ns_get_normalized_pathname(node, TRUE);
1004     if (!pathname) {
1005         return (AE_OK);
1006     }
1007 
1008     /* Get the object info for number of method parameters */
1009 
1010     status = acpi_get_object_info(obj_handle, &obj_info);
1011     if (ACPI_FAILURE(status)) {
1012         ACPI_FREE(pathname);
1013         return (status);
1014     }
1015 
1016     param_objects.count = 0;
1017     param_objects.pointer = NULL;
1018 
1019     if (obj_info->type == ACPI_TYPE_METHOD) {
1020 
1021         /* Setup default parameters (with proper types) */
1022 
1023         arg_type_list = predefined->info.argument_list;
1024         arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
1025 
1026         /*
1027          * Setup the ACPI-required number of arguments, regardless of what
1028          * the actual method defines. If there is a difference, then the
1029          * method is wrong and a warning will be issued during execution.
1030          */
1031         this_param = params;
1032         for (i = 0; i < arg_count; i++) {
1033             arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
1034             this_param->type = arg_type;
1035 
1036             switch (arg_type) {
1037             case ACPI_TYPE_INTEGER:
1038 
1039                 this_param->integer.value = 1;
1040                 break;
1041 
1042             case ACPI_TYPE_STRING:
1043 
1044                 this_param->string.pointer =
1045                     "This is the default argument string";
1046                 this_param->string.length =
1047                     strlen(this_param->string.pointer);
1048                 break;
1049 
1050             case ACPI_TYPE_BUFFER:
1051 
1052                 this_param->buffer.pointer = (u8 *)params;  /* just a garbage buffer */
1053                 this_param->buffer.length = 48;
1054                 break;
1055 
1056             case ACPI_TYPE_PACKAGE:
1057 
1058                 this_param->package.elements = NULL;
1059                 this_param->package.count = 0;
1060                 break;
1061 
1062             default:
1063 
1064                 acpi_os_printf
1065                     ("%s: Unsupported argument type: %u\n",
1066                      pathname, arg_type);
1067                 break;
1068             }
1069 
1070             this_param++;
1071         }
1072 
1073         param_objects.count = arg_count;
1074         param_objects.pointer = params;
1075     }
1076 
1077     ACPI_FREE(obj_info);
1078     return_obj.pointer = NULL;
1079     return_obj.length = ACPI_ALLOCATE_BUFFER;
1080 
1081     /* Do the actual method execution */
1082 
1083     acpi_gbl_method_executing = TRUE;
1084 
1085     status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
1086 
1087     acpi_os_printf("%-32s returned %s\n",
1088                pathname, acpi_format_exception(status));
1089     acpi_gbl_method_executing = FALSE;
1090     ACPI_FREE(pathname);
1091 
1092     /* Ignore status from method execution */
1093 
1094     status = AE_OK;
1095 
1096     /* Update count, check if we have executed enough methods */
1097 
1098     info->count++;
1099     if (info->count >= info->max_count) {
1100         status = AE_CTRL_TERMINATE;
1101     }
1102 
1103     return (status);
1104 }