Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /*******************************************************************************
0003  *
0004  * Module Name: dbnames - Debugger commands for the acpi namespace
0005  *
0006  ******************************************************************************/
0007 
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acnamesp.h"
0011 #include "acdebug.h"
0012 #include "acpredef.h"
0013 #include "acinterp.h"
0014 
0015 #define _COMPONENT          ACPI_CA_DEBUGGER
0016 ACPI_MODULE_NAME("dbnames")
0017 
0018 /* Local prototypes */
0019 static acpi_status
0020 acpi_db_walk_and_match_name(acpi_handle obj_handle,
0021                 u32 nesting_level,
0022                 void *context, void **return_value);
0023 
0024 static acpi_status
0025 acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
0026                   u32 nesting_level,
0027                   void *context, void **return_value);
0028 
0029 static acpi_status
0030 acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
0031                   u32 nesting_level,
0032                   void *context, void **return_value);
0033 
0034 static acpi_status
0035 acpi_db_walk_for_object_counts(acpi_handle obj_handle,
0036                    u32 nesting_level,
0037                    void *context, void **return_value);
0038 
0039 static acpi_status
0040 acpi_db_integrity_walk(acpi_handle obj_handle,
0041                u32 nesting_level, void *context, void **return_value);
0042 
0043 static acpi_status
0044 acpi_db_walk_for_references(acpi_handle obj_handle,
0045                 u32 nesting_level,
0046                 void *context, void **return_value);
0047 
0048 static acpi_status
0049 acpi_db_bus_walk(acpi_handle obj_handle,
0050          u32 nesting_level, void *context, void **return_value);
0051 
0052 /*
0053  * Arguments for the Objects command
0054  * These object types map directly to the ACPI_TYPES
0055  */
0056 static struct acpi_db_argument_info acpi_db_object_types[] = {
0057     {"ANY"},
0058     {"INTEGERS"},
0059     {"STRINGS"},
0060     {"BUFFERS"},
0061     {"PACKAGES"},
0062     {"FIELDS"},
0063     {"DEVICES"},
0064     {"EVENTS"},
0065     {"METHODS"},
0066     {"MUTEXES"},
0067     {"REGIONS"},
0068     {"POWERRESOURCES"},
0069     {"PROCESSORS"},
0070     {"THERMALZONES"},
0071     {"BUFFERFIELDS"},
0072     {"DDBHANDLES"},
0073     {"DEBUG"},
0074     {"REGIONFIELDS"},
0075     {"BANKFIELDS"},
0076     {"INDEXFIELDS"},
0077     {"REFERENCES"},
0078     {"ALIASES"},
0079     {"METHODALIASES"},
0080     {"NOTIFY"},
0081     {"ADDRESSHANDLER"},
0082     {"RESOURCE"},
0083     {"RESOURCEFIELD"},
0084     {"SCOPES"},
0085     {NULL}          /* Must be null terminated */
0086 };
0087 
0088 /*******************************************************************************
0089  *
0090  * FUNCTION:    acpi_db_set_scope
0091  *
0092  * PARAMETERS:  name                - New scope path
0093  *
0094  * RETURN:      Status
0095  *
0096  * DESCRIPTION: Set the "current scope" as maintained by this utility.
0097  *              The scope is used as a prefix to ACPI paths.
0098  *
0099  ******************************************************************************/
0100 
0101 void acpi_db_set_scope(char *name)
0102 {
0103     acpi_status status;
0104     struct acpi_namespace_node *node;
0105 
0106     if (!name || name[0] == 0) {
0107         acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf);
0108         return;
0109     }
0110 
0111     acpi_db_prep_namestring(name);
0112 
0113     if (ACPI_IS_ROOT_PREFIX(name[0])) {
0114 
0115         /* Validate new scope from the root */
0116 
0117         status = acpi_ns_get_node(acpi_gbl_root_node, name,
0118                       ACPI_NS_NO_UPSEARCH, &node);
0119         if (ACPI_FAILURE(status)) {
0120             goto error_exit;
0121         }
0122 
0123         acpi_gbl_db_scope_buf[0] = 0;
0124     } else {
0125         /* Validate new scope relative to old scope */
0126 
0127         status = acpi_ns_get_node(acpi_gbl_db_scope_node, name,
0128                       ACPI_NS_NO_UPSEARCH, &node);
0129         if (ACPI_FAILURE(status)) {
0130             goto error_exit;
0131         }
0132     }
0133 
0134     /* Build the final pathname */
0135 
0136     if (acpi_ut_safe_strcat
0137         (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) {
0138         status = AE_BUFFER_OVERFLOW;
0139         goto error_exit;
0140     }
0141 
0142     if (acpi_ut_safe_strcat
0143         (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) {
0144         status = AE_BUFFER_OVERFLOW;
0145         goto error_exit;
0146     }
0147 
0148     acpi_gbl_db_scope_node = node;
0149     acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf);
0150     return;
0151 
0152 error_exit:
0153 
0154     acpi_os_printf("Could not attach scope: %s, %s\n",
0155                name, acpi_format_exception(status));
0156 }
0157 
0158 /*******************************************************************************
0159  *
0160  * FUNCTION:    acpi_db_dump_namespace
0161  *
0162  * PARAMETERS:  start_arg       - Node to begin namespace dump
0163  *              depth_arg       - Maximum tree depth to be dumped
0164  *
0165  * RETURN:      None
0166  *
0167  * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
0168  *              with type and other information.
0169  *
0170  ******************************************************************************/
0171 
0172 void acpi_db_dump_namespace(char *start_arg, char *depth_arg)
0173 {
0174     acpi_handle subtree_entry = acpi_gbl_root_node;
0175     u32 max_depth = ACPI_UINT32_MAX;
0176 
0177     /* No argument given, just start at the root and dump entire namespace */
0178 
0179     if (start_arg) {
0180         subtree_entry = acpi_db_convert_to_node(start_arg);
0181         if (!subtree_entry) {
0182             return;
0183         }
0184 
0185         /* Now we can check for the depth argument */
0186 
0187         if (depth_arg) {
0188             max_depth = strtoul(depth_arg, NULL, 0);
0189         }
0190     }
0191 
0192     acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
0193 
0194     if (((struct acpi_namespace_node *)subtree_entry)->parent) {
0195         acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
0196                    ((struct acpi_namespace_node *)subtree_entry)->
0197                    name.ascii, subtree_entry);
0198     } else {
0199         acpi_os_printf("ACPI Namespace (from %s):\n",
0200                    ACPI_NAMESPACE_ROOT);
0201     }
0202 
0203     /* Display the subtree */
0204 
0205     acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
0206     acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
0207                  ACPI_OWNER_ID_MAX, subtree_entry);
0208     acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
0209 }
0210 
0211 /*******************************************************************************
0212  *
0213  * FUNCTION:    acpi_db_dump_namespace_paths
0214  *
0215  * PARAMETERS:  None
0216  *
0217  * RETURN:      None
0218  *
0219  * DESCRIPTION: Dump entire namespace with full object pathnames and object
0220  *              type information. Alternative to "namespace" command.
0221  *
0222  ******************************************************************************/
0223 
0224 void acpi_db_dump_namespace_paths(void)
0225 {
0226 
0227     acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
0228     acpi_os_printf("ACPI Namespace (from root):\n");
0229 
0230     /* Display the entire namespace */
0231 
0232     acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
0233     acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
0234                   ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX,
0235                   acpi_gbl_root_node);
0236 
0237     acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
0238 }
0239 
0240 /*******************************************************************************
0241  *
0242  * FUNCTION:    acpi_db_dump_namespace_by_owner
0243  *
0244  * PARAMETERS:  owner_arg       - Owner ID whose nodes will be displayed
0245  *              depth_arg       - Maximum tree depth to be dumped
0246  *
0247  * RETURN:      None
0248  *
0249  * DESCRIPTION: Dump elements of the namespace that are owned by the owner_id.
0250  *
0251  ******************************************************************************/
0252 
0253 void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg)
0254 {
0255     acpi_handle subtree_entry = acpi_gbl_root_node;
0256     u32 max_depth = ACPI_UINT32_MAX;
0257     acpi_owner_id owner_id;
0258 
0259     owner_id = (acpi_owner_id)strtoul(owner_arg, NULL, 0);
0260 
0261     /* Now we can check for the depth argument */
0262 
0263     if (depth_arg) {
0264         max_depth = strtoul(depth_arg, NULL, 0);
0265     }
0266 
0267     acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
0268     acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id);
0269 
0270     /* Display the subtree */
0271 
0272     acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
0273     acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
0274                  owner_id, subtree_entry);
0275     acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
0276 }
0277 
0278 /*******************************************************************************
0279  *
0280  * FUNCTION:    acpi_db_walk_and_match_name
0281  *
0282  * PARAMETERS:  Callback from walk_namespace
0283  *
0284  * RETURN:      Status
0285  *
0286  * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
0287  *              are supported -- '?' matches any character.
0288  *
0289  ******************************************************************************/
0290 
0291 static acpi_status
0292 acpi_db_walk_and_match_name(acpi_handle obj_handle,
0293                 u32 nesting_level,
0294                 void *context, void **return_value)
0295 {
0296     acpi_status status;
0297     char *requested_name = (char *)context;
0298     u32 i;
0299     struct acpi_buffer buffer;
0300     struct acpi_walk_info info;
0301 
0302     /* Check for a name match */
0303 
0304     for (i = 0; i < 4; i++) {
0305 
0306         /* Wildcard support */
0307 
0308         if ((requested_name[i] != '?') &&
0309             (requested_name[i] != ((struct acpi_namespace_node *)
0310                        obj_handle)->name.ascii[i])) {
0311 
0312             /* No match, just exit */
0313 
0314             return (AE_OK);
0315         }
0316     }
0317 
0318     /* Get the full pathname to this object */
0319 
0320     buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0321     status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
0322     if (ACPI_FAILURE(status)) {
0323         acpi_os_printf("Could Not get pathname for object %p\n",
0324                    obj_handle);
0325     } else {
0326         info.count = 0;
0327         info.owner_id = ACPI_OWNER_ID_MAX;
0328         info.debug_level = ACPI_UINT32_MAX;
0329         info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
0330 
0331         acpi_os_printf("%32s", (char *)buffer.pointer);
0332         (void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info,
0333                           NULL);
0334         ACPI_FREE(buffer.pointer);
0335     }
0336 
0337     return (AE_OK);
0338 }
0339 
0340 /*******************************************************************************
0341  *
0342  * FUNCTION:    acpi_db_find_name_in_namespace
0343  *
0344  * PARAMETERS:  name_arg        - The 4-character ACPI name to find.
0345  *                                wildcards are supported.
0346  *
0347  * RETURN:      None
0348  *
0349  * DESCRIPTION: Search the namespace for a given name (with wildcards)
0350  *
0351  ******************************************************************************/
0352 
0353 acpi_status acpi_db_find_name_in_namespace(char *name_arg)
0354 {
0355     char acpi_name[5] = "____";
0356     char *acpi_name_ptr = acpi_name;
0357 
0358     if (strlen(name_arg) > ACPI_NAMESEG_SIZE) {
0359         acpi_os_printf("Name must be no longer than 4 characters\n");
0360         return (AE_OK);
0361     }
0362 
0363     /* Pad out name with underscores as necessary to create a 4-char name */
0364 
0365     acpi_ut_strupr(name_arg);
0366     while (*name_arg) {
0367         *acpi_name_ptr = *name_arg;
0368         acpi_name_ptr++;
0369         name_arg++;
0370     }
0371 
0372     /* Walk the namespace from the root */
0373 
0374     (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0375                   ACPI_UINT32_MAX, acpi_db_walk_and_match_name,
0376                   NULL, acpi_name, NULL);
0377 
0378     acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
0379     return (AE_OK);
0380 }
0381 
0382 /*******************************************************************************
0383  *
0384  * FUNCTION:    acpi_db_walk_for_predefined_names
0385  *
0386  * PARAMETERS:  Callback from walk_namespace
0387  *
0388  * RETURN:      Status
0389  *
0390  * DESCRIPTION: Detect and display predefined ACPI names (names that start with
0391  *              an underscore)
0392  *
0393  ******************************************************************************/
0394 
0395 static acpi_status
0396 acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
0397                   u32 nesting_level,
0398                   void *context, void **return_value)
0399 {
0400     struct acpi_namespace_node *node =
0401         (struct acpi_namespace_node *)obj_handle;
0402     u32 *count = (u32 *)context;
0403     const union acpi_predefined_info *predefined;
0404     const union acpi_predefined_info *package = NULL;
0405     char *pathname;
0406     char string_buffer[48];
0407 
0408     predefined = acpi_ut_match_predefined_method(node->name.ascii);
0409     if (!predefined) {
0410         return (AE_OK);
0411     }
0412 
0413     pathname = acpi_ns_get_normalized_pathname(node, TRUE);
0414     if (!pathname) {
0415         return (AE_OK);
0416     }
0417 
0418     /* If method returns a package, the info is in the next table entry */
0419 
0420     if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
0421         package = predefined + 1;
0422     }
0423 
0424     acpi_ut_get_expected_return_types(string_buffer,
0425                       predefined->info.expected_btypes);
0426 
0427     acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname,
0428                METHOD_GET_ARG_COUNT(predefined->info.argument_list),
0429                string_buffer);
0430 
0431     if (package) {
0432         acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
0433                    package->ret_info.type,
0434                    package->ret_info.object_type1,
0435                    package->ret_info.count1);
0436     }
0437 
0438     acpi_os_printf("\n");
0439 
0440     /* Check that the declared argument count matches the ACPI spec */
0441 
0442     acpi_ns_check_acpi_compliance(pathname, node, predefined);
0443 
0444     ACPI_FREE(pathname);
0445     (*count)++;
0446     return (AE_OK);
0447 }
0448 
0449 /*******************************************************************************
0450  *
0451  * FUNCTION:    acpi_db_check_predefined_names
0452  *
0453  * PARAMETERS:  None
0454  *
0455  * RETURN:      None
0456  *
0457  * DESCRIPTION: Validate all predefined names in the namespace
0458  *
0459  ******************************************************************************/
0460 
0461 void acpi_db_check_predefined_names(void)
0462 {
0463     u32 count = 0;
0464 
0465     /* Search all nodes in namespace */
0466 
0467     (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0468                   ACPI_UINT32_MAX,
0469                   acpi_db_walk_for_predefined_names, NULL,
0470                   (void *)&count, NULL);
0471 
0472     acpi_os_printf("Found %u predefined names in the namespace\n", count);
0473 }
0474 
0475 /*******************************************************************************
0476  *
0477  * FUNCTION:    acpi_db_walk_for_object_counts
0478  *
0479  * PARAMETERS:  Callback from walk_namespace
0480  *
0481  * RETURN:      Status
0482  *
0483  * DESCRIPTION: Display short info about objects in the namespace
0484  *
0485  ******************************************************************************/
0486 
0487 static acpi_status
0488 acpi_db_walk_for_object_counts(acpi_handle obj_handle,
0489                    u32 nesting_level,
0490                    void *context, void **return_value)
0491 {
0492     struct acpi_object_info *info = (struct acpi_object_info *)context;
0493     struct acpi_namespace_node *node =
0494         (struct acpi_namespace_node *)obj_handle;
0495 
0496     if (node->type > ACPI_TYPE_NS_NODE_MAX) {
0497         acpi_os_printf("[%4.4s]: Unknown object type %X\n",
0498                    node->name.ascii, node->type);
0499     } else {
0500         info->types[node->type]++;
0501     }
0502 
0503     return (AE_OK);
0504 }
0505 
0506 /*******************************************************************************
0507  *
0508  * FUNCTION:    acpi_db_walk_for_fields
0509  *
0510  * PARAMETERS:  Callback from walk_namespace
0511  *
0512  * RETURN:      Status
0513  *
0514  * DESCRIPTION: Display short info about objects in the namespace
0515  *
0516  ******************************************************************************/
0517 
0518 static acpi_status
0519 acpi_db_walk_for_fields(acpi_handle obj_handle,
0520             u32 nesting_level, void *context, void **return_value)
0521 {
0522     union acpi_object *ret_value;
0523     struct acpi_region_walk_info *info =
0524         (struct acpi_region_walk_info *)context;
0525     struct acpi_buffer buffer;
0526     acpi_status status;
0527     struct acpi_namespace_node *node = acpi_ns_validate_handle(obj_handle);
0528 
0529     if (!node) {
0530         return (AE_OK);
0531     }
0532     if (node->object->field.region_obj->region.space_id !=
0533         info->address_space_id) {
0534         return (AE_OK);
0535     }
0536 
0537     info->count++;
0538 
0539     /* Get and display the full pathname to this object */
0540 
0541     buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0542     status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
0543     if (ACPI_FAILURE(status)) {
0544         acpi_os_printf("Could Not get pathname for object %p\n",
0545                    obj_handle);
0546         return (AE_OK);
0547     }
0548 
0549     acpi_os_printf("%s ", (char *)buffer.pointer);
0550     ACPI_FREE(buffer.pointer);
0551 
0552     buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0553     acpi_evaluate_object(obj_handle, NULL, NULL, &buffer);
0554 
0555     /*
0556      * Since this is a field unit, surround the output in braces
0557      */
0558     acpi_os_printf("{");
0559 
0560     ret_value = (union acpi_object *)buffer.pointer;
0561     switch (ret_value->type) {
0562     case ACPI_TYPE_INTEGER:
0563 
0564         acpi_os_printf("%8.8X%8.8X",
0565                    ACPI_FORMAT_UINT64(ret_value->integer.value));
0566         break;
0567 
0568     case ACPI_TYPE_BUFFER:
0569 
0570         acpi_ut_dump_buffer(ret_value->buffer.pointer,
0571                     ret_value->buffer.length,
0572                     DB_DISPLAY_DATA_ONLY | DB_BYTE_DISPLAY, 0);
0573         break;
0574 
0575     default:
0576 
0577         break;
0578     }
0579     acpi_os_printf("}\n");
0580 
0581     ACPI_FREE(buffer.pointer);
0582 
0583     return (AE_OK);
0584 }
0585 
0586 /*******************************************************************************
0587  *
0588  * FUNCTION:    acpi_db_walk_for_specific_objects
0589  *
0590  * PARAMETERS:  Callback from walk_namespace
0591  *
0592  * RETURN:      Status
0593  *
0594  * DESCRIPTION: Display short info about objects in the namespace
0595  *
0596  ******************************************************************************/
0597 
0598 static acpi_status
0599 acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
0600                   u32 nesting_level,
0601                   void *context, void **return_value)
0602 {
0603     struct acpi_walk_info *info = (struct acpi_walk_info *)context;
0604     struct acpi_buffer buffer;
0605     acpi_status status;
0606 
0607     info->count++;
0608 
0609     /* Get and display the full pathname to this object */
0610 
0611     buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0612     status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
0613     if (ACPI_FAILURE(status)) {
0614         acpi_os_printf("Could Not get pathname for object %p\n",
0615                    obj_handle);
0616         return (AE_OK);
0617     }
0618 
0619     acpi_os_printf("%32s", (char *)buffer.pointer);
0620     ACPI_FREE(buffer.pointer);
0621 
0622     /* Dump short info about the object */
0623 
0624     (void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL);
0625     return (AE_OK);
0626 }
0627 
0628 /*******************************************************************************
0629  *
0630  * FUNCTION:    acpi_db_display_objects
0631  *
0632  * PARAMETERS:  obj_type_arg        - Type of object to display
0633  *              display_count_arg   - Max depth to display
0634  *
0635  * RETURN:      None
0636  *
0637  * DESCRIPTION: Display objects in the namespace of the requested type
0638  *
0639  ******************************************************************************/
0640 
0641 acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
0642 {
0643     struct acpi_walk_info info;
0644     acpi_object_type type;
0645     struct acpi_object_info *object_info;
0646     u32 i;
0647     u32 total_objects = 0;
0648 
0649     /* No argument means display summary/count of all object types */
0650 
0651     if (!obj_type_arg) {
0652         object_info =
0653             ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
0654 
0655         /* Walk the namespace from the root */
0656 
0657         (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0658                       ACPI_UINT32_MAX,
0659                       acpi_db_walk_for_object_counts, NULL,
0660                       (void *)object_info, NULL);
0661 
0662         acpi_os_printf("\nSummary of namespace objects:\n\n");
0663 
0664         for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
0665             acpi_os_printf("%8u %s\n", object_info->types[i],
0666                        acpi_ut_get_type_name(i));
0667 
0668             total_objects += object_info->types[i];
0669         }
0670 
0671         acpi_os_printf("\n%8u Total namespace objects\n\n",
0672                    total_objects);
0673 
0674         ACPI_FREE(object_info);
0675         return (AE_OK);
0676     }
0677 
0678     /* Get the object type */
0679 
0680     type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
0681     if (type == ACPI_TYPE_NOT_FOUND) {
0682         acpi_os_printf("Invalid or unsupported argument\n");
0683         return (AE_OK);
0684     }
0685 
0686     acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
0687     acpi_os_printf
0688         ("Objects of type [%s] defined in the current ACPI Namespace:\n",
0689          acpi_ut_get_type_name(type));
0690 
0691     acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
0692 
0693     info.count = 0;
0694     info.owner_id = ACPI_OWNER_ID_MAX;
0695     info.debug_level = ACPI_UINT32_MAX;
0696     info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
0697 
0698     /* Walk the namespace from the root */
0699 
0700     (void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
0701                   acpi_db_walk_for_specific_objects, NULL,
0702                   (void *)&info, NULL);
0703 
0704     acpi_os_printf
0705         ("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
0706          info.count, acpi_ut_get_type_name(type));
0707 
0708     acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
0709     return (AE_OK);
0710 }
0711 
0712 /*******************************************************************************
0713  *
0714  * FUNCTION:    acpi_db_display_fields
0715  *
0716  * PARAMETERS:  obj_type_arg        - Type of object to display
0717  *              display_count_arg   - Max depth to display
0718  *
0719  * RETURN:      None
0720  *
0721  * DESCRIPTION: Display objects in the namespace of the requested type
0722  *
0723  ******************************************************************************/
0724 
0725 acpi_status acpi_db_display_fields(u32 address_space_id)
0726 {
0727     struct acpi_region_walk_info info;
0728 
0729     info.count = 0;
0730     info.owner_id = ACPI_OWNER_ID_MAX;
0731     info.debug_level = ACPI_UINT32_MAX;
0732     info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
0733     info.address_space_id = address_space_id;
0734 
0735     /* Walk the namespace from the root */
0736 
0737     (void)acpi_walk_namespace(ACPI_TYPE_LOCAL_REGION_FIELD,
0738                   ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
0739                   acpi_db_walk_for_fields, NULL, (void *)&info,
0740                   NULL);
0741 
0742     return (AE_OK);
0743 }
0744 
0745 /*******************************************************************************
0746  *
0747  * FUNCTION:    acpi_db_integrity_walk
0748  *
0749  * PARAMETERS:  Callback from walk_namespace
0750  *
0751  * RETURN:      Status
0752  *
0753  * DESCRIPTION: Examine one NS node for valid values.
0754  *
0755  ******************************************************************************/
0756 
0757 static acpi_status
0758 acpi_db_integrity_walk(acpi_handle obj_handle,
0759                u32 nesting_level, void *context, void **return_value)
0760 {
0761     struct acpi_integrity_info *info =
0762         (struct acpi_integrity_info *)context;
0763     struct acpi_namespace_node *node =
0764         (struct acpi_namespace_node *)obj_handle;
0765     union acpi_operand_object *object;
0766     u8 alias = TRUE;
0767 
0768     info->nodes++;
0769 
0770     /* Verify the NS node, and dereference aliases */
0771 
0772     while (alias) {
0773         if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
0774             acpi_os_printf
0775                 ("Invalid Descriptor Type for Node %p [%s] - "
0776                  "is %2.2X should be %2.2X\n", node,
0777                  acpi_ut_get_descriptor_name(node),
0778                  ACPI_GET_DESCRIPTOR_TYPE(node),
0779                  ACPI_DESC_TYPE_NAMED);
0780             return (AE_OK);
0781         }
0782 
0783         if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
0784             (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
0785             node = (struct acpi_namespace_node *)node->object;
0786         } else {
0787             alias = FALSE;
0788         }
0789     }
0790 
0791     if (node->type > ACPI_TYPE_LOCAL_MAX) {
0792         acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
0793                    node, node->type);
0794         return (AE_OK);
0795     }
0796 
0797     if (!acpi_ut_valid_nameseg(node->name.ascii)) {
0798         acpi_os_printf("Invalid AcpiName for Node %p\n", node);
0799         return (AE_OK);
0800     }
0801 
0802     object = acpi_ns_get_attached_object(node);
0803     if (object) {
0804         info->objects++;
0805         if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
0806             acpi_os_printf
0807                 ("Invalid Descriptor Type for Object %p [%s]\n",
0808                  object, acpi_ut_get_descriptor_name(object));
0809         }
0810     }
0811 
0812     return (AE_OK);
0813 }
0814 
0815 /*******************************************************************************
0816  *
0817  * FUNCTION:    acpi_db_check_integrity
0818  *
0819  * PARAMETERS:  None
0820  *
0821  * RETURN:      None
0822  *
0823  * DESCRIPTION: Check entire namespace for data structure integrity
0824  *
0825  ******************************************************************************/
0826 
0827 void acpi_db_check_integrity(void)
0828 {
0829     struct acpi_integrity_info info = { 0, 0 };
0830 
0831     /* Search all nodes in namespace */
0832 
0833     (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0834                   ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
0835                   (void *)&info, NULL);
0836 
0837     acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
0838                info.nodes, info.objects);
0839 }
0840 
0841 /*******************************************************************************
0842  *
0843  * FUNCTION:    acpi_db_walk_for_references
0844  *
0845  * PARAMETERS:  Callback from walk_namespace
0846  *
0847  * RETURN:      Status
0848  *
0849  * DESCRIPTION: Check if this namespace object refers to the target object
0850  *              that is passed in as the context value.
0851  *
0852  * Note: Currently doesn't check subobjects within the Node's object
0853  *
0854  ******************************************************************************/
0855 
0856 static acpi_status
0857 acpi_db_walk_for_references(acpi_handle obj_handle,
0858                 u32 nesting_level,
0859                 void *context, void **return_value)
0860 {
0861     union acpi_operand_object *obj_desc =
0862         (union acpi_operand_object *)context;
0863     struct acpi_namespace_node *node =
0864         (struct acpi_namespace_node *)obj_handle;
0865 
0866     /* Check for match against the namespace node itself */
0867 
0868     if (node == (void *)obj_desc) {
0869         acpi_os_printf("Object is a Node [%4.4s]\n",
0870                    acpi_ut_get_node_name(node));
0871     }
0872 
0873     /* Check for match against the object attached to the node */
0874 
0875     if (acpi_ns_get_attached_object(node) == obj_desc) {
0876         acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
0877                    node, acpi_ut_get_node_name(node));
0878     }
0879 
0880     return (AE_OK);
0881 }
0882 
0883 /*******************************************************************************
0884  *
0885  * FUNCTION:    acpi_db_find_references
0886  *
0887  * PARAMETERS:  object_arg      - String with hex value of the object
0888  *
0889  * RETURN:      None
0890  *
0891  * DESCRIPTION: Search namespace for all references to the input object
0892  *
0893  ******************************************************************************/
0894 
0895 void acpi_db_find_references(char *object_arg)
0896 {
0897     union acpi_operand_object *obj_desc;
0898     acpi_size address;
0899 
0900     /* Convert string to object pointer */
0901 
0902     address = strtoul(object_arg, NULL, 16);
0903     obj_desc = ACPI_TO_POINTER(address);
0904 
0905     /* Search all nodes in namespace */
0906 
0907     (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0908                   ACPI_UINT32_MAX, acpi_db_walk_for_references,
0909                   NULL, (void *)obj_desc, NULL);
0910 }
0911 
0912 /*******************************************************************************
0913  *
0914  * FUNCTION:    acpi_db_bus_walk
0915  *
0916  * PARAMETERS:  Callback from walk_namespace
0917  *
0918  * RETURN:      Status
0919  *
0920  * DESCRIPTION: Display info about device objects that have a corresponding
0921  *              _PRT method.
0922  *
0923  ******************************************************************************/
0924 
0925 static acpi_status
0926 acpi_db_bus_walk(acpi_handle obj_handle,
0927          u32 nesting_level, void *context, void **return_value)
0928 {
0929     struct acpi_namespace_node *node =
0930         (struct acpi_namespace_node *)obj_handle;
0931     acpi_status status;
0932     struct acpi_buffer buffer;
0933     struct acpi_namespace_node *temp_node;
0934     struct acpi_device_info *info;
0935     u32 i;
0936 
0937     if ((node->type != ACPI_TYPE_DEVICE) &&
0938         (node->type != ACPI_TYPE_PROCESSOR)) {
0939         return (AE_OK);
0940     }
0941 
0942     /* Exit if there is no _PRT under this device */
0943 
0944     status = acpi_get_handle(node, METHOD_NAME__PRT,
0945                  ACPI_CAST_PTR(acpi_handle, &temp_node));
0946     if (ACPI_FAILURE(status)) {
0947         return (AE_OK);
0948     }
0949 
0950     /* Get the full path to this device object */
0951 
0952     buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0953     status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
0954     if (ACPI_FAILURE(status)) {
0955         acpi_os_printf("Could Not get pathname for object %p\n",
0956                    obj_handle);
0957         return (AE_OK);
0958     }
0959 
0960     status = acpi_get_object_info(obj_handle, &info);
0961     if (ACPI_FAILURE(status)) {
0962         return (AE_OK);
0963     }
0964 
0965     /* Display the full path */
0966 
0967     acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
0968     ACPI_FREE(buffer.pointer);
0969 
0970     if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
0971         acpi_os_printf(" - Is PCI Root Bridge");
0972     }
0973     acpi_os_printf("\n");
0974 
0975     /* _PRT info */
0976 
0977     acpi_os_printf("_PRT: %p\n", temp_node);
0978 
0979     /* Dump _ADR, _HID, _UID, _CID */
0980 
0981     if (info->valid & ACPI_VALID_ADR) {
0982         acpi_os_printf("_ADR: %8.8X%8.8X\n",
0983                    ACPI_FORMAT_UINT64(info->address));
0984     } else {
0985         acpi_os_printf("_ADR: <Not Present>\n");
0986     }
0987 
0988     if (info->valid & ACPI_VALID_HID) {
0989         acpi_os_printf("_HID: %s\n", info->hardware_id.string);
0990     } else {
0991         acpi_os_printf("_HID: <Not Present>\n");
0992     }
0993 
0994     if (info->valid & ACPI_VALID_UID) {
0995         acpi_os_printf("_UID: %s\n", info->unique_id.string);
0996     } else {
0997         acpi_os_printf("_UID: <Not Present>\n");
0998     }
0999 
1000     if (info->valid & ACPI_VALID_CID) {
1001         for (i = 0; i < info->compatible_id_list.count; i++) {
1002             acpi_os_printf("_CID: %s\n",
1003                        info->compatible_id_list.ids[i].string);
1004         }
1005     } else {
1006         acpi_os_printf("_CID: <Not Present>\n");
1007     }
1008 
1009     ACPI_FREE(info);
1010     return (AE_OK);
1011 }
1012 
1013 /*******************************************************************************
1014  *
1015  * FUNCTION:    acpi_db_get_bus_info
1016  *
1017  * PARAMETERS:  None
1018  *
1019  * RETURN:      None
1020  *
1021  * DESCRIPTION: Display info about system buses.
1022  *
1023  ******************************************************************************/
1024 
1025 void acpi_db_get_bus_info(void)
1026 {
1027     /* Search all nodes in namespace */
1028 
1029     (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1030                   ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL,
1031                   NULL);
1032 }