225 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: dsinit - Object initialization namespace walk5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12#include "acdispat.h"13#include "acnamesp.h"14#include "actables.h"15#include "acinterp.h"16 17#define _COMPONENT ACPI_DISPATCHER18ACPI_MODULE_NAME("dsinit")19 20/* Local prototypes */21static acpi_status22acpi_ds_init_one_object(acpi_handle obj_handle,23 u32 level, void *context, void **return_value);24 25/*******************************************************************************26 *27 * FUNCTION: acpi_ds_init_one_object28 *29 * PARAMETERS: obj_handle - Node for the object30 * level - Current nesting level31 * context - Points to a init info struct32 * return_value - Not used33 *34 * RETURN: Status35 *36 * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object37 * within the namespace.38 *39 * Currently, the only objects that require initialization are:40 * 1) Methods41 * 2) Operation Regions42 *43 ******************************************************************************/44 45static acpi_status46acpi_ds_init_one_object(acpi_handle obj_handle,47 u32 level, void *context, void **return_value)48{49 struct acpi_init_walk_info *info =50 (struct acpi_init_walk_info *)context;51 struct acpi_namespace_node *node =52 (struct acpi_namespace_node *)obj_handle;53 acpi_status status;54 union acpi_operand_object *obj_desc;55 56 ACPI_FUNCTION_ENTRY();57 58 /*59 * We are only interested in NS nodes owned by the table that60 * was just loaded61 */62 if (node->owner_id != info->owner_id) {63 return (AE_OK);64 }65 66 info->object_count++;67 68 /* And even then, we are only interested in a few object types */69 70 switch (acpi_ns_get_type(obj_handle)) {71 case ACPI_TYPE_REGION:72 73 status = acpi_ds_initialize_region(obj_handle);74 if (ACPI_FAILURE(status)) {75 ACPI_EXCEPTION((AE_INFO, status,76 "During Region initialization %p [%4.4s]",77 obj_handle,78 acpi_ut_get_node_name(obj_handle)));79 }80 81 info->op_region_count++;82 break;83 84 case ACPI_TYPE_METHOD:85 /*86 * Auto-serialization support. We will examine each method that is87 * not_serialized to determine if it creates any Named objects. If88 * it does, it will be marked serialized to prevent problems if89 * the method is entered by two or more threads and an attempt is90 * made to create the same named object twice -- which results in91 * an AE_ALREADY_EXISTS exception and method abort.92 */93 info->method_count++;94 obj_desc = acpi_ns_get_attached_object(node);95 if (!obj_desc) {96 break;97 }98 99 /* Ignore if already serialized */100 101 if (obj_desc->method.info_flags & ACPI_METHOD_SERIALIZED) {102 info->serial_method_count++;103 break;104 }105 106 if (acpi_gbl_auto_serialize_methods) {107 108 /* Parse/scan method and serialize it if necessary */109 110 acpi_ds_auto_serialize_method(node, obj_desc);111 if (obj_desc->method.112 info_flags & ACPI_METHOD_SERIALIZED) {113 114 /* Method was just converted to Serialized */115 116 info->serial_method_count++;117 info->serialized_method_count++;118 break;119 }120 }121 122 info->non_serial_method_count++;123 break;124 125 case ACPI_TYPE_DEVICE:126 127 info->device_count++;128 break;129 130 default:131 132 break;133 }134 135 /*136 * We ignore errors from above, and always return OK, since137 * we don't want to abort the walk on a single error.138 */139 return (AE_OK);140}141 142/*******************************************************************************143 *144 * FUNCTION: acpi_ds_initialize_objects145 *146 * PARAMETERS: table_desc - Descriptor for parent ACPI table147 * start_node - Root of subtree to be initialized.148 *149 * RETURN: Status150 *151 * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any152 * necessary initialization on the objects found therein153 *154 ******************************************************************************/155 156acpi_status157acpi_ds_initialize_objects(u32 table_index,158 struct acpi_namespace_node *start_node)159{160 acpi_status status;161 struct acpi_init_walk_info info;162 struct acpi_table_header *table;163 acpi_owner_id owner_id;164 165 ACPI_FUNCTION_TRACE(ds_initialize_objects);166 167 status = acpi_tb_get_owner_id(table_index, &owner_id);168 if (ACPI_FAILURE(status)) {169 return_ACPI_STATUS(status);170 }171 172 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,173 "**** Starting initialization of namespace objects ****\n"));174 175 /* Set all init info to zero */176 177 memset(&info, 0, sizeof(struct acpi_init_walk_info));178 179 info.owner_id = owner_id;180 info.table_index = table_index;181 182 /* Walk entire namespace from the supplied root */183 184 /*185 * We don't use acpi_walk_namespace since we do not want to acquire186 * the namespace reader lock.187 */188 status =189 acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,190 ACPI_NS_WALK_NO_UNLOCK,191 acpi_ds_init_one_object, NULL, &info, NULL);192 if (ACPI_FAILURE(status)) {193 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));194 }195 196 status = acpi_get_table_by_index(table_index, &table);197 if (ACPI_FAILURE(status)) {198 return_ACPI_STATUS(status);199 }200 201 /* DSDT is always the first AML table */202 203 if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT)) {204 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,205 "\nACPI table initialization:\n"));206 }207 208 /* Summary of objects initialized */209 210 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,211 "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, "212 "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n",213 table->signature, table->oem_table_id, owner_id,214 info.object_count, info.device_count,215 info.op_region_count, info.method_count,216 info.serial_method_count,217 info.non_serial_method_count,218 info.serialized_method_count));219 220 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n",221 info.method_count, info.op_region_count));222 223 return_ACPI_STATUS(AE_OK);224}225