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

dsinit.c (6183B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: dsinit - Object initialization namespace walk
      5 *
      6 * Copyright (C) 2000 - 2022, 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_DISPATCHER
     18ACPI_MODULE_NAME("dsinit")
     19
     20/* Local prototypes */
     21static acpi_status
     22acpi_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_object
     28 *
     29 * PARAMETERS:  obj_handle      - Node for the object
     30 *              level           - Current nesting level
     31 *              context         - Points to a init info struct
     32 *              return_value    - Not used
     33 *
     34 * RETURN:      Status
     35 *
     36 * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object
     37 *              within the namespace.
     38 *
     39 *              Currently, the only objects that require initialization are:
     40 *              1) Methods
     41 *              2) Operation Regions
     42 *
     43 ******************************************************************************/
     44
     45static acpi_status
     46acpi_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 that
     60	 * was just loaded
     61	 */
     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 is
     87		 * not_serialized to determine if it creates any Named objects. If
     88		 * it does, it will be marked serialized to prevent problems if
     89		 * the method is entered by two or more threads and an attempt is
     90		 * made to create the same named object twice -- which results in
     91		 * 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, since
    137	 * 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_objects
    145 *
    146 * PARAMETERS:  table_desc      - Descriptor for parent ACPI table
    147 *              start_node      - Root of subtree to be initialized.
    148 *
    149 * RETURN:      Status
    150 *
    151 * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
    152 *              necessary initialization on the objects found therein
    153 *
    154 ******************************************************************************/
    155
    156acpi_status
    157acpi_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 acquire
    186	 * 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}