Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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