brintos

brintos / linux-shallow public Read only

0
0
Text · 3.0 KiB · bf461de Raw
159 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * ARM Generic Timer specific interface4 */5 6#ifndef SELFTEST_KVM_ARCH_TIMER_H7#define SELFTEST_KVM_ARCH_TIMER_H8 9#include "processor.h"10 11enum arch_timer {12	VIRTUAL,13	PHYSICAL,14};15 16#define CTL_ENABLE	(1 << 0)17#define CTL_IMASK	(1 << 1)18#define CTL_ISTATUS	(1 << 2)19 20#define msec_to_cycles(msec)	\21	(timer_get_cntfrq() * (uint64_t)(msec) / 1000)22 23#define usec_to_cycles(usec)	\24	(timer_get_cntfrq() * (uint64_t)(usec) / 1000000)25 26#define cycles_to_usec(cycles) \27	((uint64_t)(cycles) * 1000000 / timer_get_cntfrq())28 29static inline uint32_t timer_get_cntfrq(void)30{31	return read_sysreg(cntfrq_el0);32}33 34static inline uint64_t timer_get_cntct(enum arch_timer timer)35{36	isb();37 38	switch (timer) {39	case VIRTUAL:40		return read_sysreg(cntvct_el0);41	case PHYSICAL:42		return read_sysreg(cntpct_el0);43	default:44		GUEST_FAIL("Unexpected timer type = %u", timer);45	}46 47	/* We should not reach here */48	return 0;49}50 51static inline void timer_set_cval(enum arch_timer timer, uint64_t cval)52{53	switch (timer) {54	case VIRTUAL:55		write_sysreg(cval, cntv_cval_el0);56		break;57	case PHYSICAL:58		write_sysreg(cval, cntp_cval_el0);59		break;60	default:61		GUEST_FAIL("Unexpected timer type = %u", timer);62	}63 64	isb();65}66 67static inline uint64_t timer_get_cval(enum arch_timer timer)68{69	switch (timer) {70	case VIRTUAL:71		return read_sysreg(cntv_cval_el0);72	case PHYSICAL:73		return read_sysreg(cntp_cval_el0);74	default:75		GUEST_FAIL("Unexpected timer type = %u", timer);76	}77 78	/* We should not reach here */79	return 0;80}81 82static inline void timer_set_tval(enum arch_timer timer, int32_t tval)83{84	switch (timer) {85	case VIRTUAL:86		write_sysreg(tval, cntv_tval_el0);87		break;88	case PHYSICAL:89		write_sysreg(tval, cntp_tval_el0);90		break;91	default:92		GUEST_FAIL("Unexpected timer type = %u", timer);93	}94 95	isb();96}97 98static inline int32_t timer_get_tval(enum arch_timer timer)99{100	isb();101	switch (timer) {102	case VIRTUAL:103		return read_sysreg(cntv_tval_el0);104	case PHYSICAL:105		return read_sysreg(cntp_tval_el0);106	default:107		GUEST_FAIL("Could not get timer %d\n", timer);108	}109 110	/* We should not reach here */111	return 0;112}113 114static inline void timer_set_ctl(enum arch_timer timer, uint32_t ctl)115{116	switch (timer) {117	case VIRTUAL:118		write_sysreg(ctl, cntv_ctl_el0);119		break;120	case PHYSICAL:121		write_sysreg(ctl, cntp_ctl_el0);122		break;123	default:124		GUEST_FAIL("Unexpected timer type = %u", timer);125	}126 127	isb();128}129 130static inline uint32_t timer_get_ctl(enum arch_timer timer)131{132	switch (timer) {133	case VIRTUAL:134		return read_sysreg(cntv_ctl_el0);135	case PHYSICAL:136		return read_sysreg(cntp_ctl_el0);137	default:138		GUEST_FAIL("Unexpected timer type = %u", timer);139	}140 141	/* We should not reach here */142	return 0;143}144 145static inline void timer_set_next_cval_ms(enum arch_timer timer, uint32_t msec)146{147	uint64_t now_ct = timer_get_cntct(timer);148	uint64_t next_ct = now_ct + msec_to_cycles(msec);149 150	timer_set_cval(timer, next_ct);151}152 153static inline void timer_set_next_tval_ms(enum arch_timer timer, uint32_t msec)154{155	timer_set_tval(timer, msec_to_cycles(msec));156}157 158#endif /* SELFTEST_KVM_ARCH_TIMER_H */159