diff mbox series

[RFC,v1,09/20] arch: x86: Add TSC to ART translation

Message ID 20210824164801.28896-10-lakshmi.sowjanya.d@intel.com
State New
Headers show
Series Review Request: Add support for Intel PMC | expand

Commit Message

D, Lakshmi Sowjanya Aug. 24, 2021, 4:47 p.m. UTC
From: Lakshmi Sowjanya D <lakshmi.sowjanya.d@intel.com>

Add a function to convert TSC(Time Stamp Capture) time to ART.

The Intel(R) PMC Timed I/O device uses ART to trigger output events.

The TSC to ART translation converts the TSC value yielded by
ktime_convert_real_to_system_counter() to ART. The conversion is
required to program the COMPV register that will be compared against
the art time to generate output events.

Co-developed-by: Christopher Hall <christopher.s.hall@intel.com>
Signed-off-by: Christopher Hall <christopher.s.hall@intel.com>
Signed-off-by: Tamal Saha <tamal.saha@intel.com>
Signed-off-by: Lakshmi Sowjanya D <lakshmi.sowjanya.d@intel.com>
Reviewed-by: Mark Gross <mgross@linux.intel.com>
---
 arch/x86/include/asm/tsc.h |  3 +++
 arch/x86/kernel/tsc.c      | 35 ++++++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index a50b0102e5c1..f1de7ede3ec9 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -8,6 +8,8 @@ 
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
 
+struct system_counterval_t;
+
 /*
  * Standard way to access the cycle counter.
  */
@@ -29,6 +31,7 @@  static inline cycles_t get_cycles(void)
 }
 
 extern u64 read_art_time(void);
+extern int convert_tsc_to_art(const struct system_counterval_t *tsc, u64 *art);
 extern struct system_counterval_t convert_art_to_tsc(u64 art);
 extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns);
 
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index bbab6cf1a73b..040109228100 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1231,22 +1231,43 @@  int unsynchronized_tsc(void)
 }
 
 /*
- * Converts the current TSC to the current ART value using conversion
+ * Converts input TSC to the corresponding ART value using conversion
  * factors discovered by detect_art()
  */
-u64 read_art_time(void)
+int convert_tsc_to_art(const struct system_counterval_t *system_counter, u64 *art)
 {
-	u64 tsc, tmp, res, rem;
+	u64 tmp, res, rem;
+
+	if (system_counter->cs != art_related_clocksource)
+		return -EINVAL;
 
-	tsc = read_tsc(NULL) - art_to_tsc_offset;
-	rem = do_div(tsc, art_to_tsc_numerator);
+	res = system_counter->cycles - art_to_tsc_offset;
+	rem = do_div(res, art_to_tsc_numerator);
 
-	res = tsc * art_to_tsc_denominator;
+	*art = res * art_to_tsc_denominator;
 	tmp = rem * art_to_tsc_denominator;
 
 	do_div(tmp, art_to_tsc_numerator);
+	*art += tmp;
+
+	return 0;
+}
+EXPORT_SYMBOL(convert_tsc_to_art);
+
+/*
+ * Converts the current TSC to the current ART value using conversion
+ * factors discovered by detect_art()
+ */
+u64 read_art_time(void)
+{
+	struct system_counterval_t tsc;
+	u64 art = 0;
+
+	tsc.cs = art_related_clocksource;
+	tsc.cycles = read_tsc(NULL);
+	convert_tsc_to_art(&tsc, &art);
 
-	return res + tmp;
+	return art;
 }
 EXPORT_SYMBOL(read_art_time);