VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   35 Branches   59 Tags
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000   1) /* SPDX-License-Identifier: GPL-2.0 */
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000   2) 
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000   3) /*
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000   4)  * Definitions for the clocksource provided by the Hyper-V
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000   5)  * hypervisor to guest VMs, as described in the Hyper-V Top
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000   6)  * Level Functional Spec (TLFS).
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000   7)  *
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000   8)  * Copyright (C) 2019, Microsoft, Inc.
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000   9)  *
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  10)  * Author:  Michael Kelley <mikelley@microsoft.com>
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  11)  */
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  12) 
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  13) #ifndef __CLKSOURCE_HYPERV_TIMER_H
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  14) #define __CLKSOURCE_HYPERV_TIMER_H
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  15) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  16) #include <linux/clocksource.h>
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  17) #include <linux/math64.h>
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  18) #include <asm/mshyperv.h>
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  19) 
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  20) #define HV_MAX_MAX_DELTA_TICKS 0xffffffff
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  21) #define HV_MIN_DELTA_TICKS 1
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  22) 
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  23) /* Routines called by the VMbus driver */
ec866be6ec547 (Michael Kelley   2021-03-02 13:38:22 -0800  24) extern int hv_stimer_alloc(bool have_percpu_irqs);
4df4cb9e99f83 (Michael Kelley   2019-11-13 01:11:49 +0000  25) extern int hv_stimer_cleanup(unsigned int cpu);
4df4cb9e99f83 (Michael Kelley   2019-11-13 01:11:49 +0000  26) extern void hv_stimer_legacy_init(unsigned int cpu, int sint);
4df4cb9e99f83 (Michael Kelley   2019-11-13 01:11:49 +0000  27) extern void hv_stimer_legacy_cleanup(unsigned int cpu);
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  28) extern void hv_stimer_global_cleanup(void);
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  29) extern void hv_stimer0_isr(void);
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000  30) 
3e2d94535adb2 (Vitaly Kuznetsov 2019-08-22 10:36:30 +0200  31) #ifdef CONFIG_HYPERV_TIMER
0af3e137c1443 (Andrea Parri     2020-01-09 17:06:49 +0100  32) extern u64 (*hv_read_reference_counter)(void);
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  33) extern void hv_init_clocksource(void);
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  34) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  35) extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  36) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  37) static inline notrace u64
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  38) hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, u64 *cur_tsc)
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  39) {
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  40) 	u64 scale, offset;
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  41) 	u32 sequence;
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  42) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  43) 	/*
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  44) 	 * The protocol for reading Hyper-V TSC page is specified in Hypervisor
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  45) 	 * Top-Level Functional Specification ver. 3.0 and above. To get the
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  46) 	 * reference time we must do the following:
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  47) 	 * - READ ReferenceTscSequence
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  48) 	 *   A special '0' value indicates the time source is unreliable and we
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  49) 	 *   need to use something else. The currently published specification
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  50) 	 *   versions (up to 4.0b) contain a mistake and wrongly claim '-1'
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  51) 	 *   instead of '0' as the special value, see commit c35b82ef0294.
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  52) 	 * - ReferenceTime =
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  53) 	 *        ((RDTSC() * ReferenceTscScale) >> 64) + ReferenceTscOffset
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  54) 	 * - READ ReferenceTscSequence again. In case its value has changed
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  55) 	 *   since our first reading we need to discard ReferenceTime and repeat
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  56) 	 *   the whole sequence as the hypervisor was updating the page in
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  57) 	 *   between.
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  58) 	 */
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  59) 	do {
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  60) 		sequence = READ_ONCE(tsc_pg->tsc_sequence);
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  61) 		if (!sequence)
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  62) 			return U64_MAX;
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  63) 		/*
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  64) 		 * Make sure we read sequence before we read other values from
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  65) 		 * TSC page.
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  66) 		 */
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  67) 		smp_rmb();
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  68) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  69) 		scale = READ_ONCE(tsc_pg->tsc_scale);
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  70) 		offset = READ_ONCE(tsc_pg->tsc_offset);
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  71) 		*cur_tsc = hv_get_raw_timer();
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  72) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  73) 		/*
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  74) 		 * Make sure we read sequence after we read all other values
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  75) 		 * from TSC page.
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  76) 		 */
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  77) 		smp_rmb();
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  78) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  79) 	} while (READ_ONCE(tsc_pg->tsc_sequence) != sequence);
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  80) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  81) 	return mul_u64_u64_shr(*cur_tsc, scale, 64) + offset;
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  82) }
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  83) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  84) static inline notrace u64
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  85) hv_read_tsc_page(const struct ms_hyperv_tsc_page *tsc_pg)
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  86) {
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  87) 	u64 cur_tsc;
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  88) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  89) 	return hv_read_tsc_page_tsc(tsc_pg, &cur_tsc);
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  90) }
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  91) 
3e2d94535adb2 (Vitaly Kuznetsov 2019-08-22 10:36:30 +0200  92) #else /* CONFIG_HYPERV_TIMER */
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  93) static inline struct ms_hyperv_tsc_page *hv_get_tsc_page(void)
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  94) {
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  95) 	return NULL;
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  96) }
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  97) 
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  98) static inline u64 hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg,
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000  99) 				       u64 *cur_tsc)
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000 100) {
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000 101) 	return U64_MAX;
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000 102) }
3e2d94535adb2 (Vitaly Kuznetsov 2019-08-22 10:36:30 +0200 103) #endif /* CONFIG_HYPERV_TIMER */
dd2cb348613b4 (Michael Kelley   2019-07-01 04:26:06 +0000 104) 
fd1fea6834d0f (Michael Kelley   2019-07-01 04:25:56 +0000 105) #endif