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

utxface.c (14740B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: utxface - External interfaces, miscellaneous utility functions
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#define EXPORT_ACPI_INTERFACES
     11
     12#include <acpi/acpi.h>
     13#include "accommon.h"
     14#include "acdebug.h"
     15
     16#define _COMPONENT          ACPI_UTILITIES
     17ACPI_MODULE_NAME("utxface")
     18
     19/*******************************************************************************
     20 *
     21 * FUNCTION:    acpi_terminate
     22 *
     23 * PARAMETERS:  None
     24 *
     25 * RETURN:      Status
     26 *
     27 * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources.
     28 *
     29 ******************************************************************************/
     30acpi_status ACPI_INIT_FUNCTION acpi_terminate(void)
     31{
     32	acpi_status status;
     33
     34	ACPI_FUNCTION_TRACE(acpi_terminate);
     35
     36	/* Shutdown and free all resources */
     37
     38	acpi_ut_subsystem_shutdown();
     39
     40	/* Free the mutex objects */
     41
     42	acpi_ut_mutex_terminate();
     43
     44	/* Now we can shutdown the OS-dependent layer */
     45
     46	status = acpi_os_terminate();
     47	return_ACPI_STATUS(status);
     48}
     49
     50ACPI_EXPORT_SYMBOL_INIT(acpi_terminate)
     51
     52#ifndef ACPI_ASL_COMPILER
     53#ifdef ACPI_FUTURE_USAGE
     54/*******************************************************************************
     55 *
     56 * FUNCTION:    acpi_subsystem_status
     57 *
     58 * PARAMETERS:  None
     59 *
     60 * RETURN:      Status of the ACPI subsystem
     61 *
     62 * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
     63 *              before making any other calls, to ensure the subsystem
     64 *              initialized successfully.
     65 *
     66 ******************************************************************************/
     67acpi_status acpi_subsystem_status(void)
     68{
     69
     70	if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) {
     71		return (AE_OK);
     72	} else {
     73		return (AE_ERROR);
     74	}
     75}
     76
     77ACPI_EXPORT_SYMBOL(acpi_subsystem_status)
     78
     79/*******************************************************************************
     80 *
     81 * FUNCTION:    acpi_get_system_info
     82 *
     83 * PARAMETERS:  out_buffer      - A buffer to receive the resources for the
     84 *                                device
     85 *
     86 * RETURN:      status          - the status of the call
     87 *
     88 * DESCRIPTION: This function is called to get information about the current
     89 *              state of the ACPI subsystem. It will return system information
     90 *              in the out_buffer.
     91 *
     92 *              If the function fails an appropriate status will be returned
     93 *              and the value of out_buffer is undefined.
     94 *
     95 ******************************************************************************/
     96acpi_status acpi_get_system_info(struct acpi_buffer *out_buffer)
     97{
     98	struct acpi_system_info *info_ptr;
     99	acpi_status status;
    100
    101	ACPI_FUNCTION_TRACE(acpi_get_system_info);
    102
    103	/* Parameter validation */
    104
    105	status = acpi_ut_validate_buffer(out_buffer);
    106	if (ACPI_FAILURE(status)) {
    107		return_ACPI_STATUS(status);
    108	}
    109
    110	/* Validate/Allocate/Clear caller buffer */
    111
    112	status =
    113	    acpi_ut_initialize_buffer(out_buffer,
    114				      sizeof(struct acpi_system_info));
    115	if (ACPI_FAILURE(status)) {
    116		return_ACPI_STATUS(status);
    117	}
    118
    119	/*
    120	 * Populate the return buffer
    121	 */
    122	info_ptr = (struct acpi_system_info *)out_buffer->pointer;
    123	info_ptr->acpi_ca_version = ACPI_CA_VERSION;
    124
    125	/* System flags (ACPI capabilities) */
    126
    127	info_ptr->flags = ACPI_SYS_MODE_ACPI;
    128
    129	/* Timer resolution - 24 or 32 bits  */
    130
    131	if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) {
    132		info_ptr->timer_resolution = 24;
    133	} else {
    134		info_ptr->timer_resolution = 32;
    135	}
    136
    137	/* Clear the reserved fields */
    138
    139	info_ptr->reserved1 = 0;
    140	info_ptr->reserved2 = 0;
    141
    142	/* Current debug levels */
    143
    144	info_ptr->debug_layer = acpi_dbg_layer;
    145	info_ptr->debug_level = acpi_dbg_level;
    146
    147	return_ACPI_STATUS(AE_OK);
    148}
    149
    150ACPI_EXPORT_SYMBOL(acpi_get_system_info)
    151
    152/*******************************************************************************
    153 *
    154 * FUNCTION:    acpi_get_statistics
    155 *
    156 * PARAMETERS:  stats           - Where the statistics are returned
    157 *
    158 * RETURN:      status          - the status of the call
    159 *
    160 * DESCRIPTION: Get the contents of the various system counters
    161 *
    162 ******************************************************************************/
    163acpi_status acpi_get_statistics(struct acpi_statistics *stats)
    164{
    165	ACPI_FUNCTION_TRACE(acpi_get_statistics);
    166
    167	/* Parameter validation */
    168
    169	if (!stats) {
    170		return_ACPI_STATUS(AE_BAD_PARAMETER);
    171	}
    172
    173	/* Various interrupt-based event counters */
    174
    175	stats->sci_count = acpi_sci_count;
    176	stats->gpe_count = acpi_gpe_count;
    177
    178	memcpy(stats->fixed_event_count, acpi_fixed_event_count,
    179	       sizeof(acpi_fixed_event_count));
    180
    181	/* Other counters */
    182
    183	stats->method_count = acpi_method_count;
    184	return_ACPI_STATUS(AE_OK);
    185}
    186
    187ACPI_EXPORT_SYMBOL(acpi_get_statistics)
    188
    189/*****************************************************************************
    190 *
    191 * FUNCTION:    acpi_install_initialization_handler
    192 *
    193 * PARAMETERS:  handler             - Callback procedure
    194 *              function            - Not (currently) used, see below
    195 *
    196 * RETURN:      Status
    197 *
    198 * DESCRIPTION: Install an initialization handler
    199 *
    200 * TBD: When a second function is added, must save the Function also.
    201 *
    202 ****************************************************************************/
    203acpi_status
    204acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
    205{
    206
    207	if (!handler) {
    208		return (AE_BAD_PARAMETER);
    209	}
    210
    211	if (acpi_gbl_init_handler) {
    212		return (AE_ALREADY_EXISTS);
    213	}
    214
    215	acpi_gbl_init_handler = handler;
    216	return (AE_OK);
    217}
    218
    219ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
    220#endif
    221
    222/*****************************************************************************
    223 *
    224 * FUNCTION:    acpi_purge_cached_objects
    225 *
    226 * PARAMETERS:  None
    227 *
    228 * RETURN:      Status
    229 *
    230 * DESCRIPTION: Empty all caches (delete the cached objects)
    231 *
    232 ****************************************************************************/
    233acpi_status acpi_purge_cached_objects(void)
    234{
    235	ACPI_FUNCTION_TRACE(acpi_purge_cached_objects);
    236
    237	(void)acpi_os_purge_cache(acpi_gbl_state_cache);
    238	(void)acpi_os_purge_cache(acpi_gbl_operand_cache);
    239	(void)acpi_os_purge_cache(acpi_gbl_ps_node_cache);
    240	(void)acpi_os_purge_cache(acpi_gbl_ps_node_ext_cache);
    241
    242	return_ACPI_STATUS(AE_OK);
    243}
    244
    245ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects)
    246
    247/*****************************************************************************
    248 *
    249 * FUNCTION:    acpi_install_interface
    250 *
    251 * PARAMETERS:  interface_name      - The interface to install
    252 *
    253 * RETURN:      Status
    254 *
    255 * DESCRIPTION: Install an _OSI interface to the global list
    256 *
    257 ****************************************************************************/
    258acpi_status acpi_install_interface(acpi_string interface_name)
    259{
    260	acpi_status status;
    261	struct acpi_interface_info *interface_info;
    262
    263	/* Parameter validation */
    264
    265	if (!interface_name || (strlen(interface_name) == 0)) {
    266		return (AE_BAD_PARAMETER);
    267	}
    268
    269	status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
    270	if (ACPI_FAILURE(status)) {
    271		return (status);
    272	}
    273
    274	/* Check if the interface name is already in the global list */
    275
    276	interface_info = acpi_ut_get_interface(interface_name);
    277	if (interface_info) {
    278		/*
    279		 * The interface already exists in the list. This is OK if the
    280		 * interface has been marked invalid -- just clear the bit.
    281		 */
    282		if (interface_info->flags & ACPI_OSI_INVALID) {
    283			interface_info->flags &= ~ACPI_OSI_INVALID;
    284			status = AE_OK;
    285		} else {
    286			status = AE_ALREADY_EXISTS;
    287		}
    288	} else {
    289		/* New interface name, install into the global list */
    290
    291		status = acpi_ut_install_interface(interface_name);
    292	}
    293
    294	acpi_os_release_mutex(acpi_gbl_osi_mutex);
    295	return (status);
    296}
    297
    298ACPI_EXPORT_SYMBOL(acpi_install_interface)
    299
    300/*****************************************************************************
    301 *
    302 * FUNCTION:    acpi_remove_interface
    303 *
    304 * PARAMETERS:  interface_name      - The interface to remove
    305 *
    306 * RETURN:      Status
    307 *
    308 * DESCRIPTION: Remove an _OSI interface from the global list
    309 *
    310 ****************************************************************************/
    311acpi_status acpi_remove_interface(acpi_string interface_name)
    312{
    313	acpi_status status;
    314
    315	/* Parameter validation */
    316
    317	if (!interface_name || (strlen(interface_name) == 0)) {
    318		return (AE_BAD_PARAMETER);
    319	}
    320
    321	status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
    322	if (ACPI_FAILURE(status)) {
    323		return (status);
    324	}
    325
    326	status = acpi_ut_remove_interface(interface_name);
    327
    328	acpi_os_release_mutex(acpi_gbl_osi_mutex);
    329	return (status);
    330}
    331
    332ACPI_EXPORT_SYMBOL(acpi_remove_interface)
    333
    334/*****************************************************************************
    335 *
    336 * FUNCTION:    acpi_install_interface_handler
    337 *
    338 * PARAMETERS:  handler             - The _OSI interface handler to install
    339 *                                    NULL means "remove existing handler"
    340 *
    341 * RETURN:      Status
    342 *
    343 * DESCRIPTION: Install a handler for the predefined _OSI ACPI method.
    344 *              invoked during execution of the internal implementation of
    345 *              _OSI. A NULL handler simply removes any existing handler.
    346 *
    347 ****************************************************************************/
    348acpi_status acpi_install_interface_handler(acpi_interface_handler handler)
    349{
    350	acpi_status status;
    351
    352	status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
    353	if (ACPI_FAILURE(status)) {
    354		return (status);
    355	}
    356
    357	if (handler && acpi_gbl_interface_handler) {
    358		status = AE_ALREADY_EXISTS;
    359	} else {
    360		acpi_gbl_interface_handler = handler;
    361	}
    362
    363	acpi_os_release_mutex(acpi_gbl_osi_mutex);
    364	return (status);
    365}
    366
    367ACPI_EXPORT_SYMBOL(acpi_install_interface_handler)
    368
    369/*****************************************************************************
    370 *
    371 * FUNCTION:    acpi_update_interfaces
    372 *
    373 * PARAMETERS:  action              - Actions to be performed during the
    374 *                                    update
    375 *
    376 * RETURN:      Status
    377 *
    378 * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
    379 *              string or/and feature group strings.
    380 *
    381 ****************************************************************************/
    382acpi_status acpi_update_interfaces(u8 action)
    383{
    384	acpi_status status;
    385
    386	status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
    387	if (ACPI_FAILURE(status)) {
    388		return (status);
    389	}
    390
    391	status = acpi_ut_update_interfaces(action);
    392
    393	acpi_os_release_mutex(acpi_gbl_osi_mutex);
    394	return (status);
    395}
    396
    397/*****************************************************************************
    398 *
    399 * FUNCTION:    acpi_check_address_range
    400 *
    401 * PARAMETERS:  space_id            - Address space ID
    402 *              address             - Start address
    403 *              length              - Length
    404 *              warn                - TRUE if warning on overlap desired
    405 *
    406 * RETURN:      Count of the number of conflicts detected.
    407 *
    408 * DESCRIPTION: Check if the input address range overlaps any of the
    409 *              ASL operation region address ranges.
    410 *
    411 ****************************************************************************/
    412
    413u32
    414acpi_check_address_range(acpi_adr_space_type space_id,
    415			 acpi_physical_address address,
    416			 acpi_size length, u8 warn)
    417{
    418	u32 overlaps;
    419	acpi_status status;
    420
    421	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    422	if (ACPI_FAILURE(status)) {
    423		return (0);
    424	}
    425
    426	overlaps = acpi_ut_check_address_range(space_id, address,
    427					       (u32)length, warn);
    428
    429	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
    430	return (overlaps);
    431}
    432
    433ACPI_EXPORT_SYMBOL(acpi_check_address_range)
    434#endif				/* !ACPI_ASL_COMPILER */
    435/*******************************************************************************
    436 *
    437 * FUNCTION:    acpi_decode_pld_buffer
    438 *
    439 * PARAMETERS:  in_buffer           - Buffer returned by _PLD method
    440 *              length              - Length of the in_buffer
    441 *              return_buffer       - Where the decode buffer is returned
    442 *
    443 * RETURN:      Status and the decoded _PLD buffer. User must deallocate
    444 *              the buffer via ACPI_FREE.
    445 *
    446 * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
    447 *              a local struct that is much more useful to an ACPI driver.
    448 *
    449 ******************************************************************************/
    450acpi_status
    451acpi_decode_pld_buffer(u8 *in_buffer,
    452		       acpi_size length, struct acpi_pld_info **return_buffer)
    453{
    454	struct acpi_pld_info *pld_info;
    455	u32 *buffer = ACPI_CAST_PTR(u32, in_buffer);
    456	u32 dword;
    457
    458	/* Parameter validation */
    459
    460	if (!in_buffer || !return_buffer
    461	    || (length < ACPI_PLD_REV1_BUFFER_SIZE)) {
    462		return (AE_BAD_PARAMETER);
    463	}
    464
    465	pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info));
    466	if (!pld_info) {
    467		return (AE_NO_MEMORY);
    468	}
    469
    470	/* First 32-bit DWord */
    471
    472	ACPI_MOVE_32_TO_32(&dword, &buffer[0]);
    473	pld_info->revision = ACPI_PLD_GET_REVISION(&dword);
    474	pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword);
    475	pld_info->red = ACPI_PLD_GET_RED(&dword);
    476	pld_info->green = ACPI_PLD_GET_GREEN(&dword);
    477	pld_info->blue = ACPI_PLD_GET_BLUE(&dword);
    478
    479	/* Second 32-bit DWord */
    480
    481	ACPI_MOVE_32_TO_32(&dword, &buffer[1]);
    482	pld_info->width = ACPI_PLD_GET_WIDTH(&dword);
    483	pld_info->height = ACPI_PLD_GET_HEIGHT(&dword);
    484
    485	/* Third 32-bit DWord */
    486
    487	ACPI_MOVE_32_TO_32(&dword, &buffer[2]);
    488	pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword);
    489	pld_info->dock = ACPI_PLD_GET_DOCK(&dword);
    490	pld_info->lid = ACPI_PLD_GET_LID(&dword);
    491	pld_info->panel = ACPI_PLD_GET_PANEL(&dword);
    492	pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword);
    493	pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword);
    494	pld_info->shape = ACPI_PLD_GET_SHAPE(&dword);
    495	pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword);
    496	pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword);
    497	pld_info->group_position = ACPI_PLD_GET_POSITION(&dword);
    498	pld_info->bay = ACPI_PLD_GET_BAY(&dword);
    499
    500	/* Fourth 32-bit DWord */
    501
    502	ACPI_MOVE_32_TO_32(&dword, &buffer[3]);
    503	pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword);
    504	pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword);
    505	pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword);
    506	pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword);
    507	pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword);
    508	pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword);
    509	pld_info->order = ACPI_PLD_GET_ORDER(&dword);
    510
    511	if (length >= ACPI_PLD_REV2_BUFFER_SIZE) {
    512
    513		/* Fifth 32-bit DWord (Revision 2 of _PLD) */
    514
    515		ACPI_MOVE_32_TO_32(&dword, &buffer[4]);
    516		pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword);
    517		pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword);
    518	}
    519
    520	*return_buffer = pld_info;
    521	return (AE_OK);
    522}
    523
    524ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer)