mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
f5c1e1c5a6
ACPICA commit b2294cae776f5a66a7697414b21949d307e6856f This patch removes unwanted spaces for typedef. This solution doesn't cover function types. Note that the linuxize result of this commit is very giant and should have many conflicts against the current Linux upstream. Thus it is required to modify the linuxize result of this commit and the commits around it manually in order to have them merged to the Linux upstream. Since this is very costy, we should do this only once, and if we can't ensure to do this only once, we need to revert the Linux code to the wrong indentation result before merging the linuxize result of this commit. Lv Zheng. Link: https://github.com/acpica/acpica/commit/b2294cae Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
948 lines
26 KiB
C
948 lines
26 KiB
C
/*******************************************************************************
|
|
*
|
|
* Module Name: dbnames - Debugger commands for the acpi namespace
|
|
*
|
|
******************************************************************************/
|
|
|
|
/*
|
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions, and the following disclaimer,
|
|
* without modification.
|
|
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
|
* substantially similar to the "NO WARRANTY" disclaimer below
|
|
* ("Disclaimer") and any redistribution must be conditioned upon
|
|
* including a substantially similar Disclaimer requirement for further
|
|
* binary redistribution.
|
|
* 3. Neither the names of the above-listed copyright holders nor the names
|
|
* of any contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* Alternatively, this software may be distributed under the terms of the
|
|
* GNU General Public License ("GPL") version 2 as published by the Free
|
|
* Software Foundation.
|
|
*
|
|
* NO WARRANTY
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGES.
|
|
*/
|
|
|
|
#include <acpi/acpi.h>
|
|
#include "accommon.h"
|
|
#include "acnamesp.h"
|
|
#include "acdebug.h"
|
|
#include "acpredef.h"
|
|
|
|
#define _COMPONENT ACPI_CA_DEBUGGER
|
|
ACPI_MODULE_NAME("dbnames")
|
|
|
|
/* Local prototypes */
|
|
static acpi_status
|
|
acpi_db_walk_and_match_name(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value);
|
|
|
|
static acpi_status
|
|
acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value);
|
|
|
|
static acpi_status
|
|
acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value);
|
|
|
|
static acpi_status
|
|
acpi_db_walk_for_object_counts(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value);
|
|
|
|
static acpi_status
|
|
acpi_db_integrity_walk(acpi_handle obj_handle,
|
|
u32 nesting_level, void *context, void **return_value);
|
|
|
|
static acpi_status
|
|
acpi_db_walk_for_references(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value);
|
|
|
|
static acpi_status
|
|
acpi_db_bus_walk(acpi_handle obj_handle,
|
|
u32 nesting_level, void *context, void **return_value);
|
|
|
|
/*
|
|
* Arguments for the Objects command
|
|
* These object types map directly to the ACPI_TYPES
|
|
*/
|
|
static struct acpi_db_argument_info acpi_db_object_types[] = {
|
|
{"ANY"},
|
|
{"INTEGERS"},
|
|
{"STRINGS"},
|
|
{"BUFFERS"},
|
|
{"PACKAGES"},
|
|
{"FIELDS"},
|
|
{"DEVICES"},
|
|
{"EVENTS"},
|
|
{"METHODS"},
|
|
{"MUTEXES"},
|
|
{"REGIONS"},
|
|
{"POWERRESOURCES"},
|
|
{"PROCESSORS"},
|
|
{"THERMALZONES"},
|
|
{"BUFFERFIELDS"},
|
|
{"DDBHANDLES"},
|
|
{"DEBUG"},
|
|
{"REGIONFIELDS"},
|
|
{"BANKFIELDS"},
|
|
{"INDEXFIELDS"},
|
|
{"REFERENCES"},
|
|
{"ALIASES"},
|
|
{"METHODALIASES"},
|
|
{"NOTIFY"},
|
|
{"ADDRESSHANDLER"},
|
|
{"RESOURCE"},
|
|
{"RESOURCEFIELD"},
|
|
{"SCOPES"},
|
|
{NULL} /* Must be null terminated */
|
|
};
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_set_scope
|
|
*
|
|
* PARAMETERS: name - New scope path
|
|
*
|
|
* RETURN: Status
|
|
*
|
|
* DESCRIPTION: Set the "current scope" as maintained by this utility.
|
|
* The scope is used as a prefix to ACPI paths.
|
|
*
|
|
******************************************************************************/
|
|
|
|
void acpi_db_set_scope(char *name)
|
|
{
|
|
acpi_status status;
|
|
struct acpi_namespace_node *node;
|
|
|
|
if (!name || name[0] == 0) {
|
|
acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf);
|
|
return;
|
|
}
|
|
|
|
acpi_db_prep_namestring(name);
|
|
|
|
if (ACPI_IS_ROOT_PREFIX(name[0])) {
|
|
|
|
/* Validate new scope from the root */
|
|
|
|
status = acpi_ns_get_node(acpi_gbl_root_node, name,
|
|
ACPI_NS_NO_UPSEARCH, &node);
|
|
if (ACPI_FAILURE(status)) {
|
|
goto error_exit;
|
|
}
|
|
|
|
acpi_gbl_db_scope_buf[0] = 0;
|
|
} else {
|
|
/* Validate new scope relative to old scope */
|
|
|
|
status = acpi_ns_get_node(acpi_gbl_db_scope_node, name,
|
|
ACPI_NS_NO_UPSEARCH, &node);
|
|
if (ACPI_FAILURE(status)) {
|
|
goto error_exit;
|
|
}
|
|
}
|
|
|
|
/* Build the final pathname */
|
|
|
|
if (acpi_ut_safe_strcat
|
|
(acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) {
|
|
status = AE_BUFFER_OVERFLOW;
|
|
goto error_exit;
|
|
}
|
|
|
|
if (acpi_ut_safe_strcat
|
|
(acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) {
|
|
status = AE_BUFFER_OVERFLOW;
|
|
goto error_exit;
|
|
}
|
|
|
|
acpi_gbl_db_scope_node = node;
|
|
acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf);
|
|
return;
|
|
|
|
error_exit:
|
|
|
|
acpi_os_printf("Could not attach scope: %s, %s\n",
|
|
name, acpi_format_exception(status));
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_dump_namespace
|
|
*
|
|
* PARAMETERS: start_arg - Node to begin namespace dump
|
|
* depth_arg - Maximum tree depth to be dumped
|
|
*
|
|
* RETURN: None
|
|
*
|
|
* DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
|
|
* with type and other information.
|
|
*
|
|
******************************************************************************/
|
|
|
|
void acpi_db_dump_namespace(char *start_arg, char *depth_arg)
|
|
{
|
|
acpi_handle subtree_entry = acpi_gbl_root_node;
|
|
u32 max_depth = ACPI_UINT32_MAX;
|
|
|
|
/* No argument given, just start at the root and dump entire namespace */
|
|
|
|
if (start_arg) {
|
|
subtree_entry = acpi_db_convert_to_node(start_arg);
|
|
if (!subtree_entry) {
|
|
return;
|
|
}
|
|
|
|
/* Now we can check for the depth argument */
|
|
|
|
if (depth_arg) {
|
|
max_depth = strtoul(depth_arg, NULL, 0);
|
|
}
|
|
}
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
|
|
acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
|
|
((struct acpi_namespace_node *)subtree_entry)->name.
|
|
ascii, subtree_entry);
|
|
|
|
/* Display the subtree */
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
|
|
acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
|
|
ACPI_OWNER_ID_MAX, subtree_entry);
|
|
acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_dump_namespace_paths
|
|
*
|
|
* PARAMETERS: None
|
|
*
|
|
* RETURN: None
|
|
*
|
|
* DESCRIPTION: Dump entire namespace with full object pathnames and object
|
|
* type information. Alternative to "namespace" command.
|
|
*
|
|
******************************************************************************/
|
|
|
|
void acpi_db_dump_namespace_paths(void)
|
|
{
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
|
|
acpi_os_printf("ACPI Namespace (from root):\n");
|
|
|
|
/* Display the entire namespace */
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
|
|
acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
|
|
ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX,
|
|
acpi_gbl_root_node);
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_dump_namespace_by_owner
|
|
*
|
|
* PARAMETERS: owner_arg - Owner ID whose nodes will be displayed
|
|
* depth_arg - Maximum tree depth to be dumped
|
|
*
|
|
* RETURN: None
|
|
*
|
|
* DESCRIPTION: Dump elements of the namespace that are owned by the owner_id.
|
|
*
|
|
******************************************************************************/
|
|
|
|
void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg)
|
|
{
|
|
acpi_handle subtree_entry = acpi_gbl_root_node;
|
|
u32 max_depth = ACPI_UINT32_MAX;
|
|
acpi_owner_id owner_id;
|
|
|
|
owner_id = (acpi_owner_id)strtoul(owner_arg, NULL, 0);
|
|
|
|
/* Now we can check for the depth argument */
|
|
|
|
if (depth_arg) {
|
|
max_depth = strtoul(depth_arg, NULL, 0);
|
|
}
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
|
|
acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id);
|
|
|
|
/* Display the subtree */
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
|
|
acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
|
|
owner_id, subtree_entry);
|
|
acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_walk_and_match_name
|
|
*
|
|
* PARAMETERS: Callback from walk_namespace
|
|
*
|
|
* RETURN: Status
|
|
*
|
|
* DESCRIPTION: Find a particular name/names within the namespace. Wildcards
|
|
* are supported -- '?' matches any character.
|
|
*
|
|
******************************************************************************/
|
|
|
|
static acpi_status
|
|
acpi_db_walk_and_match_name(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value)
|
|
{
|
|
acpi_status status;
|
|
char *requested_name = (char *)context;
|
|
u32 i;
|
|
struct acpi_buffer buffer;
|
|
struct acpi_walk_info info;
|
|
|
|
/* Check for a name match */
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
/* Wildcard support */
|
|
|
|
if ((requested_name[i] != '?') &&
|
|
(requested_name[i] != ((struct acpi_namespace_node *)
|
|
obj_handle)->name.ascii[i])) {
|
|
|
|
/* No match, just exit */
|
|
|
|
return (AE_OK);
|
|
}
|
|
}
|
|
|
|
/* Get the full pathname to this object */
|
|
|
|
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
|
|
status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
|
|
if (ACPI_FAILURE(status)) {
|
|
acpi_os_printf("Could Not get pathname for object %p\n",
|
|
obj_handle);
|
|
} else {
|
|
info.owner_id = ACPI_OWNER_ID_MAX;
|
|
info.debug_level = ACPI_UINT32_MAX;
|
|
info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
|
|
|
|
acpi_os_printf("%32s", (char *)buffer.pointer);
|
|
(void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info,
|
|
NULL);
|
|
ACPI_FREE(buffer.pointer);
|
|
}
|
|
|
|
return (AE_OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_find_name_in_namespace
|
|
*
|
|
* PARAMETERS: name_arg - The 4-character ACPI name to find.
|
|
* wildcards are supported.
|
|
*
|
|
* RETURN: None
|
|
*
|
|
* DESCRIPTION: Search the namespace for a given name (with wildcards)
|
|
*
|
|
******************************************************************************/
|
|
|
|
acpi_status acpi_db_find_name_in_namespace(char *name_arg)
|
|
{
|
|
char acpi_name[5] = "____";
|
|
char *acpi_name_ptr = acpi_name;
|
|
|
|
if (strlen(name_arg) > ACPI_NAME_SIZE) {
|
|
acpi_os_printf("Name must be no longer than 4 characters\n");
|
|
return (AE_OK);
|
|
}
|
|
|
|
/* Pad out name with underscores as necessary to create a 4-char name */
|
|
|
|
acpi_ut_strupr(name_arg);
|
|
while (*name_arg) {
|
|
*acpi_name_ptr = *name_arg;
|
|
acpi_name_ptr++;
|
|
name_arg++;
|
|
}
|
|
|
|
/* Walk the namespace from the root */
|
|
|
|
(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
|
|
ACPI_UINT32_MAX, acpi_db_walk_and_match_name,
|
|
NULL, acpi_name, NULL);
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
|
|
return (AE_OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_walk_for_predefined_names
|
|
*
|
|
* PARAMETERS: Callback from walk_namespace
|
|
*
|
|
* RETURN: Status
|
|
*
|
|
* DESCRIPTION: Detect and display predefined ACPI names (names that start with
|
|
* an underscore)
|
|
*
|
|
******************************************************************************/
|
|
|
|
static acpi_status
|
|
acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value)
|
|
{
|
|
struct acpi_namespace_node *node =
|
|
(struct acpi_namespace_node *)obj_handle;
|
|
u32 *count = (u32 *)context;
|
|
const union acpi_predefined_info *predefined;
|
|
const union acpi_predefined_info *package = NULL;
|
|
char *pathname;
|
|
char string_buffer[48];
|
|
|
|
predefined = acpi_ut_match_predefined_method(node->name.ascii);
|
|
if (!predefined) {
|
|
return (AE_OK);
|
|
}
|
|
|
|
pathname = acpi_ns_get_normalized_pathname(node, TRUE);
|
|
if (!pathname) {
|
|
return (AE_OK);
|
|
}
|
|
|
|
/* If method returns a package, the info is in the next table entry */
|
|
|
|
if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
|
|
package = predefined + 1;
|
|
}
|
|
|
|
acpi_ut_get_expected_return_types(string_buffer,
|
|
predefined->info.expected_btypes);
|
|
|
|
acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname,
|
|
METHOD_GET_ARG_COUNT(predefined->info.argument_list),
|
|
string_buffer);
|
|
|
|
if (package) {
|
|
acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
|
|
package->ret_info.type,
|
|
package->ret_info.object_type1,
|
|
package->ret_info.count1);
|
|
}
|
|
|
|
acpi_os_printf("\n");
|
|
|
|
/* Check that the declared argument count matches the ACPI spec */
|
|
|
|
acpi_ns_check_acpi_compliance(pathname, node, predefined);
|
|
|
|
ACPI_FREE(pathname);
|
|
(*count)++;
|
|
return (AE_OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_check_predefined_names
|
|
*
|
|
* PARAMETERS: None
|
|
*
|
|
* RETURN: None
|
|
*
|
|
* DESCRIPTION: Validate all predefined names in the namespace
|
|
*
|
|
******************************************************************************/
|
|
|
|
void acpi_db_check_predefined_names(void)
|
|
{
|
|
u32 count = 0;
|
|
|
|
/* Search all nodes in namespace */
|
|
|
|
(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
|
|
ACPI_UINT32_MAX,
|
|
acpi_db_walk_for_predefined_names, NULL,
|
|
(void *)&count, NULL);
|
|
|
|
acpi_os_printf("Found %u predefined names in the namespace\n", count);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_walk_for_object_counts
|
|
*
|
|
* PARAMETERS: Callback from walk_namespace
|
|
*
|
|
* RETURN: Status
|
|
*
|
|
* DESCRIPTION: Display short info about objects in the namespace
|
|
*
|
|
******************************************************************************/
|
|
|
|
static acpi_status
|
|
acpi_db_walk_for_object_counts(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value)
|
|
{
|
|
struct acpi_object_info *info = (struct acpi_object_info *)context;
|
|
struct acpi_namespace_node *node =
|
|
(struct acpi_namespace_node *)obj_handle;
|
|
|
|
if (node->type > ACPI_TYPE_NS_NODE_MAX) {
|
|
acpi_os_printf("[%4.4s]: Unknown object type %X\n",
|
|
node->name.ascii, node->type);
|
|
} else {
|
|
info->types[node->type]++;
|
|
}
|
|
|
|
return (AE_OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_walk_for_specific_objects
|
|
*
|
|
* PARAMETERS: Callback from walk_namespace
|
|
*
|
|
* RETURN: Status
|
|
*
|
|
* DESCRIPTION: Display short info about objects in the namespace
|
|
*
|
|
******************************************************************************/
|
|
|
|
static acpi_status
|
|
acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value)
|
|
{
|
|
struct acpi_walk_info *info = (struct acpi_walk_info *)context;
|
|
struct acpi_buffer buffer;
|
|
acpi_status status;
|
|
|
|
info->count++;
|
|
|
|
/* Get and display the full pathname to this object */
|
|
|
|
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
|
|
status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
|
|
if (ACPI_FAILURE(status)) {
|
|
acpi_os_printf("Could Not get pathname for object %p\n",
|
|
obj_handle);
|
|
return (AE_OK);
|
|
}
|
|
|
|
acpi_os_printf("%32s", (char *)buffer.pointer);
|
|
ACPI_FREE(buffer.pointer);
|
|
|
|
/* Dump short info about the object */
|
|
|
|
(void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL);
|
|
return (AE_OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_display_objects
|
|
*
|
|
* PARAMETERS: obj_type_arg - Type of object to display
|
|
* display_count_arg - Max depth to display
|
|
*
|
|
* RETURN: None
|
|
*
|
|
* DESCRIPTION: Display objects in the namespace of the requested type
|
|
*
|
|
******************************************************************************/
|
|
|
|
acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
|
|
{
|
|
struct acpi_walk_info info;
|
|
acpi_object_type type;
|
|
struct acpi_object_info *object_info;
|
|
u32 i;
|
|
u32 total_objects = 0;
|
|
|
|
/* No argument means display summary/count of all object types */
|
|
|
|
if (!obj_type_arg) {
|
|
object_info =
|
|
ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
|
|
|
|
/* Walk the namespace from the root */
|
|
|
|
(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
|
|
ACPI_UINT32_MAX,
|
|
acpi_db_walk_for_object_counts, NULL,
|
|
(void *)object_info, NULL);
|
|
|
|
acpi_os_printf("\nSummary of namespace objects:\n\n");
|
|
|
|
for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
|
|
acpi_os_printf("%8u %s\n", object_info->types[i],
|
|
acpi_ut_get_type_name(i));
|
|
|
|
total_objects += object_info->types[i];
|
|
}
|
|
|
|
acpi_os_printf("\n%8u Total namespace objects\n\n",
|
|
total_objects);
|
|
|
|
ACPI_FREE(object_info);
|
|
return (AE_OK);
|
|
}
|
|
|
|
/* Get the object type */
|
|
|
|
type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
|
|
if (type == ACPI_TYPE_NOT_FOUND) {
|
|
acpi_os_printf("Invalid or unsupported argument\n");
|
|
return (AE_OK);
|
|
}
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
|
|
acpi_os_printf
|
|
("Objects of type [%s] defined in the current ACPI Namespace:\n",
|
|
acpi_ut_get_type_name(type));
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
|
|
|
|
info.count = 0;
|
|
info.owner_id = ACPI_OWNER_ID_MAX;
|
|
info.debug_level = ACPI_UINT32_MAX;
|
|
info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
|
|
|
|
/* Walk the namespace from the root */
|
|
|
|
(void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
|
|
acpi_db_walk_for_specific_objects, NULL,
|
|
(void *)&info, NULL);
|
|
|
|
acpi_os_printf
|
|
("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
|
|
info.count, acpi_ut_get_type_name(type));
|
|
|
|
acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
|
|
return (AE_OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_integrity_walk
|
|
*
|
|
* PARAMETERS: Callback from walk_namespace
|
|
*
|
|
* RETURN: Status
|
|
*
|
|
* DESCRIPTION: Examine one NS node for valid values.
|
|
*
|
|
******************************************************************************/
|
|
|
|
static acpi_status
|
|
acpi_db_integrity_walk(acpi_handle obj_handle,
|
|
u32 nesting_level, void *context, void **return_value)
|
|
{
|
|
struct acpi_integrity_info *info =
|
|
(struct acpi_integrity_info *)context;
|
|
struct acpi_namespace_node *node =
|
|
(struct acpi_namespace_node *)obj_handle;
|
|
union acpi_operand_object *object;
|
|
u8 alias = TRUE;
|
|
|
|
info->nodes++;
|
|
|
|
/* Verify the NS node, and dereference aliases */
|
|
|
|
while (alias) {
|
|
if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
|
|
acpi_os_printf
|
|
("Invalid Descriptor Type for Node %p [%s] - "
|
|
"is %2.2X should be %2.2X\n", node,
|
|
acpi_ut_get_descriptor_name(node),
|
|
ACPI_GET_DESCRIPTOR_TYPE(node),
|
|
ACPI_DESC_TYPE_NAMED);
|
|
return (AE_OK);
|
|
}
|
|
|
|
if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
|
|
(node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
|
|
node = (struct acpi_namespace_node *)node->object;
|
|
} else {
|
|
alias = FALSE;
|
|
}
|
|
}
|
|
|
|
if (node->type > ACPI_TYPE_LOCAL_MAX) {
|
|
acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
|
|
node, node->type);
|
|
return (AE_OK);
|
|
}
|
|
|
|
if (!acpi_ut_valid_acpi_name(node->name.ascii)) {
|
|
acpi_os_printf("Invalid AcpiName for Node %p\n", node);
|
|
return (AE_OK);
|
|
}
|
|
|
|
object = acpi_ns_get_attached_object(node);
|
|
if (object) {
|
|
info->objects++;
|
|
if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
|
|
acpi_os_printf
|
|
("Invalid Descriptor Type for Object %p [%s]\n",
|
|
object, acpi_ut_get_descriptor_name(object));
|
|
}
|
|
}
|
|
|
|
return (AE_OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_check_integrity
|
|
*
|
|
* PARAMETERS: None
|
|
*
|
|
* RETURN: None
|
|
*
|
|
* DESCRIPTION: Check entire namespace for data structure integrity
|
|
*
|
|
******************************************************************************/
|
|
|
|
void acpi_db_check_integrity(void)
|
|
{
|
|
struct acpi_integrity_info info = { 0, 0 };
|
|
|
|
/* Search all nodes in namespace */
|
|
|
|
(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
|
|
ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
|
|
(void *)&info, NULL);
|
|
|
|
acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
|
|
info.nodes, info.objects);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_walk_for_references
|
|
*
|
|
* PARAMETERS: Callback from walk_namespace
|
|
*
|
|
* RETURN: Status
|
|
*
|
|
* DESCRIPTION: Check if this namespace object refers to the target object
|
|
* that is passed in as the context value.
|
|
*
|
|
* Note: Currently doesn't check subobjects within the Node's object
|
|
*
|
|
******************************************************************************/
|
|
|
|
static acpi_status
|
|
acpi_db_walk_for_references(acpi_handle obj_handle,
|
|
u32 nesting_level,
|
|
void *context, void **return_value)
|
|
{
|
|
union acpi_operand_object *obj_desc =
|
|
(union acpi_operand_object *)context;
|
|
struct acpi_namespace_node *node =
|
|
(struct acpi_namespace_node *)obj_handle;
|
|
|
|
/* Check for match against the namespace node itself */
|
|
|
|
if (node == (void *)obj_desc) {
|
|
acpi_os_printf("Object is a Node [%4.4s]\n",
|
|
acpi_ut_get_node_name(node));
|
|
}
|
|
|
|
/* Check for match against the object attached to the node */
|
|
|
|
if (acpi_ns_get_attached_object(node) == obj_desc) {
|
|
acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
|
|
node, acpi_ut_get_node_name(node));
|
|
}
|
|
|
|
return (AE_OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_find_references
|
|
*
|
|
* PARAMETERS: object_arg - String with hex value of the object
|
|
*
|
|
* RETURN: None
|
|
*
|
|
* DESCRIPTION: Search namespace for all references to the input object
|
|
*
|
|
******************************************************************************/
|
|
|
|
void acpi_db_find_references(char *object_arg)
|
|
{
|
|
union acpi_operand_object *obj_desc;
|
|
acpi_size address;
|
|
|
|
/* Convert string to object pointer */
|
|
|
|
address = strtoul(object_arg, NULL, 16);
|
|
obj_desc = ACPI_TO_POINTER(address);
|
|
|
|
/* Search all nodes in namespace */
|
|
|
|
(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
|
|
ACPI_UINT32_MAX, acpi_db_walk_for_references,
|
|
NULL, (void *)obj_desc, NULL);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_bus_walk
|
|
*
|
|
* PARAMETERS: Callback from walk_namespace
|
|
*
|
|
* RETURN: Status
|
|
*
|
|
* DESCRIPTION: Display info about device objects that have a corresponding
|
|
* _PRT method.
|
|
*
|
|
******************************************************************************/
|
|
|
|
static acpi_status
|
|
acpi_db_bus_walk(acpi_handle obj_handle,
|
|
u32 nesting_level, void *context, void **return_value)
|
|
{
|
|
struct acpi_namespace_node *node =
|
|
(struct acpi_namespace_node *)obj_handle;
|
|
acpi_status status;
|
|
struct acpi_buffer buffer;
|
|
struct acpi_namespace_node *temp_node;
|
|
struct acpi_device_info *info;
|
|
u32 i;
|
|
|
|
if ((node->type != ACPI_TYPE_DEVICE) &&
|
|
(node->type != ACPI_TYPE_PROCESSOR)) {
|
|
return (AE_OK);
|
|
}
|
|
|
|
/* Exit if there is no _PRT under this device */
|
|
|
|
status = acpi_get_handle(node, METHOD_NAME__PRT,
|
|
ACPI_CAST_PTR(acpi_handle, &temp_node));
|
|
if (ACPI_FAILURE(status)) {
|
|
return (AE_OK);
|
|
}
|
|
|
|
/* Get the full path to this device object */
|
|
|
|
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
|
|
status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
|
|
if (ACPI_FAILURE(status)) {
|
|
acpi_os_printf("Could Not get pathname for object %p\n",
|
|
obj_handle);
|
|
return (AE_OK);
|
|
}
|
|
|
|
status = acpi_get_object_info(obj_handle, &info);
|
|
if (ACPI_FAILURE(status)) {
|
|
return (AE_OK);
|
|
}
|
|
|
|
/* Display the full path */
|
|
|
|
acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
|
|
ACPI_FREE(buffer.pointer);
|
|
|
|
if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
|
|
acpi_os_printf(" - Is PCI Root Bridge");
|
|
}
|
|
acpi_os_printf("\n");
|
|
|
|
/* _PRT info */
|
|
|
|
acpi_os_printf("_PRT: %p\n", temp_node);
|
|
|
|
/* Dump _ADR, _HID, _UID, _CID */
|
|
|
|
if (info->valid & ACPI_VALID_ADR) {
|
|
acpi_os_printf("_ADR: %8.8X%8.8X\n",
|
|
ACPI_FORMAT_UINT64(info->address));
|
|
} else {
|
|
acpi_os_printf("_ADR: <Not Present>\n");
|
|
}
|
|
|
|
if (info->valid & ACPI_VALID_HID) {
|
|
acpi_os_printf("_HID: %s\n", info->hardware_id.string);
|
|
} else {
|
|
acpi_os_printf("_HID: <Not Present>\n");
|
|
}
|
|
|
|
if (info->valid & ACPI_VALID_UID) {
|
|
acpi_os_printf("_UID: %s\n", info->unique_id.string);
|
|
} else {
|
|
acpi_os_printf("_UID: <Not Present>\n");
|
|
}
|
|
|
|
if (info->valid & ACPI_VALID_CID) {
|
|
for (i = 0; i < info->compatible_id_list.count; i++) {
|
|
acpi_os_printf("_CID: %s\n",
|
|
info->compatible_id_list.ids[i].string);
|
|
}
|
|
} else {
|
|
acpi_os_printf("_CID: <Not Present>\n");
|
|
}
|
|
|
|
ACPI_FREE(info);
|
|
return (AE_OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_db_get_bus_info
|
|
*
|
|
* PARAMETERS: None
|
|
*
|
|
* RETURN: None
|
|
*
|
|
* DESCRIPTION: Display info about system busses.
|
|
*
|
|
******************************************************************************/
|
|
|
|
void acpi_db_get_bus_info(void)
|
|
{
|
|
/* Search all nodes in namespace */
|
|
|
|
(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
|
|
ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL,
|
|
NULL);
|
|
}
|