[U-Boot] [PATCH v7 4/4] RISC-V: Add S-mode timer implementation

Anup Patel anup at brainfault.org
Mon Dec 3 05:27:43 UTC 2018


When running in S-mode, we can use rdtime and rdtimeh instructions
for reading timer ticks (just like Linux). The frequency of timer
ticks is passed by prior booting stages in "timebase-frequency" DT
property of the "/cpus" DT node.

This patch provides a generic timer implementation for U-Boot
running in S-mode. For U-Boot running in M-mode, specific timer
drivers will have to be provided.

Signed-off-by: Anup Patel <anup at brainfault.org>
---
 arch/Kconfig            |  1 -
 arch/riscv/Kconfig      | 22 +++++++++++----
 arch/riscv/lib/Makefile |  1 +
 arch/riscv/lib/time.c   | 60 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 6 deletions(-)
 create mode 100644 arch/riscv/lib/time.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 9fdd2f7e66..a4fcb3522d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -72,7 +72,6 @@ config RISCV
 	imply BLK
 	imply CLK
 	imply MTD
-	imply TIMER
 	imply CMD_DM
 
 config SANDBOX
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 732a357a99..20a060454b 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -44,6 +44,23 @@ config ARCH_RV64I
 
 endchoice
 
+choice
+	prompt "Run Mode"
+	default RISCV_MMODE
+
+config RISCV_MMODE
+	bool "Machine"
+	select TIMER
+	help
+	   Choose this option to build U-Boot for RISC-V M-Mode.
+
+config RISCV_SMODE
+	bool "Supervisor"
+	help
+	   Choose this option to build U-Boot for RISC-V S-Mode.
+
+endchoice
+
 config RISCV_ISA_C
 	bool "Emit compressed instructions"
 	default y
@@ -55,11 +72,6 @@ config RISCV_ISA_C
 config RISCV_ISA_A
 	def_bool y
 
-config RISCV_SMODE
-	bool "Run in S-Mode"
-	help
-	  Enable this option to build U-Boot for RISC-V S-Mode
-
 config 32BIT
 	bool
 
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index b58db89752..98aa6d40e7 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -12,6 +12,7 @@ obj-y	+= cache.o
 obj-y	+= interrupts.o
 obj-y	+= reset.o
 obj-y   += setjmp.o
+obj-$(CONFIG_RISCV_SMODE) += time.o
 
 # For building EFI apps
 CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
diff --git a/arch/riscv/lib/time.c b/arch/riscv/lib/time.c
new file mode 100644
index 0000000000..077e568ca6
--- /dev/null
+++ b/arch/riscv/lib/time.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Anup Patel <anup at brainfault.org>
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static unsigned int tbclk;
+
+static void setup_tbclk(void)
+{
+	int cpus;
+
+	if (!gd->fdt_blob || tbclk)
+		return;
+
+	cpus = fdt_path_offset(gd->fdt_blob, "/cpus");
+	if (cpus < 0) {
+		debug("%s: Missing /cpus node\n", __func__);
+		return;
+	}
+
+	tbclk = fdtdec_get_int(gd->fdt_blob, cpus,
+			       "timebase-frequency", 1000000);
+}
+
+ulong notrace get_tbclk(void)
+{
+	setup_tbclk();
+
+	return tbclk;
+}
+
+#ifdef CONFIG_64BIT
+uint64_t notrace get_ticks(void)
+{
+	unsigned long n;
+
+	__asm__ __volatile__ (
+		"rdtime %0"
+		: "=r" (n));
+	return n;
+}
+#else
+uint64_t notrace get_ticks(void)
+{
+	uint32_t 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 ((uint64_t)hi << 32) | lo;
+}
+#endif
-- 
2.17.1



More information about the U-Boot mailing list