[U-Boot,v2,09/20] riscv: Implement riscv_get_time() API using rdtime instruction

Message ID 1544192072-28764-10-git-send-email-bmeng.cn@gmail.com
State Superseded
Delegated to: Andes
Headers show
Series
  • riscv: Adding RISC-V CPU and timer driver
Related show

Commit Message

Bin Meng Dec. 7, 2018, 2:14 p.m.
From: Anup Patel <anup@brainfault.org>

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>

---

Changes in v2:
- incorporated and reworked Anup's S-mode timer patch
  @ http://patchwork.ozlabs.org/patch/1006663/

 arch/riscv/Kconfig      |  8 ++++++++
 arch/riscv/lib/Makefile |  1 +
 arch/riscv/lib/rdtime.c | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+)
 create mode 100644 arch/riscv/lib/rdtime.c

Comments

Auer, Lukas Dec. 10, 2018, 11:36 p.m. | #1
On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
> From: Anup Patel <anup@brainfault.org>
> 
> 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>
> 
> ---
> 
> Changes in v2:
> - incorporated and reworked Anup's S-mode timer patch
>   @ http://patchwork.ozlabs.org/patch/1006663/
> 
>  arch/riscv/Kconfig      |  8 ++++++++
>  arch/riscv/lib/Makefile |  1 +
>  arch/riscv/lib/rdtime.c | 36 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 45 insertions(+)
>  create mode 100644 arch/riscv/lib/rdtime.c
> 

Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index f513f52..7dc6e3f 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -104,4 +104,12 @@  config SIFIVE_CLINT
 	  The SiFive CLINT block holds memory-mapped control and status registers
 	  associated with software and timer interrupts.
 
+config RISCV_RDTIME
+	bool
+	default y if RISCV_SMODE
+	help
+	  The provides the riscv_get_time() API that is implemented using the
+	  standard rdtime instruction. This is the case for S-mode U-Boot, and
+	  is useful for processors that support rdtime in M-mode too.
+
 endmenu
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index b13c876..edfa616 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 0000000..b16680f
--- /dev/null
+++ b/arch/riscv/lib/rdtime.c
@@ -0,0 +1,36 @@ 
+// 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 */
+u64 riscv_get_time(void)
+{
+#ifdef CONFIG_64BIT
+	u64 n;
+
+	__asm__ __volatile__ (
+		"rdtime %0"
+		: "=r" (n));
+
+	return 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));
+
+	return ((u64)hi << 32) | lo;
+#endif
+}