cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dbnames.c (27592B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/*******************************************************************************
      3 *
      4 * Module Name: dbnames - Debugger commands for the acpi namespace
      5 *
      6 ******************************************************************************/
      7
      8#include <acpi/acpi.h>
      9#include "accommon.h"
     10#include "acnamesp.h"
     11#include "acdebug.h"
     12#include "acpredef.h"
     13#include "acinterp.h"
     14
     15#define _COMPONENT          ACPI_CA_DEBUGGER
     16ACPI_MODULE_NAME("dbnames")
     17
     18/* Local prototypes */
     19static acpi_status
     20acpi_db_walk_and_match_name(acpi_handle obj_handle,
     21			    u32 nesting_level,
     22			    void *context, void **return_value);
     23
     24static acpi_status
     25acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
     26				  u32 nesting_level,
     27				  void *context, void **return_value);
     28
     29static acpi_status
     30acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
     31				  u32 nesting_level,
     32				  void *context, void **return_value);
     33
     34static acpi_status
     35acpi_db_walk_for_object_counts(acpi_handle obj_handle,
     36			       u32 nesting_level,
     37			       void *context, void **return_value);
     38
     39static acpi_status
     40acpi_db_integrity_walk(acpi_handle obj_handle,
     41		       u32 nesting_level, void *context, void **return_value);
     42
     43static acpi_status
     44acpi_db_walk_for_references(acpi_handle obj_handle,
     45			    u32 nesting_level,
     46			    void *context, void **return_value);
     47
     48static acpi_status
     49acpi_db_bus_walk(acpi_handle obj_handle,
     50		 u32 nesting_level, void *context, void **return_value);
     51
     52/*
     53 * Arguments for the Objects command
     54 * These object types map directly to the ACPI_TYPES
     55 */
     56static struct acpi_db_argument_info acpi_db_object_types[] = {
     57	{"ANY"},
     58	{"INTEGERS"},
     59	{"STRINGS"},
     60	{"BUFFERS"},
     61	{"PACKAGES"},
     62	{"FIELDS"},
     63	{"DEVICES"},
     64	{"EVENTS"},
     65	{"METHODS"},
     66	{"MUTEXES"},
     67	{"REGIONS"},
     68	{"POWERRESOURCES"},
     69	{"PROCESSORS"},
     70	{"THERMALZONES"},
     71	{"BUFFERFIELDS"},
     72	{"DDBHANDLES"},
     73	{"DEBUG"},
     74	{"REGIONFIELDS"},
     75	{"BANKFIELDS"},
     76	{"INDEXFIELDS"},
     77	{"REFERENCES"},
     78	{"ALIASES"},
     79	{"METHODALIASES"},
     80	{"NOTIFY"},
     81	{"ADDRESSHANDLER"},
     82	{"RESOURCE"},
     83	{"RESOURCEFIELD"},
     84	{"SCOPES"},
     85	{NULL}			/* Must be null terminated */
     86};
     87
     88/*******************************************************************************
     89 *
     90 * FUNCTION:    acpi_db_set_scope
     91 *
     92 * PARAMETERS:  name                - New scope path
     93 *
     94 * RETURN:      Status
     95 *
     96 * DESCRIPTION: Set the "current scope" as maintained by this utility.
     97 *              The scope is used as a prefix to ACPI paths.
     98 *
     99 ******************************************************************************/
    100
    101void acpi_db_set_scope(char *name)
    102{
    103	acpi_status status;
    104	struct acpi_namespace_node *node;
    105
    106	if (!name || name[0] == 0) {
    107		acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf);
    108		return;
    109	}
    110
    111	acpi_db_prep_namestring(name);
    112
    113	if (ACPI_IS_ROOT_PREFIX(name[0])) {
    114
    115		/* Validate new scope from the root */
    116
    117		status = acpi_ns_get_node(acpi_gbl_root_node, name,
    118					  ACPI_NS_NO_UPSEARCH, &node);
    119		if (ACPI_FAILURE(status)) {
    120			goto error_exit;
    121		}
    122
    123		acpi_gbl_db_scope_buf[0] = 0;
    124	} else {
    125		/* Validate new scope relative to old scope */
    126
    127		status = acpi_ns_get_node(acpi_gbl_db_scope_node, name,
    128					  ACPI_NS_NO_UPSEARCH, &node);
    129		if (ACPI_FAILURE(status)) {
    130			goto error_exit;
    131		}
    132	}
    133
    134	/* Build the final pathname */
    135
    136	if (acpi_ut_safe_strcat
    137	    (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) {
    138		status = AE_BUFFER_OVERFLOW;
    139		goto error_exit;
    140	}
    141
    142	if (acpi_ut_safe_strcat
    143	    (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) {
    144		status = AE_BUFFER_OVERFLOW;
    145		goto error_exit;
    146	}
    147
    148	acpi_gbl_db_scope_node = node;
    149	acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf);
    150	return;
    151
    152error_exit:
    153
    154	acpi_os_printf("Could not attach scope: %s, %s\n",
    155		       name, acpi_format_exception(status));
    156}
    157
    158/*******************************************************************************
    159 *
    160 * FUNCTION:    acpi_db_dump_namespace
    161 *
    162 * PARAMETERS:  start_arg       - Node to begin namespace dump
    163 *              depth_arg       - Maximum tree depth to be dumped
    164 *
    165 * RETURN:      None
    166 *
    167 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
    168 *              with type and other information.
    169 *
    170 ******************************************************************************/
    171
    172void acpi_db_dump_namespace(char *start_arg, char *depth_arg)
    173{
    174	acpi_handle subtree_entry = acpi_gbl_root_node;
    175	u32 max_depth = ACPI_UINT32_MAX;
    176
    177	/* No argument given, just start at the root and dump entire namespace */
    178
    179	if (start_arg) {
    180		subtree_entry = acpi_db_convert_to_node(start_arg);
    181		if (!subtree_entry) {
    182			return;
    183		}
    184
    185		/* Now we can check for the depth argument */
    186
    187		if (depth_arg) {
    188			max_depth = strtoul(depth_arg, NULL, 0);
    189		}
    190	}
    191
    192	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
    193
    194	if (((struct acpi_namespace_node *)subtree_entry)->parent) {
    195		acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
    196			       ((struct acpi_namespace_node *)subtree_entry)->
    197			       name.ascii, subtree_entry);
    198	} else {
    199		acpi_os_printf("ACPI Namespace (from %s):\n",
    200			       ACPI_NAMESPACE_ROOT);
    201	}
    202
    203	/* Display the subtree */
    204
    205	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
    206	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
    207			     ACPI_OWNER_ID_MAX, subtree_entry);
    208	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
    209}
    210
    211/*******************************************************************************
    212 *
    213 * FUNCTION:    acpi_db_dump_namespace_paths
    214 *
    215 * PARAMETERS:  None
    216 *
    217 * RETURN:      None
    218 *
    219 * DESCRIPTION: Dump entire namespace with full object pathnames and object
    220 *              type information. Alternative to "namespace" command.
    221 *
    222 ******************************************************************************/
    223
    224void acpi_db_dump_namespace_paths(void)
    225{
    226
    227	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
    228	acpi_os_printf("ACPI Namespace (from root):\n");
    229
    230	/* Display the entire namespace */
    231
    232	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
    233	acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
    234				  ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX,
    235				  acpi_gbl_root_node);
    236
    237	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
    238}
    239
    240/*******************************************************************************
    241 *
    242 * FUNCTION:    acpi_db_dump_namespace_by_owner
    243 *
    244 * PARAMETERS:  owner_arg       - Owner ID whose nodes will be displayed
    245 *              depth_arg       - Maximum tree depth to be dumped
    246 *
    247 * RETURN:      None
    248 *
    249 * DESCRIPTION: Dump elements of the namespace that are owned by the owner_id.
    250 *
    251 ******************************************************************************/
    252
    253void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg)
    254{
    255	acpi_handle subtree_entry = acpi_gbl_root_node;
    256	u32 max_depth = ACPI_UINT32_MAX;
    257	acpi_owner_id owner_id;
    258
    259	owner_id = (acpi_owner_id)strtoul(owner_arg, NULL, 0);
    260
    261	/* Now we can check for the depth argument */
    262
    263	if (depth_arg) {
    264		max_depth = strtoul(depth_arg, NULL, 0);
    265	}
    266
    267	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
    268	acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id);
    269
    270	/* Display the subtree */
    271
    272	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
    273	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
    274			     owner_id, subtree_entry);
    275	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
    276}
    277
    278/*******************************************************************************
    279 *
    280 * FUNCTION:    acpi_db_walk_and_match_name
    281 *
    282 * PARAMETERS:  Callback from walk_namespace
    283 *
    284 * RETURN:      Status
    285 *
    286 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
    287 *              are supported -- '?' matches any character.
    288 *
    289 ******************************************************************************/
    290
    291static acpi_status
    292acpi_db_walk_and_match_name(acpi_handle obj_handle,
    293			    u32 nesting_level,
    294			    void *context, void **return_value)
    295{
    296	acpi_status status;
    297	char *requested_name = (char *)context;
    298	u32 i;
    299	struct acpi_buffer buffer;
    300	struct acpi_walk_info info;
    301
    302	/* Check for a name match */
    303
    304	for (i = 0; i < 4; i++) {
    305
    306		/* Wildcard support */
    307
    308		if ((requested_name[i] != '?') &&
    309		    (requested_name[i] != ((struct acpi_namespace_node *)
    310					   obj_handle)->name.ascii[i])) {
    311
    312			/* No match, just exit */
    313
    314			return (AE_OK);
    315		}
    316	}
    317
    318	/* Get the full pathname to this object */
    319
    320	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    321	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
    322	if (ACPI_FAILURE(status)) {
    323		acpi_os_printf("Could Not get pathname for object %p\n",
    324			       obj_handle);
    325	} else {
    326		info.count = 0;
    327		info.owner_id = ACPI_OWNER_ID_MAX;
    328		info.debug_level = ACPI_UINT32_MAX;
    329		info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
    330
    331		acpi_os_printf("%32s", (char *)buffer.pointer);
    332		(void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info,
    333					      NULL);
    334		ACPI_FREE(buffer.pointer);
    335	}
    336
    337	return (AE_OK);
    338}
    339
    340/*******************************************************************************
    341 *
    342 * FUNCTION:    acpi_db_find_name_in_namespace
    343 *
    344 * PARAMETERS:  name_arg        - The 4-character ACPI name to find.
    345 *                                wildcards are supported.
    346 *
    347 * RETURN:      None
    348 *
    349 * DESCRIPTION: Search the namespace for a given name (with wildcards)
    350 *
    351 ******************************************************************************/
    352
    353acpi_status acpi_db_find_name_in_namespace(char *name_arg)
    354{
    355	char acpi_name[5] = "____";
    356	char *acpi_name_ptr = acpi_name;
    357
    358	if (strlen(name_arg) > ACPI_NAMESEG_SIZE) {
    359		acpi_os_printf("Name must be no longer than 4 characters\n");
    360		return (AE_OK);
    361	}
    362
    363	/* Pad out name with underscores as necessary to create a 4-char name */
    364
    365	acpi_ut_strupr(name_arg);
    366	while (*name_arg) {
    367		*acpi_name_ptr = *name_arg;
    368		acpi_name_ptr++;
    369		name_arg++;
    370	}
    371
    372	/* Walk the namespace from the root */
    373
    374	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    375				  ACPI_UINT32_MAX, acpi_db_walk_and_match_name,
    376				  NULL, acpi_name, NULL);
    377
    378	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
    379	return (AE_OK);
    380}
    381
    382/*******************************************************************************
    383 *
    384 * FUNCTION:    acpi_db_walk_for_predefined_names
    385 *
    386 * PARAMETERS:  Callback from walk_namespace
    387 *
    388 * RETURN:      Status
    389 *
    390 * DESCRIPTION: Detect and display predefined ACPI names (names that start with
    391 *              an underscore)
    392 *
    393 ******************************************************************************/
    394
    395static acpi_status
    396acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
    397				  u32 nesting_level,
    398				  void *context, void **return_value)
    399{
    400	struct acpi_namespace_node *node =
    401	    (struct acpi_namespace_node *)obj_handle;
    402	u32 *count = (u32 *)context;
    403	const union acpi_predefined_info *predefined;
    404	const union acpi_predefined_info *package = NULL;
    405	char *pathname;
    406	char string_buffer[48];
    407
    408	predefined = acpi_ut_match_predefined_method(node->name.ascii);
    409	if (!predefined) {
    410		return (AE_OK);
    411	}
    412
    413	pathname = acpi_ns_get_normalized_pathname(node, TRUE);
    414	if (!pathname) {
    415		return (AE_OK);
    416	}
    417
    418	/* If method returns a package, the info is in the next table entry */
    419
    420	if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
    421		package = predefined + 1;
    422	}
    423
    424	acpi_ut_get_expected_return_types(string_buffer,
    425					  predefined->info.expected_btypes);
    426
    427	acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname,
    428		       METHOD_GET_ARG_COUNT(predefined->info.argument_list),
    429		       string_buffer);
    430
    431	if (package) {
    432		acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
    433			       package->ret_info.type,
    434			       package->ret_info.object_type1,
    435			       package->ret_info.count1);
    436	}
    437
    438	acpi_os_printf("\n");
    439
    440	/* Check that the declared argument count matches the ACPI spec */
    441
    442	acpi_ns_check_acpi_compliance(pathname, node, predefined);
    443
    444	ACPI_FREE(pathname);
    445	(*count)++;
    446	return (AE_OK);
    447}
    448
    449/*******************************************************************************
    450 *
    451 * FUNCTION:    acpi_db_check_predefined_names
    452 *
    453 * PARAMETERS:  None
    454 *
    455 * RETURN:      None
    456 *
    457 * DESCRIPTION: Validate all predefined names in the namespace
    458 *
    459 ******************************************************************************/
    460
    461void acpi_db_check_predefined_names(void)
    462{
    463	u32 count = 0;
    464
    465	/* Search all nodes in namespace */
    466
    467	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    468				  ACPI_UINT32_MAX,
    469				  acpi_db_walk_for_predefined_names, NULL,
    470				  (void *)&count, NULL);
    471
    472	acpi_os_printf("Found %u predefined names in the namespace\n", count);
    473}
    474
    475/*******************************************************************************
    476 *
    477 * FUNCTION:    acpi_db_walk_for_object_counts
    478 *
    479 * PARAMETERS:  Callback from walk_namespace
    480 *
    481 * RETURN:      Status
    482 *
    483 * DESCRIPTION: Display short info about objects in the namespace
    484 *
    485 ******************************************************************************/
    486
    487static acpi_status
    488acpi_db_walk_for_object_counts(acpi_handle obj_handle,
    489			       u32 nesting_level,
    490			       void *context, void **return_value)
    491{
    492	struct acpi_object_info *info = (struct acpi_object_info *)context;
    493	struct acpi_namespace_node *node =
    494	    (struct acpi_namespace_node *)obj_handle;
    495
    496	if (node->type > ACPI_TYPE_NS_NODE_MAX) {
    497		acpi_os_printf("[%4.4s]: Unknown object type %X\n",
    498			       node->name.ascii, node->type);
    499	} else {
    500		info->types[node->type]++;
    501	}
    502
    503	return (AE_OK);
    504}
    505
    506/*******************************************************************************
    507 *
    508 * FUNCTION:    acpi_db_walk_for_fields
    509 *
    510 * PARAMETERS:  Callback from walk_namespace
    511 *
    512 * RETURN:      Status
    513 *
    514 * DESCRIPTION: Display short info about objects in the namespace
    515 *
    516 ******************************************************************************/
    517
    518static acpi_status
    519acpi_db_walk_for_fields(acpi_handle obj_handle,
    520			u32 nesting_level, void *context, void **return_value)
    521{
    522	union acpi_object *ret_value;
    523	struct acpi_region_walk_info *info =
    524	    (struct acpi_region_walk_info *)context;
    525	struct acpi_buffer buffer;
    526	acpi_status status;
    527	struct acpi_namespace_node *node = acpi_ns_validate_handle(obj_handle);
    528
    529	if (!node) {
    530		return (AE_OK);
    531	}
    532	if (node->object->field.region_obj->region.space_id !=
    533	    info->address_space_id) {
    534		return (AE_OK);
    535	}
    536
    537	info->count++;
    538
    539	/* Get and display the full pathname to this object */
    540
    541	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    542	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
    543	if (ACPI_FAILURE(status)) {
    544		acpi_os_printf("Could Not get pathname for object %p\n",
    545			       obj_handle);
    546		return (AE_OK);
    547	}
    548
    549	acpi_os_printf("%s ", (char *)buffer.pointer);
    550	ACPI_FREE(buffer.pointer);
    551
    552	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    553	acpi_evaluate_object(obj_handle, NULL, NULL, &buffer);
    554
    555	/*
    556	 * Since this is a field unit, surround the output in braces
    557	 */
    558	acpi_os_printf("{");
    559
    560	ret_value = (union acpi_object *)buffer.pointer;
    561	switch (ret_value->type) {
    562	case ACPI_TYPE_INTEGER:
    563
    564		acpi_os_printf("%8.8X%8.8X",
    565			       ACPI_FORMAT_UINT64(ret_value->integer.value));
    566		break;
    567
    568	case ACPI_TYPE_BUFFER:
    569
    570		acpi_ut_dump_buffer(ret_value->buffer.pointer,
    571				    ret_value->buffer.length,
    572				    DB_DISPLAY_DATA_ONLY | DB_BYTE_DISPLAY, 0);
    573		break;
    574
    575	default:
    576
    577		break;
    578	}
    579	acpi_os_printf("}\n");
    580
    581	ACPI_FREE(buffer.pointer);
    582
    583	return (AE_OK);
    584}
    585
    586/*******************************************************************************
    587 *
    588 * FUNCTION:    acpi_db_walk_for_specific_objects
    589 *
    590 * PARAMETERS:  Callback from walk_namespace
    591 *
    592 * RETURN:      Status
    593 *
    594 * DESCRIPTION: Display short info about objects in the namespace
    595 *
    596 ******************************************************************************/
    597
    598static acpi_status
    599acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
    600				  u32 nesting_level,
    601				  void *context, void **return_value)
    602{
    603	struct acpi_walk_info *info = (struct acpi_walk_info *)context;
    604	struct acpi_buffer buffer;
    605	acpi_status status;
    606
    607	info->count++;
    608
    609	/* Get and display the full pathname to this object */
    610
    611	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    612	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
    613	if (ACPI_FAILURE(status)) {
    614		acpi_os_printf("Could Not get pathname for object %p\n",
    615			       obj_handle);
    616		return (AE_OK);
    617	}
    618
    619	acpi_os_printf("%32s", (char *)buffer.pointer);
    620	ACPI_FREE(buffer.pointer);
    621
    622	/* Dump short info about the object */
    623
    624	(void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL);
    625	return (AE_OK);
    626}
    627
    628/*******************************************************************************
    629 *
    630 * FUNCTION:    acpi_db_display_objects
    631 *
    632 * PARAMETERS:  obj_type_arg        - Type of object to display
    633 *              display_count_arg   - Max depth to display
    634 *
    635 * RETURN:      None
    636 *
    637 * DESCRIPTION: Display objects in the namespace of the requested type
    638 *
    639 ******************************************************************************/
    640
    641acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
    642{
    643	struct acpi_walk_info info;
    644	acpi_object_type type;
    645	struct acpi_object_info *object_info;
    646	u32 i;
    647	u32 total_objects = 0;
    648
    649	/* No argument means display summary/count of all object types */
    650
    651	if (!obj_type_arg) {
    652		object_info =
    653		    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
    654
    655		/* Walk the namespace from the root */
    656
    657		(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    658					  ACPI_UINT32_MAX,
    659					  acpi_db_walk_for_object_counts, NULL,
    660					  (void *)object_info, NULL);
    661
    662		acpi_os_printf("\nSummary of namespace objects:\n\n");
    663
    664		for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
    665			acpi_os_printf("%8u %s\n", object_info->types[i],
    666				       acpi_ut_get_type_name(i));
    667
    668			total_objects += object_info->types[i];
    669		}
    670
    671		acpi_os_printf("\n%8u Total namespace objects\n\n",
    672			       total_objects);
    673
    674		ACPI_FREE(object_info);
    675		return (AE_OK);
    676	}
    677
    678	/* Get the object type */
    679
    680	type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
    681	if (type == ACPI_TYPE_NOT_FOUND) {
    682		acpi_os_printf("Invalid or unsupported argument\n");
    683		return (AE_OK);
    684	}
    685
    686	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
    687	acpi_os_printf
    688	    ("Objects of type [%s] defined in the current ACPI Namespace:\n",
    689	     acpi_ut_get_type_name(type));
    690
    691	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
    692
    693	info.count = 0;
    694	info.owner_id = ACPI_OWNER_ID_MAX;
    695	info.debug_level = ACPI_UINT32_MAX;
    696	info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
    697
    698	/* Walk the namespace from the root */
    699
    700	(void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
    701				  acpi_db_walk_for_specific_objects, NULL,
    702				  (void *)&info, NULL);
    703
    704	acpi_os_printf
    705	    ("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
    706	     info.count, acpi_ut_get_type_name(type));
    707
    708	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
    709	return (AE_OK);
    710}
    711
    712/*******************************************************************************
    713 *
    714 * FUNCTION:    acpi_db_display_fields
    715 *
    716 * PARAMETERS:  obj_type_arg        - Type of object to display
    717 *              display_count_arg   - Max depth to display
    718 *
    719 * RETURN:      None
    720 *
    721 * DESCRIPTION: Display objects in the namespace of the requested type
    722 *
    723 ******************************************************************************/
    724
    725acpi_status acpi_db_display_fields(u32 address_space_id)
    726{
    727	struct acpi_region_walk_info info;
    728
    729	info.count = 0;
    730	info.owner_id = ACPI_OWNER_ID_MAX;
    731	info.debug_level = ACPI_UINT32_MAX;
    732	info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
    733	info.address_space_id = address_space_id;
    734
    735	/* Walk the namespace from the root */
    736
    737	(void)acpi_walk_namespace(ACPI_TYPE_LOCAL_REGION_FIELD,
    738				  ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
    739				  acpi_db_walk_for_fields, NULL, (void *)&info,
    740				  NULL);
    741
    742	return (AE_OK);
    743}
    744
    745/*******************************************************************************
    746 *
    747 * FUNCTION:    acpi_db_integrity_walk
    748 *
    749 * PARAMETERS:  Callback from walk_namespace
    750 *
    751 * RETURN:      Status
    752 *
    753 * DESCRIPTION: Examine one NS node for valid values.
    754 *
    755 ******************************************************************************/
    756
    757static acpi_status
    758acpi_db_integrity_walk(acpi_handle obj_handle,
    759		       u32 nesting_level, void *context, void **return_value)
    760{
    761	struct acpi_integrity_info *info =
    762	    (struct acpi_integrity_info *)context;
    763	struct acpi_namespace_node *node =
    764	    (struct acpi_namespace_node *)obj_handle;
    765	union acpi_operand_object *object;
    766	u8 alias = TRUE;
    767
    768	info->nodes++;
    769
    770	/* Verify the NS node, and dereference aliases */
    771
    772	while (alias) {
    773		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
    774			acpi_os_printf
    775			    ("Invalid Descriptor Type for Node %p [%s] - "
    776			     "is %2.2X should be %2.2X\n", node,
    777			     acpi_ut_get_descriptor_name(node),
    778			     ACPI_GET_DESCRIPTOR_TYPE(node),
    779			     ACPI_DESC_TYPE_NAMED);
    780			return (AE_OK);
    781		}
    782
    783		if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
    784		    (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
    785			node = (struct acpi_namespace_node *)node->object;
    786		} else {
    787			alias = FALSE;
    788		}
    789	}
    790
    791	if (node->type > ACPI_TYPE_LOCAL_MAX) {
    792		acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
    793			       node, node->type);
    794		return (AE_OK);
    795	}
    796
    797	if (!acpi_ut_valid_nameseg(node->name.ascii)) {
    798		acpi_os_printf("Invalid AcpiName for Node %p\n", node);
    799		return (AE_OK);
    800	}
    801
    802	object = acpi_ns_get_attached_object(node);
    803	if (object) {
    804		info->objects++;
    805		if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
    806			acpi_os_printf
    807			    ("Invalid Descriptor Type for Object %p [%s]\n",
    808			     object, acpi_ut_get_descriptor_name(object));
    809		}
    810	}
    811
    812	return (AE_OK);
    813}
    814
    815/*******************************************************************************
    816 *
    817 * FUNCTION:    acpi_db_check_integrity
    818 *
    819 * PARAMETERS:  None
    820 *
    821 * RETURN:      None
    822 *
    823 * DESCRIPTION: Check entire namespace for data structure integrity
    824 *
    825 ******************************************************************************/
    826
    827void acpi_db_check_integrity(void)
    828{
    829	struct acpi_integrity_info info = { 0, 0 };
    830
    831	/* Search all nodes in namespace */
    832
    833	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    834				  ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
    835				  (void *)&info, NULL);
    836
    837	acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
    838		       info.nodes, info.objects);
    839}
    840
    841/*******************************************************************************
    842 *
    843 * FUNCTION:    acpi_db_walk_for_references
    844 *
    845 * PARAMETERS:  Callback from walk_namespace
    846 *
    847 * RETURN:      Status
    848 *
    849 * DESCRIPTION: Check if this namespace object refers to the target object
    850 *              that is passed in as the context value.
    851 *
    852 * Note: Currently doesn't check subobjects within the Node's object
    853 *
    854 ******************************************************************************/
    855
    856static acpi_status
    857acpi_db_walk_for_references(acpi_handle obj_handle,
    858			    u32 nesting_level,
    859			    void *context, void **return_value)
    860{
    861	union acpi_operand_object *obj_desc =
    862	    (union acpi_operand_object *)context;
    863	struct acpi_namespace_node *node =
    864	    (struct acpi_namespace_node *)obj_handle;
    865
    866	/* Check for match against the namespace node itself */
    867
    868	if (node == (void *)obj_desc) {
    869		acpi_os_printf("Object is a Node [%4.4s]\n",
    870			       acpi_ut_get_node_name(node));
    871	}
    872
    873	/* Check for match against the object attached to the node */
    874
    875	if (acpi_ns_get_attached_object(node) == obj_desc) {
    876		acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
    877			       node, acpi_ut_get_node_name(node));
    878	}
    879
    880	return (AE_OK);
    881}
    882
    883/*******************************************************************************
    884 *
    885 * FUNCTION:    acpi_db_find_references
    886 *
    887 * PARAMETERS:  object_arg      - String with hex value of the object
    888 *
    889 * RETURN:      None
    890 *
    891 * DESCRIPTION: Search namespace for all references to the input object
    892 *
    893 ******************************************************************************/
    894
    895void acpi_db_find_references(char *object_arg)
    896{
    897	union acpi_operand_object *obj_desc;
    898	acpi_size address;
    899
    900	/* Convert string to object pointer */
    901
    902	address = strtoul(object_arg, NULL, 16);
    903	obj_desc = ACPI_TO_POINTER(address);
    904
    905	/* Search all nodes in namespace */
    906
    907	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    908				  ACPI_UINT32_MAX, acpi_db_walk_for_references,
    909				  NULL, (void *)obj_desc, NULL);
    910}
    911
    912/*******************************************************************************
    913 *
    914 * FUNCTION:    acpi_db_bus_walk
    915 *
    916 * PARAMETERS:  Callback from walk_namespace
    917 *
    918 * RETURN:      Status
    919 *
    920 * DESCRIPTION: Display info about device objects that have a corresponding
    921 *              _PRT method.
    922 *
    923 ******************************************************************************/
    924
    925static acpi_status
    926acpi_db_bus_walk(acpi_handle obj_handle,
    927		 u32 nesting_level, void *context, void **return_value)
    928{
    929	struct acpi_namespace_node *node =
    930	    (struct acpi_namespace_node *)obj_handle;
    931	acpi_status status;
    932	struct acpi_buffer buffer;
    933	struct acpi_namespace_node *temp_node;
    934	struct acpi_device_info *info;
    935	u32 i;
    936
    937	if ((node->type != ACPI_TYPE_DEVICE) &&
    938	    (node->type != ACPI_TYPE_PROCESSOR)) {
    939		return (AE_OK);
    940	}
    941
    942	/* Exit if there is no _PRT under this device */
    943
    944	status = acpi_get_handle(node, METHOD_NAME__PRT,
    945				 ACPI_CAST_PTR(acpi_handle, &temp_node));
    946	if (ACPI_FAILURE(status)) {
    947		return (AE_OK);
    948	}
    949
    950	/* Get the full path to this device object */
    951
    952	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    953	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
    954	if (ACPI_FAILURE(status)) {
    955		acpi_os_printf("Could Not get pathname for object %p\n",
    956			       obj_handle);
    957		return (AE_OK);
    958	}
    959
    960	status = acpi_get_object_info(obj_handle, &info);
    961	if (ACPI_FAILURE(status)) {
    962		return (AE_OK);
    963	}
    964
    965	/* Display the full path */
    966
    967	acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
    968	ACPI_FREE(buffer.pointer);
    969
    970	if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
    971		acpi_os_printf(" - Is PCI Root Bridge");
    972	}
    973	acpi_os_printf("\n");
    974
    975	/* _PRT info */
    976
    977	acpi_os_printf("_PRT: %p\n", temp_node);
    978
    979	/* Dump _ADR, _HID, _UID, _CID */
    980
    981	if (info->valid & ACPI_VALID_ADR) {
    982		acpi_os_printf("_ADR: %8.8X%8.8X\n",
    983			       ACPI_FORMAT_UINT64(info->address));
    984	} else {
    985		acpi_os_printf("_ADR: <Not Present>\n");
    986	}
    987
    988	if (info->valid & ACPI_VALID_HID) {
    989		acpi_os_printf("_HID: %s\n", info->hardware_id.string);
    990	} else {
    991		acpi_os_printf("_HID: <Not Present>\n");
    992	}
    993
    994	if (info->valid & ACPI_VALID_UID) {
    995		acpi_os_printf("_UID: %s\n", info->unique_id.string);
    996	} else {
    997		acpi_os_printf("_UID: <Not Present>\n");
    998	}
    999
   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
   1025void 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}