summaryrefslogtreecommitdiffstats
path: root/arch/riscv/lib
diff options
context:
space:
mode:
authorAnup Patel <anup@brainfault.org>2018-12-12 06:12:31 -0800
committerAndes <uboot@andestech.com>2018-12-18 09:56:27 +0800
commit511107d85d6f2739a641076acfb5646ba2a19fc8 (patch)
treef71c7e8185c6fe4ae6881e41d811e9d15f25672a /arch/riscv/lib
parent644a3cd77e840d1be6a714b8ce284d6ef3ad2f06 (diff)
downloadu-boot-511107d85d6f2739a641076acfb5646ba2a19fc8.tar.gz
u-boot-511107d85d6f2739a641076acfb5646ba2a19fc8.tar.xz
u-boot-511107d85d6f2739a641076acfb5646ba2a19fc8.zip
riscv: Implement riscv_get_time() API using rdtime instruction
This adds an implementation of riscv_get_time() API that is using rdtime instruction. This is the case for S-mode U-Boot, and is useful for processors that support rdtime in M-mode too. Signed-off-by: Anup Patel <anup@brainfault.org> Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Diffstat (limited to 'arch/riscv/lib')
-rw-r--r--arch/riscv/lib/Makefile1
-rw-r--r--arch/riscv/lib/rdtime.c38
2 files changed, 39 insertions, 0 deletions
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index b13c87661e..edfa61690c 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -9,6 +9,7 @@
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_GO) += boot.o
obj-y += cache.o
+obj-$(CONFIG_RISCV_RDTIME) += rdtime.o
obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o
obj-y += interrupts.o
obj-y += reset.o
diff --git a/arch/riscv/lib/rdtime.c b/arch/riscv/lib/rdtime.c
new file mode 100644
index 0000000000..e128d7fce6
--- /dev/null
+++ b/arch/riscv/lib/rdtime.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Anup Patel <anup@brainfault.org>
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * The riscv_get_time() API implementation that is using the
+ * standard rdtime instruction.
+ */
+
+#include <common.h>
+
+/* Implement the API required by RISC-V timer driver */
+int riscv_get_time(u64 *time)
+{
+#ifdef CONFIG_64BIT
+ u64 n;
+
+ __asm__ __volatile__ (
+ "rdtime %0"
+ : "=r" (n));
+
+ *time = n;
+#else
+ u32 lo, hi, tmp;
+
+ __asm__ __volatile__ (
+ "1:\n"
+ "rdtimeh %0\n"
+ "rdtime %1\n"
+ "rdtimeh %2\n"
+ "bne %0, %2, 1b"
+ : "=&r" (hi), "=&r" (lo), "=&r" (tmp));
+
+ *time = ((u64)hi << 32) | lo;
+#endif
+
+ return 0;
+}