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

hwt.c (5099B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/******************************************************************************
      3 *
      4 *	(C)Copyright 1998,1999 SysKonnect,
      5 *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
      6 *
      7 *	See the file "skfddi.c" for further information.
      8 *
      9 *	The information in this file is provided "AS IS" without warranty.
     10 *
     11 ******************************************************************************/
     12
     13/*
     14 * Timer Driver for FBI board (timer chip 82C54)
     15 */
     16
     17/*
     18 * Modifications:
     19 *
     20 *	28-Jun-1994 sw	Edit v1.6.
     21 *			MCA: Added support for the SK-NET FDDI-FM2 adapter. The
     22 *			 following functions have been added(+) or modified(*):
     23 *			 hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*)
     24 */
     25
     26#include "h/types.h"
     27#include "h/fddi.h"
     28#include "h/smc.h"
     29
     30/*
     31 * Prototypes of local functions.
     32 */
     33/* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
     34/*static void hwt_restart() ; */
     35
     36/************************
     37 *
     38 *	hwt_start
     39 *
     40 *	Start hardware timer (clock ticks are 16us).
     41 *
     42 *	void hwt_start(
     43 *		struct s_smc *smc,
     44 *		u_long time) ;
     45 * In
     46 *	smc - A pointer to the SMT Context structure.
     47 *
     48 *	time - The time in units of 16us to load the timer with.
     49 * Out
     50 *	Nothing.
     51 *
     52 ************************/
     53#define	HWT_MAX	(65000)
     54
     55void hwt_start(struct s_smc *smc, u_long time)
     56{
     57	u_short	cnt ;
     58
     59	if (time > HWT_MAX)
     60		time = HWT_MAX ;
     61
     62	smc->hw.t_start = time ;
     63	smc->hw.t_stop = 0L ;
     64
     65	cnt = (u_short)time ;
     66	/*
     67	 * if time < 16 us
     68	 *	time = 16 us
     69	 */
     70	if (!cnt)
     71		cnt++ ;
     72
     73	outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ;	/* Load timer value. */
     74	outpw(ADDR(B2_TI_CRTL), TIM_START) ;		/* Start timer. */
     75
     76	smc->hw.timer_activ = TRUE ;
     77}
     78
     79/************************
     80 *
     81 *	hwt_stop
     82 *
     83 *	Stop hardware timer.
     84 *
     85 *	void hwt_stop(
     86 *		struct s_smc *smc) ;
     87 * In
     88 *	smc - A pointer to the SMT Context structure.
     89 * Out
     90 *	Nothing.
     91 *
     92 ************************/
     93void hwt_stop(struct s_smc *smc)
     94{
     95	outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
     96	outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
     97
     98	smc->hw.timer_activ = FALSE ;
     99}
    100
    101/************************
    102 *
    103 *	hwt_init
    104 *
    105 *	Initialize hardware timer.
    106 *
    107 *	void hwt_init(
    108 *		struct s_smc *smc) ;
    109 * In
    110 *	smc - A pointer to the SMT Context structure.
    111 * Out
    112 *	Nothing.
    113 *
    114 ************************/
    115void hwt_init(struct s_smc *smc)
    116{
    117	smc->hw.t_start = 0 ;
    118	smc->hw.t_stop	= 0 ;
    119	smc->hw.timer_activ = FALSE ;
    120
    121	hwt_restart(smc) ;
    122}
    123
    124/************************
    125 *
    126 *	hwt_restart
    127 *
    128 *	Clear timer interrupt.
    129 *
    130 *	void hwt_restart(
    131 *		struct s_smc *smc) ;
    132 * In
    133 *	smc - A pointer to the SMT Context structure.
    134 * Out
    135 *	Nothing.
    136 *
    137 ************************/
    138void hwt_restart(struct s_smc *smc)
    139{
    140	hwt_stop(smc) ;
    141}
    142
    143/************************
    144 *
    145 *	hwt_read
    146 *
    147 *	Stop hardware timer and read time elapsed since last start.
    148 *
    149 *	u_long hwt_read(smc) ;
    150 * In
    151 *	smc - A pointer to the SMT Context structure.
    152 * Out
    153 *	The elapsed time since last start in units of 16us.
    154 *
    155 ************************/
    156u_long hwt_read(struct s_smc *smc)
    157{
    158	u_short	tr ;
    159	u_long	is ;
    160
    161	if (smc->hw.timer_activ) {
    162		hwt_stop(smc) ;
    163		tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
    164
    165		is = GET_ISR() ;
    166		/* Check if timer expired (or wraparound). */
    167		if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
    168			hwt_restart(smc) ;
    169			smc->hw.t_stop = smc->hw.t_start ;
    170		}
    171		else
    172			smc->hw.t_stop = smc->hw.t_start - tr ;
    173	}
    174	return smc->hw.t_stop;
    175}
    176
    177#ifdef	PCI
    178/************************
    179 *
    180 *	hwt_quick_read
    181 *
    182 *	Stop hardware timer and read timer value and start the timer again.
    183 *
    184 *	u_long hwt_read(smc) ;
    185 * In
    186 *	smc - A pointer to the SMT Context structure.
    187 * Out
    188 *	current timer value in units of 80ns.
    189 *
    190 ************************/
    191u_long hwt_quick_read(struct s_smc *smc)
    192{
    193	u_long interval ;
    194	u_long time ;
    195
    196	interval = inpd(ADDR(B2_TI_INI)) ;
    197	outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
    198	time = inpd(ADDR(B2_TI_VAL)) ;
    199	outpd(ADDR(B2_TI_INI),time) ;
    200	outpw(ADDR(B2_TI_CRTL), TIM_START) ;
    201	outpd(ADDR(B2_TI_INI),interval) ;
    202
    203	return time;
    204}
    205
    206/************************
    207 *
    208 *	hwt_wait_time(smc,start,duration)
    209 *
    210 *	This function returnes after the amount of time is elapsed
    211 *	since the start time.
    212 * 
    213 * para	start		start time
    214 *	duration	time to wait
    215 *
    216 * NOTE: The function will return immediately, if the timer is not
    217 *	 started
    218 ************************/
    219void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
    220{
    221	long	diff ;
    222	long	interval ;
    223	int	wrapped ;
    224
    225	/*
    226	 * check if timer is running
    227	 */
    228	if (smc->hw.timer_activ == FALSE ||
    229		hwt_quick_read(smc) == hwt_quick_read(smc)) {
    230		return ;
    231	}
    232
    233	interval = inpd(ADDR(B2_TI_INI)) ;
    234	if (interval > duration) {
    235		do {
    236			diff = (long)(start - hwt_quick_read(smc)) ;
    237			if (diff < 0) {
    238				diff += interval ;
    239			}
    240		} while (diff <= duration) ;
    241	}
    242	else {
    243		diff = interval ;
    244		wrapped = 0 ;
    245		do {
    246			if (!wrapped) {
    247				if (hwt_quick_read(smc) >= start) {
    248					diff += interval ;
    249					wrapped = 1 ;
    250				}
    251			}
    252			else {
    253				if (hwt_quick_read(smc) < start) {
    254					wrapped = 0 ;
    255				}
    256			}
    257		} while (diff <= duration) ;
    258	}
    259}
    260#endif
    261