[v2,03/24] eal/loongarch: add cpu cycle operations for LoongArch
Checks
Commit Message
This patch adds architecture specific cpu cycle operations for
LoongArch. The RDTIME.D instruction is used to read constant
frequency timer information including counter value. The CPUCFG
instruction is used to dynamically identify which features of
LoongArch are implemented in the running processor during the
execution of the software. We can use this instruction to calculate
the frequency used by the timer.
Signed-off-by: Min Zhou <zhoumin@loongson.cn>
---
lib/eal/loongarch/include/rte_cycles.h | 53 ++++++++++++++++++++++++++
lib/eal/loongarch/rte_cycles.c | 45 ++++++++++++++++++++++
2 files changed, 98 insertions(+)
create mode 100644 lib/eal/loongarch/include/rte_cycles.h
create mode 100644 lib/eal/loongarch/rte_cycles.c
new file mode 100644
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_CYCLES_LOONGARCH_H_
+#define _RTE_CYCLES_LOONGARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_cycles.h"
+
+static inline uint64_t
+get_cycle_count(void)
+{
+ uint64_t count;
+
+ __asm__ __volatile__ (
+ "rdtime.d %[cycles], $zero\n"
+ : [cycles] "=r" (count)
+ ::
+ );
+ return count;
+}
+
+/**
+ * Read the time base register.
+ *
+ * @return
+ * The time base for this lcore.
+ */
+static inline uint64_t
+rte_rdtsc(void)
+{
+ return get_cycle_count();
+}
+
+static inline uint64_t
+rte_rdtsc_precise(void)
+{
+ rte_mb();
+ return rte_rdtsc();
+}
+
+static inline uint64_t
+rte_get_tsc_cycles(void) { return rte_rdtsc(); }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CYCLES_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#include "eal_private.h"
+
+#define LOONGARCH_CPUCFG4 0x4
+#define CPUCFG4_CCFREQ_MASK 0xFFFFFFFF
+#define CPUCFG4_CCFREQ_SHIFT 0
+
+#define LOONGARCH_CPUCFG5 0x5
+#define CPUCFG5_CCMUL_MASK 0xFFFF
+#define CPUCFG5_CCMUL_SHIFT 0
+
+#define CPUCFG5_CCDIV_MASK 0xFFFF0000
+#define CPUCFG5_CCDIV_SHIFT 16
+
+static __rte_noinline uint32_t
+read_cpucfg(int arg)
+{
+ int ret = 0;
+
+ __asm__ __volatile__ (
+ "cpucfg %[var], %[index]\n"
+ : [var]"=r"(ret)
+ : [index]"r"(arg)
+ :
+ );
+
+ return ret;
+}
+
+uint64_t
+get_tsc_freq_arch(void)
+{
+ uint32_t base_freq, mul_factor, div_factor;
+
+ base_freq = read_cpucfg(LOONGARCH_CPUCFG4);
+ mul_factor = (read_cpucfg(LOONGARCH_CPUCFG5) & CPUCFG5_CCMUL_MASK) >>
+ CPUCFG5_CCMUL_SHIFT;
+ div_factor = (read_cpucfg(LOONGARCH_CPUCFG5) & CPUCFG5_CCDIV_MASK) >>
+ CPUCFG5_CCDIV_SHIFT;
+
+ return base_freq * mul_factor / div_factor;
+}