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

evevent.c (8331B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: evevent - Fixed Event handling and dispatch
      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
     14#define _COMPONENT          ACPI_EVENTS
     15ACPI_MODULE_NAME("evevent")
     16#if (!ACPI_REDUCED_HARDWARE)	/* Entire module */
     17/* Local prototypes */
     18static acpi_status acpi_ev_fixed_event_initialize(void);
     19
     20static u32 acpi_ev_fixed_event_dispatch(u32 event);
     21
     22/*******************************************************************************
     23 *
     24 * FUNCTION:    acpi_ev_initialize_events
     25 *
     26 * PARAMETERS:  None
     27 *
     28 * RETURN:      Status
     29 *
     30 * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE)
     31 *
     32 ******************************************************************************/
     33
     34acpi_status acpi_ev_initialize_events(void)
     35{
     36	acpi_status status;
     37
     38	ACPI_FUNCTION_TRACE(ev_initialize_events);
     39
     40	/* If Hardware Reduced flag is set, there are no fixed events */
     41
     42	if (acpi_gbl_reduced_hardware) {
     43		return_ACPI_STATUS(AE_OK);
     44	}
     45
     46	/*
     47	 * Initialize the Fixed and General Purpose Events. This is done prior to
     48	 * enabling SCIs to prevent interrupts from occurring before the handlers
     49	 * are installed.
     50	 */
     51	status = acpi_ev_fixed_event_initialize();
     52	if (ACPI_FAILURE(status)) {
     53		ACPI_EXCEPTION((AE_INFO, status,
     54				"Unable to initialize fixed events"));
     55		return_ACPI_STATUS(status);
     56	}
     57
     58	status = acpi_ev_gpe_initialize();
     59	if (ACPI_FAILURE(status)) {
     60		ACPI_EXCEPTION((AE_INFO, status,
     61				"Unable to initialize general purpose events"));
     62		return_ACPI_STATUS(status);
     63	}
     64
     65	return_ACPI_STATUS(status);
     66}
     67
     68/*******************************************************************************
     69 *
     70 * FUNCTION:    acpi_ev_install_xrupt_handlers
     71 *
     72 * PARAMETERS:  None
     73 *
     74 * RETURN:      Status
     75 *
     76 * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
     77 *
     78 ******************************************************************************/
     79
     80acpi_status acpi_ev_install_xrupt_handlers(void)
     81{
     82	acpi_status status;
     83
     84	ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers);
     85
     86	/* If Hardware Reduced flag is set, there is no ACPI h/w */
     87
     88	if (acpi_gbl_reduced_hardware) {
     89		return_ACPI_STATUS(AE_OK);
     90	}
     91
     92	/* Install the SCI handler */
     93
     94	status = acpi_ev_install_sci_handler();
     95	if (ACPI_FAILURE(status)) {
     96		ACPI_EXCEPTION((AE_INFO, status,
     97				"Unable to install System Control Interrupt handler"));
     98		return_ACPI_STATUS(status);
     99	}
    100
    101	/* Install the handler for the Global Lock */
    102
    103	status = acpi_ev_init_global_lock_handler();
    104	if (ACPI_FAILURE(status)) {
    105		ACPI_EXCEPTION((AE_INFO, status,
    106				"Unable to initialize Global Lock handler"));
    107		return_ACPI_STATUS(status);
    108	}
    109
    110	acpi_gbl_events_initialized = TRUE;
    111	return_ACPI_STATUS(status);
    112}
    113
    114/*******************************************************************************
    115 *
    116 * FUNCTION:    acpi_ev_fixed_event_initialize
    117 *
    118 * PARAMETERS:  None
    119 *
    120 * RETURN:      Status
    121 *
    122 * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
    123 *
    124 ******************************************************************************/
    125
    126static acpi_status acpi_ev_fixed_event_initialize(void)
    127{
    128	u32 i;
    129	acpi_status status;
    130
    131	/*
    132	 * Initialize the structure that keeps track of fixed event handlers and
    133	 * disable all of the fixed events.
    134	 */
    135	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
    136		acpi_gbl_fixed_event_handlers[i].handler = NULL;
    137		acpi_gbl_fixed_event_handlers[i].context = NULL;
    138
    139		/* Disable the fixed event */
    140
    141		if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
    142			status =
    143			    acpi_write_bit_register(acpi_gbl_fixed_event_info
    144						    [i].enable_register_id,
    145						    ACPI_DISABLE_EVENT);
    146			if (ACPI_FAILURE(status)) {
    147				return (status);
    148			}
    149		}
    150	}
    151
    152	return (AE_OK);
    153}
    154
    155/*******************************************************************************
    156 *
    157 * FUNCTION:    acpi_ev_fixed_event_detect
    158 *
    159 * PARAMETERS:  None
    160 *
    161 * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
    162 *
    163 * DESCRIPTION: Checks the PM status register for active fixed events
    164 *
    165 ******************************************************************************/
    166
    167u32 acpi_ev_fixed_event_detect(void)
    168{
    169	u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
    170	u32 fixed_status;
    171	u32 fixed_enable;
    172	u32 i;
    173	acpi_status status;
    174
    175	ACPI_FUNCTION_NAME(ev_fixed_event_detect);
    176
    177	/*
    178	 * Read the fixed feature status and enable registers, as all the cases
    179	 * depend on their values. Ignore errors here.
    180	 */
    181	status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
    182	status |=
    183	    acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
    184	if (ACPI_FAILURE(status)) {
    185		return (int_status);
    186	}
    187
    188	ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
    189			  "Fixed Event Block: Enable %08X Status %08X\n",
    190			  fixed_enable, fixed_status));
    191
    192	/*
    193	 * Check for all possible Fixed Events and dispatch those that are active
    194	 */
    195	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
    196
    197		/* Both the status and enable bits must be on for this event */
    198
    199		if ((fixed_status & acpi_gbl_fixed_event_info[i].
    200		     status_bit_mask)
    201		    && (fixed_enable & acpi_gbl_fixed_event_info[i].
    202			enable_bit_mask)) {
    203			/*
    204			 * Found an active (signalled) event. Invoke global event
    205			 * handler if present.
    206			 */
    207			acpi_fixed_event_count[i]++;
    208			if (acpi_gbl_global_event_handler) {
    209				acpi_gbl_global_event_handler
    210				    (ACPI_EVENT_TYPE_FIXED, NULL, i,
    211				     acpi_gbl_global_event_handler_context);
    212			}
    213
    214			int_status |= acpi_ev_fixed_event_dispatch(i);
    215		}
    216	}
    217
    218	return (int_status);
    219}
    220
    221/*******************************************************************************
    222 *
    223 * FUNCTION:    acpi_ev_fixed_event_dispatch
    224 *
    225 * PARAMETERS:  event               - Event type
    226 *
    227 * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
    228 *
    229 * DESCRIPTION: Clears the status bit for the requested event, calls the
    230 *              handler that previously registered for the event.
    231 *              NOTE: If there is no handler for the event, the event is
    232 *              disabled to prevent further interrupts.
    233 *
    234 ******************************************************************************/
    235
    236static u32 acpi_ev_fixed_event_dispatch(u32 event)
    237{
    238
    239	ACPI_FUNCTION_ENTRY();
    240
    241	/* Clear the status bit */
    242
    243	(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
    244				      status_register_id, ACPI_CLEAR_STATUS);
    245
    246	/*
    247	 * Make sure that a handler exists. If not, report an error
    248	 * and disable the event to prevent further interrupts.
    249	 */
    250	if (!acpi_gbl_fixed_event_handlers[event].handler) {
    251		(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
    252					      enable_register_id,
    253					      ACPI_DISABLE_EVENT);
    254
    255		ACPI_ERROR((AE_INFO,
    256			    "No installed handler for fixed event - %s (%u), disabling",
    257			    acpi_ut_get_event_name(event), event));
    258
    259		return (ACPI_INTERRUPT_NOT_HANDLED);
    260	}
    261
    262	/* Invoke the Fixed Event handler */
    263
    264	return ((acpi_gbl_fixed_event_handlers[event].
    265		 handler) (acpi_gbl_fixed_event_handlers[event].context));
    266}
    267
    268/*******************************************************************************
    269 *
    270 * FUNCTION:    acpi_any_fixed_event_status_set
    271 *
    272 * PARAMETERS:  None
    273 *
    274 * RETURN:      TRUE or FALSE
    275 *
    276 * DESCRIPTION: Checks the PM status register for active fixed events
    277 *
    278 ******************************************************************************/
    279
    280u32 acpi_any_fixed_event_status_set(void)
    281{
    282	acpi_status status;
    283	u32 in_status;
    284	u32 in_enable;
    285	u32 i;
    286
    287	status = acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &in_enable);
    288	if (ACPI_FAILURE(status)) {
    289		return (FALSE);
    290	}
    291
    292	status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &in_status);
    293	if (ACPI_FAILURE(status)) {
    294		return (FALSE);
    295	}
    296
    297	/*
    298	 * Check for all possible Fixed Events and dispatch those that are active
    299	 */
    300	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
    301
    302		/* Both the status and enable bits must be on for this event */
    303
    304		if ((in_status & acpi_gbl_fixed_event_info[i].status_bit_mask) &&
    305		    (in_enable & acpi_gbl_fixed_event_info[i].enable_bit_mask)) {
    306			return (TRUE);
    307		}
    308	}
    309
    310	return (FALSE);
    311}
    312
    313#endif				/* !ACPI_REDUCED_HARDWARE */