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

evrgnini.c (17914B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: evrgnini- ACPI address_space (op_region) init
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "acevents.h"
     13#include "acnamesp.h"
     14#include "acinterp.h"
     15
     16#define _COMPONENT          ACPI_EVENTS
     17ACPI_MODULE_NAME("evrgnini")
     18
     19/*******************************************************************************
     20 *
     21 * FUNCTION:    acpi_ev_system_memory_region_setup
     22 *
     23 * PARAMETERS:  handle              - Region we are interested in
     24 *              function            - Start or stop
     25 *              handler_context     - Address space handler context
     26 *              region_context      - Region specific context
     27 *
     28 * RETURN:      Status
     29 *
     30 * DESCRIPTION: Setup a system_memory operation region
     31 *
     32 ******************************************************************************/
     33acpi_status
     34acpi_ev_system_memory_region_setup(acpi_handle handle,
     35				   u32 function,
     36				   void *handler_context, void **region_context)
     37{
     38	union acpi_operand_object *region_desc =
     39	    (union acpi_operand_object *)handle;
     40	struct acpi_mem_space_context *local_region_context;
     41	struct acpi_mem_mapping *mm;
     42
     43	ACPI_FUNCTION_TRACE(ev_system_memory_region_setup);
     44
     45	if (function == ACPI_REGION_DEACTIVATE) {
     46		if (*region_context) {
     47			local_region_context =
     48			    (struct acpi_mem_space_context *)*region_context;
     49
     50			/* Delete memory mappings if present */
     51
     52			while (local_region_context->first_mm) {
     53				mm = local_region_context->first_mm;
     54				local_region_context->first_mm = mm->next_mm;
     55				acpi_os_unmap_memory(mm->logical_address,
     56						     mm->length);
     57				ACPI_FREE(mm);
     58			}
     59			ACPI_FREE(local_region_context);
     60			*region_context = NULL;
     61		}
     62		return_ACPI_STATUS(AE_OK);
     63	}
     64
     65	/* Create a new context */
     66
     67	local_region_context =
     68	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_mem_space_context));
     69	if (!(local_region_context)) {
     70		return_ACPI_STATUS(AE_NO_MEMORY);
     71	}
     72
     73	/* Save the region length and address for use in the handler */
     74
     75	local_region_context->length = region_desc->region.length;
     76	local_region_context->address = region_desc->region.address;
     77
     78	*region_context = local_region_context;
     79	return_ACPI_STATUS(AE_OK);
     80}
     81
     82/*******************************************************************************
     83 *
     84 * FUNCTION:    acpi_ev_io_space_region_setup
     85 *
     86 * PARAMETERS:  handle              - Region we are interested in
     87 *              function            - Start or stop
     88 *              handler_context     - Address space handler context
     89 *              region_context      - Region specific context
     90 *
     91 * RETURN:      Status
     92 *
     93 * DESCRIPTION: Setup a IO operation region
     94 *
     95 ******************************************************************************/
     96
     97acpi_status
     98acpi_ev_io_space_region_setup(acpi_handle handle,
     99			      u32 function,
    100			      void *handler_context, void **region_context)
    101{
    102	ACPI_FUNCTION_TRACE(ev_io_space_region_setup);
    103
    104	if (function == ACPI_REGION_DEACTIVATE) {
    105		*region_context = NULL;
    106	} else {
    107		*region_context = handler_context;
    108	}
    109
    110	return_ACPI_STATUS(AE_OK);
    111}
    112
    113/*******************************************************************************
    114 *
    115 * FUNCTION:    acpi_ev_pci_config_region_setup
    116 *
    117 * PARAMETERS:  handle              - Region we are interested in
    118 *              function            - Start or stop
    119 *              handler_context     - Address space handler context
    120 *              region_context      - Region specific context
    121 *
    122 * RETURN:      Status
    123 *
    124 * DESCRIPTION: Setup a PCI_Config operation region
    125 *
    126 * MUTEX:       Assumes namespace is not locked
    127 *
    128 ******************************************************************************/
    129
    130acpi_status
    131acpi_ev_pci_config_region_setup(acpi_handle handle,
    132				u32 function,
    133				void *handler_context, void **region_context)
    134{
    135	acpi_status status = AE_OK;
    136	u64 pci_value;
    137	struct acpi_pci_id *pci_id = *region_context;
    138	union acpi_operand_object *handler_obj;
    139	struct acpi_namespace_node *parent_node;
    140	struct acpi_namespace_node *pci_root_node;
    141	struct acpi_namespace_node *pci_device_node;
    142	union acpi_operand_object *region_obj =
    143	    (union acpi_operand_object *)handle;
    144
    145	ACPI_FUNCTION_TRACE(ev_pci_config_region_setup);
    146
    147	handler_obj = region_obj->region.handler;
    148	if (!handler_obj) {
    149		/*
    150		 * No installed handler. This shouldn't happen because the dispatch
    151		 * routine checks before we get here, but we check again just in case.
    152		 */
    153		ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
    154				  "Attempting to init a region %p, with no handler\n",
    155				  region_obj));
    156		return_ACPI_STATUS(AE_NOT_EXIST);
    157	}
    158
    159	*region_context = NULL;
    160	if (function == ACPI_REGION_DEACTIVATE) {
    161		if (pci_id) {
    162			ACPI_FREE(pci_id);
    163		}
    164		return_ACPI_STATUS(status);
    165	}
    166
    167	parent_node = region_obj->region.node->parent;
    168
    169	/*
    170	 * Get the _SEG and _BBN values from the device upon which the handler
    171	 * is installed.
    172	 *
    173	 * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
    174	 * This is the device the handler has been registered to handle.
    175	 */
    176
    177	/*
    178	 * If the address_space.Node is still pointing to the root, we need
    179	 * to scan upward for a PCI Root bridge and re-associate the op_region
    180	 * handlers with that device.
    181	 */
    182	if (handler_obj->address_space.node == acpi_gbl_root_node) {
    183
    184		/* Start search from the parent object */
    185
    186		pci_root_node = parent_node;
    187		while (pci_root_node != acpi_gbl_root_node) {
    188
    189			/* Get the _HID/_CID in order to detect a root_bridge */
    190
    191			if (acpi_ev_is_pci_root_bridge(pci_root_node)) {
    192
    193				/* Install a handler for this PCI root bridge */
    194
    195				status = acpi_install_address_space_handler((acpi_handle)pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
    196				if (ACPI_FAILURE(status)) {
    197					if (status == AE_SAME_HANDLER) {
    198						/*
    199						 * It is OK if the handler is already installed on the
    200						 * root bridge. Still need to return a context object
    201						 * for the new PCI_Config operation region, however.
    202						 */
    203					} else {
    204						ACPI_EXCEPTION((AE_INFO, status,
    205								"Could not install PciConfig handler "
    206								"for Root Bridge %4.4s",
    207								acpi_ut_get_node_name
    208								(pci_root_node)));
    209					}
    210				}
    211				break;
    212			}
    213
    214			pci_root_node = pci_root_node->parent;
    215		}
    216
    217		/* PCI root bridge not found, use namespace root node */
    218	} else {
    219		pci_root_node = handler_obj->address_space.node;
    220	}
    221
    222	/*
    223	 * If this region is now initialized, we are done.
    224	 * (install_address_space_handler could have initialized it)
    225	 */
    226	if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
    227		return_ACPI_STATUS(AE_OK);
    228	}
    229
    230	/* Region is still not initialized. Create a new context */
    231
    232	pci_id = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pci_id));
    233	if (!pci_id) {
    234		return_ACPI_STATUS(AE_NO_MEMORY);
    235	}
    236
    237	/*
    238	 * For PCI_Config space access, we need the segment, bus, device and
    239	 * function numbers. Acquire them here.
    240	 *
    241	 * Find the parent device object. (This allows the operation region to be
    242	 * within a subscope under the device, such as a control method.)
    243	 */
    244	pci_device_node = region_obj->region.node;
    245	while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
    246		pci_device_node = pci_device_node->parent;
    247	}
    248
    249	if (!pci_device_node) {
    250		ACPI_FREE(pci_id);
    251		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
    252	}
    253
    254	/*
    255	 * Get the PCI device and function numbers from the _ADR object
    256	 * contained in the parent's scope.
    257	 */
    258	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
    259						 pci_device_node, &pci_value);
    260
    261	/*
    262	 * The default is zero, and since the allocation above zeroed the data,
    263	 * just do nothing on failure.
    264	 */
    265	if (ACPI_SUCCESS(status)) {
    266		pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
    267		pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
    268	}
    269
    270	/* The PCI segment number comes from the _SEG method */
    271
    272	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
    273						 pci_root_node, &pci_value);
    274	if (ACPI_SUCCESS(status)) {
    275		pci_id->segment = ACPI_LOWORD(pci_value);
    276	}
    277
    278	/* The PCI bus number comes from the _BBN method */
    279
    280	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
    281						 pci_root_node, &pci_value);
    282	if (ACPI_SUCCESS(status)) {
    283		pci_id->bus = ACPI_LOWORD(pci_value);
    284	}
    285
    286	/* Complete/update the PCI ID for this device */
    287
    288	status =
    289	    acpi_hw_derive_pci_id(pci_id, pci_root_node,
    290				  region_obj->region.node);
    291	if (ACPI_FAILURE(status)) {
    292		ACPI_FREE(pci_id);
    293		return_ACPI_STATUS(status);
    294	}
    295
    296	*region_context = pci_id;
    297	return_ACPI_STATUS(AE_OK);
    298}
    299
    300/*******************************************************************************
    301 *
    302 * FUNCTION:    acpi_ev_is_pci_root_bridge
    303 *
    304 * PARAMETERS:  node            - Device node being examined
    305 *
    306 * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
    307 *
    308 * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
    309 *              examining the _HID and _CID for the device.
    310 *
    311 ******************************************************************************/
    312
    313u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
    314{
    315	acpi_status status;
    316	struct acpi_pnp_device_id *hid;
    317	struct acpi_pnp_device_id_list *cid;
    318	u32 i;
    319	u8 match;
    320
    321	/* Get the _HID and check for a PCI Root Bridge */
    322
    323	status = acpi_ut_execute_HID(node, &hid);
    324	if (ACPI_FAILURE(status)) {
    325		return (FALSE);
    326	}
    327
    328	match = acpi_ut_is_pci_root_bridge(hid->string);
    329	ACPI_FREE(hid);
    330
    331	if (match) {
    332		return (TRUE);
    333	}
    334
    335	/* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
    336
    337	status = acpi_ut_execute_CID(node, &cid);
    338	if (ACPI_FAILURE(status)) {
    339		return (FALSE);
    340	}
    341
    342	/* Check all _CIDs in the returned list */
    343
    344	for (i = 0; i < cid->count; i++) {
    345		if (acpi_ut_is_pci_root_bridge(cid->ids[i].string)) {
    346			ACPI_FREE(cid);
    347			return (TRUE);
    348		}
    349	}
    350
    351	ACPI_FREE(cid);
    352	return (FALSE);
    353}
    354
    355/*******************************************************************************
    356 *
    357 * FUNCTION:    acpi_ev_pci_bar_region_setup
    358 *
    359 * PARAMETERS:  handle              - Region we are interested in
    360 *              function            - Start or stop
    361 *              handler_context     - Address space handler context
    362 *              region_context      - Region specific context
    363 *
    364 * RETURN:      Status
    365 *
    366 * DESCRIPTION: Setup a pci_BAR operation region
    367 *
    368 * MUTEX:       Assumes namespace is not locked
    369 *
    370 ******************************************************************************/
    371
    372acpi_status
    373acpi_ev_pci_bar_region_setup(acpi_handle handle,
    374			     u32 function,
    375			     void *handler_context, void **region_context)
    376{
    377	ACPI_FUNCTION_TRACE(ev_pci_bar_region_setup);
    378
    379	return_ACPI_STATUS(AE_OK);
    380}
    381
    382/*******************************************************************************
    383 *
    384 * FUNCTION:    acpi_ev_cmos_region_setup
    385 *
    386 * PARAMETERS:  handle              - Region we are interested in
    387 *              function            - Start or stop
    388 *              handler_context     - Address space handler context
    389 *              region_context      - Region specific context
    390 *
    391 * RETURN:      Status
    392 *
    393 * DESCRIPTION: Setup a CMOS operation region
    394 *
    395 * MUTEX:       Assumes namespace is not locked
    396 *
    397 ******************************************************************************/
    398
    399acpi_status
    400acpi_ev_cmos_region_setup(acpi_handle handle,
    401			  u32 function,
    402			  void *handler_context, void **region_context)
    403{
    404	ACPI_FUNCTION_TRACE(ev_cmos_region_setup);
    405
    406	return_ACPI_STATUS(AE_OK);
    407}
    408
    409/*******************************************************************************
    410 *
    411 * FUNCTION:    acpi_ev_data_table_region_setup
    412 *
    413 * PARAMETERS:  handle              - Region we are interested in
    414 *              function            - Start or stop
    415 *              handler_context     - Address space handler context
    416 *              region_context      - Region specific context
    417 *
    418 * RETURN:      Status
    419 *
    420 * DESCRIPTION: Setup a data_table_region
    421 *
    422 * MUTEX:       Assumes namespace is not locked
    423 *
    424 ******************************************************************************/
    425
    426acpi_status
    427acpi_ev_data_table_region_setup(acpi_handle handle,
    428				u32 function,
    429				void *handler_context, void **region_context)
    430{
    431	union acpi_operand_object *region_desc =
    432	    (union acpi_operand_object *)handle;
    433	struct acpi_data_table_space_context *local_region_context;
    434
    435	ACPI_FUNCTION_TRACE(ev_data_table_region_setup);
    436
    437	if (function == ACPI_REGION_DEACTIVATE) {
    438		if (*region_context) {
    439			ACPI_FREE(*region_context);
    440			*region_context = NULL;
    441		}
    442		return_ACPI_STATUS(AE_OK);
    443	}
    444
    445	/* Create a new context */
    446
    447	local_region_context =
    448	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_data_table_space_context));
    449	if (!(local_region_context)) {
    450		return_ACPI_STATUS(AE_NO_MEMORY);
    451	}
    452
    453	/* Save the data table pointer for use in the handler */
    454
    455	local_region_context->pointer = region_desc->region.pointer;
    456
    457	*region_context = local_region_context;
    458	return_ACPI_STATUS(AE_OK);
    459}
    460
    461/*******************************************************************************
    462 *
    463 * FUNCTION:    acpi_ev_default_region_setup
    464 *
    465 * PARAMETERS:  handle              - Region we are interested in
    466 *              function            - Start or stop
    467 *              handler_context     - Address space handler context
    468 *              region_context      - Region specific context
    469 *
    470 * RETURN:      Status
    471 *
    472 * DESCRIPTION: Default region initialization
    473 *
    474 ******************************************************************************/
    475
    476acpi_status
    477acpi_ev_default_region_setup(acpi_handle handle,
    478			     u32 function,
    479			     void *handler_context, void **region_context)
    480{
    481	ACPI_FUNCTION_TRACE(ev_default_region_setup);
    482
    483	if (function == ACPI_REGION_DEACTIVATE) {
    484		*region_context = NULL;
    485	} else {
    486		*region_context = handler_context;
    487	}
    488
    489	return_ACPI_STATUS(AE_OK);
    490}
    491
    492/*******************************************************************************
    493 *
    494 * FUNCTION:    acpi_ev_initialize_region
    495 *
    496 * PARAMETERS:  region_obj      - Region we are initializing
    497 *
    498 * RETURN:      Status
    499 *
    500 * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
    501 *              for execution at a later time
    502 *
    503 *              Get the appropriate address space handler for a newly
    504 *              created region.
    505 *
    506 *              This also performs address space specific initialization. For
    507 *              example, PCI regions must have an _ADR object that contains
    508 *              a PCI address in the scope of the definition. This address is
    509 *              required to perform an access to PCI config space.
    510 *
    511 * MUTEX:       Interpreter should be unlocked, because we may run the _REG
    512 *              method for this region.
    513 *
    514 * NOTE:        Possible incompliance:
    515 *              There is a behavior conflict in automatic _REG execution:
    516 *              1. When the interpreter is evaluating a method, we can only
    517 *                 automatically run _REG for the following case:
    518 *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
    519 *              2. When the interpreter is loading a table, we can also
    520 *                 automatically run _REG for the following case:
    521 *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
    522 *              Though this may not be compliant to the de-facto standard, the
    523 *              logic is kept in order not to trigger regressions. And keeping
    524 *              this logic should be taken care by the caller of this function.
    525 *
    526 ******************************************************************************/
    527
    528acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj)
    529{
    530	union acpi_operand_object *handler_obj;
    531	union acpi_operand_object *obj_desc;
    532	acpi_adr_space_type space_id;
    533	struct acpi_namespace_node *node;
    534
    535	ACPI_FUNCTION_TRACE(ev_initialize_region);
    536
    537	if (!region_obj) {
    538		return_ACPI_STATUS(AE_BAD_PARAMETER);
    539	}
    540
    541	if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
    542		return_ACPI_STATUS(AE_OK);
    543	}
    544
    545	region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
    546
    547	node = region_obj->region.node->parent;
    548	space_id = region_obj->region.space_id;
    549
    550	/*
    551	 * The following loop depends upon the root Node having no parent
    552	 * ie: acpi_gbl_root_node->Parent being set to NULL
    553	 */
    554	while (node) {
    555
    556		/* Check to see if a handler exists */
    557
    558		handler_obj = NULL;
    559		obj_desc = acpi_ns_get_attached_object(node);
    560		if (obj_desc) {
    561
    562			/* Can only be a handler if the object exists */
    563
    564			switch (node->type) {
    565			case ACPI_TYPE_DEVICE:
    566			case ACPI_TYPE_PROCESSOR:
    567			case ACPI_TYPE_THERMAL:
    568
    569				handler_obj = obj_desc->common_notify.handler;
    570				break;
    571
    572			default:
    573
    574				/* Ignore other objects */
    575
    576				break;
    577			}
    578
    579			handler_obj =
    580			    acpi_ev_find_region_handler(space_id, handler_obj);
    581			if (handler_obj) {
    582
    583				/* Found correct handler */
    584
    585				ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
    586						  "Found handler %p for region %p in obj %p\n",
    587						  handler_obj, region_obj,
    588						  obj_desc));
    589
    590				(void)acpi_ev_attach_region(handler_obj,
    591							    region_obj, FALSE);
    592
    593				/*
    594				 * Tell all users that this region is usable by
    595				 * running the _REG method
    596				 */
    597				acpi_ex_exit_interpreter();
    598				(void)acpi_ev_execute_reg_method(region_obj,
    599								 ACPI_REG_CONNECT);
    600				acpi_ex_enter_interpreter();
    601				return_ACPI_STATUS(AE_OK);
    602			}
    603		}
    604
    605		/* This node does not have the handler we need; Pop up one level */
    606
    607		node = node->parent;
    608	}
    609
    610	/*
    611	 * If we get here, there is no handler for this region. This is not
    612	 * fatal because many regions get created before a handler is installed
    613	 * for said region.
    614	 */
    615	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
    616			  "No handler for RegionType %s(%X) (RegionObj %p)\n",
    617			  acpi_ut_get_region_name(space_id), space_id,
    618			  region_obj));
    619
    620	return_ACPI_STATUS(AE_OK);
    621}