Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /*******************************************************************************
0003  *
0004  * Module Name: dbcmds - Miscellaneous debug commands and output routines
0005  *
0006  ******************************************************************************/
0007 
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acevents.h"
0011 #include "acdebug.h"
0012 #include "acnamesp.h"
0013 #include "acresrc.h"
0014 #include "actables.h"
0015 
0016 #define _COMPONENT          ACPI_CA_DEBUGGER
0017 ACPI_MODULE_NAME("dbcmds")
0018 
0019 /* Local prototypes */
0020 static void
0021 acpi_dm_compare_aml_resources(u8 *aml1_buffer,
0022                   acpi_rsdesc_size aml1_buffer_length,
0023                   u8 *aml2_buffer,
0024                   acpi_rsdesc_size aml2_buffer_length);
0025 
0026 static acpi_status
0027 acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name);
0028 
0029 static acpi_status
0030 acpi_db_resource_callback(struct acpi_resource *resource, void *context);
0031 
0032 static acpi_status
0033 acpi_db_device_resources(acpi_handle obj_handle,
0034              u32 nesting_level, void *context, void **return_value);
0035 
0036 static void acpi_db_do_one_sleep_state(u8 sleep_state);
0037 
0038 static char *acpi_db_trace_method_name = NULL;
0039 
0040 /*******************************************************************************
0041  *
0042  * FUNCTION:    acpi_db_convert_to_node
0043  *
0044  * PARAMETERS:  in_string           - String to convert
0045  *
0046  * RETURN:      Pointer to a NS node
0047  *
0048  * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
0049  *              alphanumeric strings.
0050  *
0051  ******************************************************************************/
0052 
0053 struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string)
0054 {
0055     struct acpi_namespace_node *node;
0056     acpi_size address;
0057 
0058     if ((*in_string >= 0x30) && (*in_string <= 0x39)) {
0059 
0060         /* Numeric argument, convert */
0061 
0062         address = strtoul(in_string, NULL, 16);
0063         node = ACPI_TO_POINTER(address);
0064         if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
0065             acpi_os_printf("Address %p is invalid", node);
0066             return (NULL);
0067         }
0068 
0069         /* Make sure pointer is valid NS node */
0070 
0071         if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
0072             acpi_os_printf
0073                 ("Address %p is not a valid namespace node [%s]\n",
0074                  node, acpi_ut_get_descriptor_name(node));
0075             return (NULL);
0076         }
0077     } else {
0078         /*
0079          * Alpha argument: The parameter is a name string that must be
0080          * resolved to a Namespace object.
0081          */
0082         node = acpi_db_local_ns_lookup(in_string);
0083         if (!node) {
0084             acpi_os_printf
0085                 ("Could not find [%s] in namespace, defaulting to root node\n",
0086                  in_string);
0087             node = acpi_gbl_root_node;
0088         }
0089     }
0090 
0091     return (node);
0092 }
0093 
0094 /*******************************************************************************
0095  *
0096  * FUNCTION:    acpi_db_sleep
0097  *
0098  * PARAMETERS:  object_arg          - Desired sleep state (0-5). NULL means
0099  *                                    invoke all possible sleep states.
0100  *
0101  * RETURN:      Status
0102  *
0103  * DESCRIPTION: Simulate sleep/wake sequences
0104  *
0105  ******************************************************************************/
0106 
0107 acpi_status acpi_db_sleep(char *object_arg)
0108 {
0109     u8 sleep_state;
0110     u32 i;
0111 
0112     ACPI_FUNCTION_TRACE(acpi_db_sleep);
0113 
0114     /* Null input (no arguments) means to invoke all sleep states */
0115 
0116     if (!object_arg) {
0117         acpi_os_printf("Invoking all possible sleep states, 0-%d\n",
0118                    ACPI_S_STATES_MAX);
0119 
0120         for (i = 0; i <= ACPI_S_STATES_MAX; i++) {
0121             acpi_db_do_one_sleep_state((u8)i);
0122         }
0123 
0124         return_ACPI_STATUS(AE_OK);
0125     }
0126 
0127     /* Convert argument to binary and invoke the sleep state */
0128 
0129     sleep_state = (u8)strtoul(object_arg, NULL, 0);
0130     acpi_db_do_one_sleep_state(sleep_state);
0131     return_ACPI_STATUS(AE_OK);
0132 }
0133 
0134 /*******************************************************************************
0135  *
0136  * FUNCTION:    acpi_db_do_one_sleep_state
0137  *
0138  * PARAMETERS:  sleep_state         - Desired sleep state (0-5)
0139  *
0140  * RETURN:      None
0141  *
0142  * DESCRIPTION: Simulate a sleep/wake sequence
0143  *
0144  ******************************************************************************/
0145 
0146 static void acpi_db_do_one_sleep_state(u8 sleep_state)
0147 {
0148     acpi_status status;
0149     u8 sleep_type_a;
0150     u8 sleep_type_b;
0151 
0152     /* Validate parameter */
0153 
0154     if (sleep_state > ACPI_S_STATES_MAX) {
0155         acpi_os_printf("Sleep state %d out of range (%d max)\n",
0156                    sleep_state, ACPI_S_STATES_MAX);
0157         return;
0158     }
0159 
0160     acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n",
0161                sleep_state, acpi_gbl_sleep_state_names[sleep_state]);
0162 
0163     /* Get the values for the sleep type registers (for display only) */
0164 
0165     status =
0166         acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b);
0167     if (ACPI_FAILURE(status)) {
0168         acpi_os_printf("Could not evaluate [%s] method, %s\n",
0169                    acpi_gbl_sleep_state_names[sleep_state],
0170                    acpi_format_exception(status));
0171         return;
0172     }
0173 
0174     acpi_os_printf
0175         ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
0176          sleep_state, sleep_type_a, sleep_type_b);
0177 
0178     /* Invoke the various sleep/wake interfaces */
0179 
0180     acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n",
0181                sleep_state);
0182     status = acpi_enter_sleep_state_prep(sleep_state);
0183     if (ACPI_FAILURE(status)) {
0184         goto error_exit;
0185     }
0186 
0187     acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state);
0188     status = acpi_enter_sleep_state(sleep_state);
0189     if (ACPI_FAILURE(status)) {
0190         goto error_exit;
0191     }
0192 
0193     acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n",
0194                sleep_state);
0195     status = acpi_leave_sleep_state_prep(sleep_state);
0196     if (ACPI_FAILURE(status)) {
0197         goto error_exit;
0198     }
0199 
0200     acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n",
0201                sleep_state);
0202     status = acpi_leave_sleep_state(sleep_state);
0203     if (ACPI_FAILURE(status)) {
0204         goto error_exit;
0205     }
0206 
0207     return;
0208 
0209 error_exit:
0210     ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d",
0211             sleep_state));
0212 }
0213 
0214 /*******************************************************************************
0215  *
0216  * FUNCTION:    acpi_db_display_locks
0217  *
0218  * PARAMETERS:  None
0219  *
0220  * RETURN:      None
0221  *
0222  * DESCRIPTION: Display information about internal mutexes.
0223  *
0224  ******************************************************************************/
0225 
0226 void acpi_db_display_locks(void)
0227 {
0228     u32 i;
0229 
0230     for (i = 0; i < ACPI_MAX_MUTEX; i++) {
0231         acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i),
0232                    acpi_gbl_mutex_info[i].thread_id ==
0233                    ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked");
0234     }
0235 }
0236 
0237 /*******************************************************************************
0238  *
0239  * FUNCTION:    acpi_db_display_table_info
0240  *
0241  * PARAMETERS:  table_arg           - Name of table to be displayed
0242  *
0243  * RETURN:      None
0244  *
0245  * DESCRIPTION: Display information about loaded tables. Current
0246  *              implementation displays all loaded tables.
0247  *
0248  ******************************************************************************/
0249 
0250 void acpi_db_display_table_info(char *table_arg)
0251 {
0252     u32 i;
0253     struct acpi_table_desc *table_desc;
0254     acpi_status status;
0255 
0256     /* Header */
0257 
0258     acpi_os_printf("Idx ID  Status Type                    "
0259                "TableHeader (Sig, Address, Length, Misc)\n");
0260 
0261     /* Walk the entire root table list */
0262 
0263     for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
0264         table_desc = &acpi_gbl_root_table_list.tables[i];
0265 
0266         /* Index and Table ID */
0267 
0268         acpi_os_printf("%3u %.2u ", i, table_desc->owner_id);
0269 
0270         /* Decode the table flags */
0271 
0272         if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) {
0273             acpi_os_printf("NotLoaded ");
0274         } else {
0275             acpi_os_printf(" Loaded ");
0276         }
0277 
0278         switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
0279         case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0280 
0281             acpi_os_printf("External/virtual ");
0282             break;
0283 
0284         case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0285 
0286             acpi_os_printf("Internal/physical ");
0287             break;
0288 
0289         case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0290 
0291             acpi_os_printf("Internal/virtual ");
0292             break;
0293 
0294         default:
0295 
0296             acpi_os_printf("INVALID TYPE    ");
0297             break;
0298         }
0299 
0300         /* Make sure that the table is mapped */
0301 
0302         status = acpi_tb_validate_table(table_desc);
0303         if (ACPI_FAILURE(status)) {
0304             return;
0305         }
0306 
0307         /* Dump the table header */
0308 
0309         if (table_desc->pointer) {
0310             acpi_tb_print_table_header(table_desc->address,
0311                            table_desc->pointer);
0312         } else {
0313             /* If the pointer is null, the table has been unloaded */
0314 
0315             ACPI_INFO(("%4.4s - Table has been unloaded",
0316                    table_desc->signature.ascii));
0317         }
0318     }
0319 }
0320 
0321 /*******************************************************************************
0322  *
0323  * FUNCTION:    acpi_db_unload_acpi_table
0324  *
0325  * PARAMETERS:  object_name         - Namespace pathname for an object that
0326  *                                    is owned by the table to be unloaded
0327  *
0328  * RETURN:      None
0329  *
0330  * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
0331  *              by the table.
0332  *
0333  ******************************************************************************/
0334 
0335 void acpi_db_unload_acpi_table(char *object_name)
0336 {
0337     struct acpi_namespace_node *node;
0338     acpi_status status;
0339 
0340     /* Translate name to an Named object */
0341 
0342     node = acpi_db_convert_to_node(object_name);
0343     if (!node) {
0344         return;
0345     }
0346 
0347     status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node));
0348     if (ACPI_SUCCESS(status)) {
0349         acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n",
0350                    object_name, node);
0351     } else {
0352         acpi_os_printf("%s, while unloading parent table of [%s]\n",
0353                    acpi_format_exception(status), object_name);
0354     }
0355 }
0356 
0357 /*******************************************************************************
0358  *
0359  * FUNCTION:    acpi_db_send_notify
0360  *
0361  * PARAMETERS:  name                - Name of ACPI object where to send notify
0362  *              value               - Value of the notify to send.
0363  *
0364  * RETURN:      None
0365  *
0366  * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
0367  *              named object as an ACPI notify.
0368  *
0369  ******************************************************************************/
0370 
0371 void acpi_db_send_notify(char *name, u32 value)
0372 {
0373     struct acpi_namespace_node *node;
0374     acpi_status status;
0375 
0376     /* Translate name to an Named object */
0377 
0378     node = acpi_db_convert_to_node(name);
0379     if (!node) {
0380         return;
0381     }
0382 
0383     /* Dispatch the notify if legal */
0384 
0385     if (acpi_ev_is_notify_object(node)) {
0386         status = acpi_ev_queue_notify_request(node, value);
0387         if (ACPI_FAILURE(status)) {
0388             acpi_os_printf("Could not queue notify\n");
0389         }
0390     } else {
0391         acpi_os_printf("Named object [%4.4s] Type %s, "
0392                    "must be Device/Thermal/Processor type\n",
0393                    acpi_ut_get_node_name(node),
0394                    acpi_ut_get_type_name(node->type));
0395     }
0396 }
0397 
0398 /*******************************************************************************
0399  *
0400  * FUNCTION:    acpi_db_display_interfaces
0401  *
0402  * PARAMETERS:  action_arg          - Null, "install", or "remove"
0403  *              interface_name_arg  - Name for install/remove options
0404  *
0405  * RETURN:      None
0406  *
0407  * DESCRIPTION: Display or modify the global _OSI interface list
0408  *
0409  ******************************************************************************/
0410 
0411 void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg)
0412 {
0413     struct acpi_interface_info *next_interface;
0414     char *sub_string;
0415     acpi_status status;
0416 
0417     /* If no arguments, just display current interface list */
0418 
0419     if (!action_arg) {
0420         (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex,
0421                         ACPI_WAIT_FOREVER);
0422 
0423         next_interface = acpi_gbl_supported_interfaces;
0424         while (next_interface) {
0425             if (!(next_interface->flags & ACPI_OSI_INVALID)) {
0426                 acpi_os_printf("%s\n", next_interface->name);
0427             }
0428 
0429             next_interface = next_interface->next;
0430         }
0431 
0432         acpi_os_release_mutex(acpi_gbl_osi_mutex);
0433         return;
0434     }
0435 
0436     /* If action_arg exists, so must interface_name_arg */
0437 
0438     if (!interface_name_arg) {
0439         acpi_os_printf("Missing Interface Name argument\n");
0440         return;
0441     }
0442 
0443     /* Uppercase the action for match below */
0444 
0445     acpi_ut_strupr(action_arg);
0446 
0447     /* install - install an interface */
0448 
0449     sub_string = strstr("INSTALL", action_arg);
0450     if (sub_string) {
0451         status = acpi_install_interface(interface_name_arg);
0452         if (ACPI_FAILURE(status)) {
0453             acpi_os_printf("%s, while installing \"%s\"\n",
0454                        acpi_format_exception(status),
0455                        interface_name_arg);
0456         }
0457         return;
0458     }
0459 
0460     /* remove - remove an interface */
0461 
0462     sub_string = strstr("REMOVE", action_arg);
0463     if (sub_string) {
0464         status = acpi_remove_interface(interface_name_arg);
0465         if (ACPI_FAILURE(status)) {
0466             acpi_os_printf("%s, while removing \"%s\"\n",
0467                        acpi_format_exception(status),
0468                        interface_name_arg);
0469         }
0470         return;
0471     }
0472 
0473     /* Invalid action_arg */
0474 
0475     acpi_os_printf("Invalid action argument: %s\n", action_arg);
0476     return;
0477 }
0478 
0479 /*******************************************************************************
0480  *
0481  * FUNCTION:    acpi_db_display_template
0482  *
0483  * PARAMETERS:  buffer_arg          - Buffer name or address
0484  *
0485  * RETURN:      None
0486  *
0487  * DESCRIPTION: Dump a buffer that contains a resource template
0488  *
0489  ******************************************************************************/
0490 
0491 void acpi_db_display_template(char *buffer_arg)
0492 {
0493     struct acpi_namespace_node *node;
0494     acpi_status status;
0495     struct acpi_buffer return_buffer;
0496 
0497     /* Translate buffer_arg to an Named object */
0498 
0499     node = acpi_db_convert_to_node(buffer_arg);
0500     if (!node || (node == acpi_gbl_root_node)) {
0501         acpi_os_printf("Invalid argument: %s\n", buffer_arg);
0502         return;
0503     }
0504 
0505     /* We must have a buffer object */
0506 
0507     if (node->type != ACPI_TYPE_BUFFER) {
0508         acpi_os_printf
0509             ("Not a Buffer object, cannot be a template: %s\n",
0510              buffer_arg);
0511         return;
0512     }
0513 
0514     return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
0515     return_buffer.pointer = acpi_gbl_db_buffer;
0516 
0517     /* Attempt to convert the raw buffer to a resource list */
0518 
0519     status = acpi_rs_create_resource_list(node->object, &return_buffer);
0520 
0521     acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
0522     acpi_dbg_level |= ACPI_LV_RESOURCES;
0523 
0524     if (ACPI_FAILURE(status)) {
0525         acpi_os_printf
0526             ("Could not convert Buffer to a resource list: %s, %s\n",
0527              buffer_arg, acpi_format_exception(status));
0528         goto dump_buffer;
0529     }
0530 
0531     /* Now we can dump the resource list */
0532 
0533     acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
0534                          return_buffer.pointer));
0535 
0536 dump_buffer:
0537     acpi_os_printf("\nRaw data buffer:\n");
0538     acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer,
0539                   node->object->buffer.length,
0540                   DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
0541 
0542     acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
0543     return;
0544 }
0545 
0546 /*******************************************************************************
0547  *
0548  * FUNCTION:    acpi_dm_compare_aml_resources
0549  *
0550  * PARAMETERS:  aml1_buffer         - Contains first resource list
0551  *              aml1_buffer_length  - Length of first resource list
0552  *              aml2_buffer         - Contains second resource list
0553  *              aml2_buffer_length  - Length of second resource list
0554  *
0555  * RETURN:      None
0556  *
0557  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
0558  *              order to isolate a miscompare to an individual resource)
0559  *
0560  ******************************************************************************/
0561 
0562 static void
0563 acpi_dm_compare_aml_resources(u8 *aml1_buffer,
0564                   acpi_rsdesc_size aml1_buffer_length,
0565                   u8 *aml2_buffer,
0566                   acpi_rsdesc_size aml2_buffer_length)
0567 {
0568     u8 *aml1;
0569     u8 *aml2;
0570     u8 *aml1_end;
0571     u8 *aml2_end;
0572     acpi_rsdesc_size aml1_length;
0573     acpi_rsdesc_size aml2_length;
0574     acpi_rsdesc_size offset = 0;
0575     u8 resource_type;
0576     u32 count = 0;
0577     u32 i;
0578 
0579     /* Compare overall buffer sizes (may be different due to size rounding) */
0580 
0581     if (aml1_buffer_length != aml2_buffer_length) {
0582         acpi_os_printf("**** Buffer length mismatch in converted "
0583                    "AML: Original %X, New %X ****\n",
0584                    aml1_buffer_length, aml2_buffer_length);
0585     }
0586 
0587     aml1 = aml1_buffer;
0588     aml2 = aml2_buffer;
0589     aml1_end = aml1_buffer + aml1_buffer_length;
0590     aml2_end = aml2_buffer + aml2_buffer_length;
0591 
0592     /* Walk the descriptor lists, comparing each descriptor */
0593 
0594     while ((aml1 < aml1_end) && (aml2 < aml2_end)) {
0595 
0596         /* Get the lengths of each descriptor */
0597 
0598         aml1_length = acpi_ut_get_descriptor_length(aml1);
0599         aml2_length = acpi_ut_get_descriptor_length(aml2);
0600         resource_type = acpi_ut_get_resource_type(aml1);
0601 
0602         /* Check for descriptor length match */
0603 
0604         if (aml1_length != aml2_length) {
0605             acpi_os_printf
0606                 ("**** Length mismatch in descriptor [%.2X] type %2.2X, "
0607                  "Offset %8.8X Len1 %X, Len2 %X ****\n", count,
0608                  resource_type, offset, aml1_length, aml2_length);
0609         }
0610 
0611         /* Check for descriptor byte match */
0612 
0613         else if (memcmp(aml1, aml2, aml1_length)) {
0614             acpi_os_printf
0615                 ("**** Data mismatch in descriptor [%.2X] type %2.2X, "
0616                  "Offset %8.8X ****\n", count, resource_type,
0617                  offset);
0618 
0619             for (i = 0; i < aml1_length; i++) {
0620                 if (aml1[i] != aml2[i]) {
0621                     acpi_os_printf
0622                         ("Mismatch at byte offset %.2X: is %2.2X, "
0623                          "should be %2.2X\n", i, aml2[i],
0624                          aml1[i]);
0625                 }
0626             }
0627         }
0628 
0629         /* Exit on end_tag descriptor */
0630 
0631         if (resource_type == ACPI_RESOURCE_NAME_END_TAG) {
0632             return;
0633         }
0634 
0635         /* Point to next descriptor in each buffer */
0636 
0637         count++;
0638         offset += aml1_length;
0639         aml1 += aml1_length;
0640         aml2 += aml2_length;
0641     }
0642 }
0643 
0644 /*******************************************************************************
0645  *
0646  * FUNCTION:    acpi_dm_test_resource_conversion
0647  *
0648  * PARAMETERS:  node                - Parent device node
0649  *              name                - resource method name (_CRS)
0650  *
0651  * RETURN:      Status
0652  *
0653  * DESCRIPTION: Compare the original AML with a conversion of the AML to
0654  *              internal resource list, then back to AML.
0655  *
0656  ******************************************************************************/
0657 
0658 static acpi_status
0659 acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name)
0660 {
0661     acpi_status status;
0662     struct acpi_buffer return_buffer;
0663     struct acpi_buffer resource_buffer;
0664     struct acpi_buffer new_aml;
0665     union acpi_object *original_aml;
0666 
0667     acpi_os_printf("Resource Conversion Comparison:\n");
0668 
0669     new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0670     return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0671     resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0672 
0673     /* Get the original _CRS AML resource template */
0674 
0675     status = acpi_evaluate_object(node, name, NULL, &return_buffer);
0676     if (ACPI_FAILURE(status)) {
0677         acpi_os_printf("Could not obtain %s: %s\n",
0678                    name, acpi_format_exception(status));
0679         return (status);
0680     }
0681 
0682     /* Get the AML resource template, converted to internal resource structs */
0683 
0684     status = acpi_get_current_resources(node, &resource_buffer);
0685     if (ACPI_FAILURE(status)) {
0686         acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
0687                    acpi_format_exception(status));
0688         goto exit1;
0689     }
0690 
0691     /* Convert internal resource list to external AML resource template */
0692 
0693     status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml);
0694     if (ACPI_FAILURE(status)) {
0695         acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n",
0696                    acpi_format_exception(status));
0697         goto exit2;
0698     }
0699 
0700     /* Compare original AML to the newly created AML resource list */
0701 
0702     original_aml = return_buffer.pointer;
0703 
0704     acpi_dm_compare_aml_resources(original_aml->buffer.pointer,
0705                       (acpi_rsdesc_size)original_aml->buffer.
0706                       length, new_aml.pointer,
0707                       (acpi_rsdesc_size)new_aml.length);
0708 
0709     /* Cleanup and exit */
0710 
0711     ACPI_FREE(new_aml.pointer);
0712 exit2:
0713     ACPI_FREE(resource_buffer.pointer);
0714 exit1:
0715     ACPI_FREE(return_buffer.pointer);
0716     return (status);
0717 }
0718 
0719 /*******************************************************************************
0720  *
0721  * FUNCTION:    acpi_db_resource_callback
0722  *
0723  * PARAMETERS:  acpi_walk_resource_callback
0724  *
0725  * RETURN:      Status
0726  *
0727  * DESCRIPTION: Simple callback to exercise acpi_walk_resources and
0728  *              acpi_walk_resource_buffer.
0729  *
0730  ******************************************************************************/
0731 
0732 static acpi_status
0733 acpi_db_resource_callback(struct acpi_resource *resource, void *context)
0734 {
0735 
0736     return (AE_OK);
0737 }
0738 
0739 /*******************************************************************************
0740  *
0741  * FUNCTION:    acpi_db_device_resources
0742  *
0743  * PARAMETERS:  acpi_walk_callback
0744  *
0745  * RETURN:      Status
0746  *
0747  * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
0748  *
0749  ******************************************************************************/
0750 
0751 static acpi_status
0752 acpi_db_device_resources(acpi_handle obj_handle,
0753              u32 nesting_level, void *context, void **return_value)
0754 {
0755     struct acpi_namespace_node *node;
0756     struct acpi_namespace_node *prt_node = NULL;
0757     struct acpi_namespace_node *crs_node = NULL;
0758     struct acpi_namespace_node *prs_node = NULL;
0759     struct acpi_namespace_node *aei_node = NULL;
0760     char *parent_path;
0761     struct acpi_buffer return_buffer;
0762     acpi_status status;
0763 
0764     node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
0765     parent_path = acpi_ns_get_normalized_pathname(node, TRUE);
0766     if (!parent_path) {
0767         return (AE_NO_MEMORY);
0768     }
0769 
0770     /* Get handles to the resource methods for this device */
0771 
0772     (void)acpi_get_handle(node, METHOD_NAME__PRT,
0773                   ACPI_CAST_PTR(acpi_handle, &prt_node));
0774     (void)acpi_get_handle(node, METHOD_NAME__CRS,
0775                   ACPI_CAST_PTR(acpi_handle, &crs_node));
0776     (void)acpi_get_handle(node, METHOD_NAME__PRS,
0777                   ACPI_CAST_PTR(acpi_handle, &prs_node));
0778     (void)acpi_get_handle(node, METHOD_NAME__AEI,
0779                   ACPI_CAST_PTR(acpi_handle, &aei_node));
0780 
0781     if (!prt_node && !crs_node && !prs_node && !aei_node) {
0782         goto cleanup;   /* Nothing to do */
0783     }
0784 
0785     acpi_os_printf("\nDevice: %s\n", parent_path);
0786 
0787     /* Prepare for a return object of arbitrary size */
0788 
0789     return_buffer.pointer = acpi_gbl_db_buffer;
0790     return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
0791 
0792     /* _PRT */
0793 
0794     if (prt_node) {
0795         acpi_os_printf("Evaluating _PRT\n");
0796 
0797         status =
0798             acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer);
0799         if (ACPI_FAILURE(status)) {
0800             acpi_os_printf("Could not evaluate _PRT: %s\n",
0801                        acpi_format_exception(status));
0802             goto get_crs;
0803         }
0804 
0805         return_buffer.pointer = acpi_gbl_db_buffer;
0806         return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
0807 
0808         status = acpi_get_irq_routing_table(node, &return_buffer);
0809         if (ACPI_FAILURE(status)) {
0810             acpi_os_printf("GetIrqRoutingTable failed: %s\n",
0811                        acpi_format_exception(status));
0812             goto get_crs;
0813         }
0814 
0815         acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer));
0816     }
0817 
0818     /* _CRS */
0819 
0820 get_crs:
0821     if (crs_node) {
0822         acpi_os_printf("Evaluating _CRS\n");
0823 
0824         return_buffer.pointer = acpi_gbl_db_buffer;
0825         return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
0826 
0827         status =
0828             acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer);
0829         if (ACPI_FAILURE(status)) {
0830             acpi_os_printf("Could not evaluate _CRS: %s\n",
0831                        acpi_format_exception(status));
0832             goto get_prs;
0833         }
0834 
0835         /* This code exercises the acpi_walk_resources interface */
0836 
0837         status = acpi_walk_resources(node, METHOD_NAME__CRS,
0838                          acpi_db_resource_callback, NULL);
0839         if (ACPI_FAILURE(status)) {
0840             acpi_os_printf("AcpiWalkResources failed: %s\n",
0841                        acpi_format_exception(status));
0842             goto get_prs;
0843         }
0844 
0845         /* Get the _CRS resource list (test ALLOCATE buffer) */
0846 
0847         return_buffer.pointer = NULL;
0848         return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0849 
0850         status = acpi_get_current_resources(node, &return_buffer);
0851         if (ACPI_FAILURE(status)) {
0852             acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
0853                        acpi_format_exception(status));
0854             goto get_prs;
0855         }
0856 
0857         /* This code exercises the acpi_walk_resource_buffer interface */
0858 
0859         status = acpi_walk_resource_buffer(&return_buffer,
0860                            acpi_db_resource_callback,
0861                            NULL);
0862         if (ACPI_FAILURE(status)) {
0863             acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n",
0864                        acpi_format_exception(status));
0865             goto end_crs;
0866         }
0867 
0868         /* Dump the _CRS resource list */
0869 
0870         acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
0871                              return_buffer.
0872                              pointer));
0873 
0874         /*
0875          * Perform comparison of original AML to newly created AML. This
0876          * tests both the AML->Resource conversion and the Resource->AML
0877          * conversion.
0878          */
0879         (void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS);
0880 
0881         /* Execute _SRS with the resource list */
0882 
0883         acpi_os_printf("Evaluating _SRS\n");
0884 
0885         status = acpi_set_current_resources(node, &return_buffer);
0886         if (ACPI_FAILURE(status)) {
0887             acpi_os_printf("AcpiSetCurrentResources failed: %s\n",
0888                        acpi_format_exception(status));
0889             goto end_crs;
0890         }
0891 
0892 end_crs:
0893         ACPI_FREE(return_buffer.pointer);
0894     }
0895 
0896     /* _PRS */
0897 
0898 get_prs:
0899     if (prs_node) {
0900         acpi_os_printf("Evaluating _PRS\n");
0901 
0902         return_buffer.pointer = acpi_gbl_db_buffer;
0903         return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
0904 
0905         status =
0906             acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer);
0907         if (ACPI_FAILURE(status)) {
0908             acpi_os_printf("Could not evaluate _PRS: %s\n",
0909                        acpi_format_exception(status));
0910             goto get_aei;
0911         }
0912 
0913         return_buffer.pointer = acpi_gbl_db_buffer;
0914         return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
0915 
0916         status = acpi_get_possible_resources(node, &return_buffer);
0917         if (ACPI_FAILURE(status)) {
0918             acpi_os_printf("AcpiGetPossibleResources failed: %s\n",
0919                        acpi_format_exception(status));
0920             goto get_aei;
0921         }
0922 
0923         acpi_rs_dump_resource_list(ACPI_CAST_PTR
0924                        (struct acpi_resource,
0925                         acpi_gbl_db_buffer));
0926     }
0927 
0928     /* _AEI */
0929 
0930 get_aei:
0931     if (aei_node) {
0932         acpi_os_printf("Evaluating _AEI\n");
0933 
0934         return_buffer.pointer = acpi_gbl_db_buffer;
0935         return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
0936 
0937         status =
0938             acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer);
0939         if (ACPI_FAILURE(status)) {
0940             acpi_os_printf("Could not evaluate _AEI: %s\n",
0941                        acpi_format_exception(status));
0942             goto cleanup;
0943         }
0944 
0945         return_buffer.pointer = acpi_gbl_db_buffer;
0946         return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
0947 
0948         status = acpi_get_event_resources(node, &return_buffer);
0949         if (ACPI_FAILURE(status)) {
0950             acpi_os_printf("AcpiGetEventResources failed: %s\n",
0951                        acpi_format_exception(status));
0952             goto cleanup;
0953         }
0954 
0955         acpi_rs_dump_resource_list(ACPI_CAST_PTR
0956                        (struct acpi_resource,
0957                         acpi_gbl_db_buffer));
0958     }
0959 
0960 cleanup:
0961     ACPI_FREE(parent_path);
0962     return (AE_OK);
0963 }
0964 
0965 /*******************************************************************************
0966  *
0967  * FUNCTION:    acpi_db_display_resources
0968  *
0969  * PARAMETERS:  object_arg          - String object name or object pointer.
0970  *                                    NULL or "*" means "display resources for
0971  *                                    all devices"
0972  *
0973  * RETURN:      None
0974  *
0975  * DESCRIPTION: Display the resource objects associated with a device.
0976  *
0977  ******************************************************************************/
0978 
0979 void acpi_db_display_resources(char *object_arg)
0980 {
0981     struct acpi_namespace_node *node;
0982 
0983     acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
0984     acpi_dbg_level |= ACPI_LV_RESOURCES;
0985 
0986     /* Asterisk means "display resources for all devices" */
0987 
0988     if (!object_arg || (!strcmp(object_arg, "*"))) {
0989         (void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
0990                       ACPI_UINT32_MAX,
0991                       acpi_db_device_resources, NULL, NULL,
0992                       NULL);
0993     } else {
0994         /* Convert string to object pointer */
0995 
0996         node = acpi_db_convert_to_node(object_arg);
0997         if (node) {
0998             if (node->type != ACPI_TYPE_DEVICE) {
0999                 acpi_os_printf
1000                     ("%4.4s: Name is not a device object (%s)\n",
1001                      node->name.ascii,
1002                      acpi_ut_get_type_name(node->type));
1003             } else {
1004                 (void)acpi_db_device_resources(node, 0, NULL,
1005                                    NULL);
1006             }
1007         }
1008     }
1009 
1010     acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
1011 }
1012 
1013 #if (!ACPI_REDUCED_HARDWARE)
1014 /*******************************************************************************
1015  *
1016  * FUNCTION:    acpi_db_generate_gpe
1017  *
1018  * PARAMETERS:  gpe_arg             - Raw GPE number, ascii string
1019  *              block_arg           - GPE block number, ascii string
1020  *                                    0 or 1 for FADT GPE blocks
1021  *
1022  * RETURN:      None
1023  *
1024  * DESCRIPTION: Simulate firing of a GPE
1025  *
1026  ******************************************************************************/
1027 
1028 void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)
1029 {
1030     u32 block_number = 0;
1031     u32 gpe_number;
1032     struct acpi_gpe_event_info *gpe_event_info;
1033 
1034     gpe_number = strtoul(gpe_arg, NULL, 0);
1035 
1036     /*
1037      * If no block arg, or block arg == 0 or 1, use the FADT-defined
1038      * GPE blocks.
1039      */
1040     if (block_arg) {
1041         block_number = strtoul(block_arg, NULL, 0);
1042         if (block_number == 1) {
1043             block_number = 0;
1044         }
1045     }
1046 
1047     gpe_event_info =
1048         acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),
1049                        gpe_number);
1050     if (!gpe_event_info) {
1051         acpi_os_printf("Invalid GPE\n");
1052         return;
1053     }
1054 
1055     (void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);
1056 }
1057 
1058 /*******************************************************************************
1059  *
1060  * FUNCTION:    acpi_db_generate_sci
1061  *
1062  * PARAMETERS:  None
1063  *
1064  * RETURN:      None
1065  *
1066  * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
1067  *
1068  ******************************************************************************/
1069 
1070 void acpi_db_generate_sci(void)
1071 {
1072     acpi_ev_sci_dispatch();
1073 }
1074 
1075 #endif              /* !ACPI_REDUCED_HARDWARE */
1076 
1077 /*******************************************************************************
1078  *
1079  * FUNCTION:    acpi_db_trace
1080  *
1081  * PARAMETERS:  enable_arg          - ENABLE/AML to enable tracer
1082  *                                    DISABLE to disable tracer
1083  *              method_arg          - Method to trace
1084  *              once_arg            - Whether trace once
1085  *
1086  * RETURN:      None
1087  *
1088  * DESCRIPTION: Control method tracing facility
1089  *
1090  ******************************************************************************/
1091 
1092 void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg)
1093 {
1094     u32 debug_level = 0;
1095     u32 debug_layer = 0;
1096     u32 flags = 0;
1097 
1098     acpi_ut_strupr(enable_arg);
1099     acpi_ut_strupr(once_arg);
1100 
1101     if (method_arg) {
1102         if (acpi_db_trace_method_name) {
1103             ACPI_FREE(acpi_db_trace_method_name);
1104             acpi_db_trace_method_name = NULL;
1105         }
1106 
1107         acpi_db_trace_method_name =
1108             ACPI_ALLOCATE(strlen(method_arg) + 1);
1109         if (!acpi_db_trace_method_name) {
1110             acpi_os_printf("Failed to allocate method name (%s)\n",
1111                        method_arg);
1112             return;
1113         }
1114 
1115         strcpy(acpi_db_trace_method_name, method_arg);
1116     }
1117 
1118     if (!strcmp(enable_arg, "ENABLE") ||
1119         !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) {
1120         if (!strcmp(enable_arg, "ENABLE")) {
1121 
1122             /* Inherit current console settings */
1123 
1124             debug_level = acpi_gbl_db_console_debug_level;
1125             debug_layer = acpi_dbg_layer;
1126         } else {
1127             /* Restrict console output to trace points only */
1128 
1129             debug_level = ACPI_LV_TRACE_POINT;
1130             debug_layer = ACPI_EXECUTER;
1131         }
1132 
1133         flags = ACPI_TRACE_ENABLED;
1134 
1135         if (!strcmp(enable_arg, "OPCODE")) {
1136             flags |= ACPI_TRACE_OPCODE;
1137         }
1138 
1139         if (once_arg && !strcmp(once_arg, "ONCE")) {
1140             flags |= ACPI_TRACE_ONESHOT;
1141         }
1142     }
1143 
1144     (void)acpi_debug_trace(acpi_db_trace_method_name,
1145                    debug_level, debug_layer, flags);
1146 }