[PATCH] RISC-V: Resurrect the MMIO timer implementation for M-mode systems
Palmer Dabbelt
palmerdabbelt at google.com
Fri Sep 18 22:54:14 EDT 2020
On Mon, 14 Sep 2020 19:11:46 PDT (-0700), Anup Patel wrote:
>
>
>> -----Original Message-----
>> From: Palmer Dabbelt <palmerdabbelt at google.com>
>> Sent: 14 September 2020 22:27
>> To: linux-riscv at lists.infradead.org
>> Cc: hch at infradead.org; Anup Patel <Anup.Patel at wdc.com>; Palmer Dabbelt
>> <palmerdabbelt at google.com>; kernel-team at android.com
>> Subject: [PATCH] RISC-V: Resurrect the MMIO timer implementation for M-
>> mode systems
>>
>> The K210 doesn't implement rdtime in M-mode, and since that's where Linux
>> runs in the NOMMU systems that means we can't use rdtime. The K210 is
>> the only system that anyone is currently running NOMMU or M-mode on, so
>> here we're just inlining the timer read directly.
>>
>> Signed-off-by: Palmer Dabbelt <palmerdabbelt at google.com>
>> ---
>> I don't actually have a K210 so I haven't tested this. If nobody else has the
>> time to I'll put together a QEMU that doesn't support rdtime in M-mode, but
>> I've yet to mess around with the !MMU stuff so that might take a little while.
>> This certainly doesn't seem worse than what's there right now, though, as
>> rdtime isn't valid in M-mode on the K210 (our only M-mode platform).
>
> I think you missed my comments in the previous email thread.
>
> I would request to make this patch bit more CLINT independent.
>
> Please see inline below.
>
>> ---
>> arch/riscv/include/asm/clint.h | 26 ++++++++++++++++++++++++++
>> arch/riscv/include/asm/timex.h | 27 +++++++++++++++++++++++++++
>> drivers/clocksource/timer-clint.c | 17 +++++++++++++++++
>> 3 files changed, 70 insertions(+)
>> create mode 100644 arch/riscv/include/asm/clint.h
>>
>> diff --git a/arch/riscv/include/asm/clint.h b/arch/riscv/include/asm/clint.h
>> new file mode 100644 index 000000000000..0789fd37b40a
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/clint.h
>> @@ -0,0 +1,26 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (C) 2020 Google, Inc
>> + */
>> +
>> +#ifndef _ASM_RISCV_CLINT_H
>> +#define _ASM_RISCV_CLINT_H
>> +
>> +#include <linux/types.h>
>> +#include <asm/mmio.h>
>> +
>> +#ifdef CONFIG_RISCV_M_MODE
>> +/*
>> + * This lives in the CLINT driver, but is accessed directly by timex.h
>> +to avoid
>> + * any overhead when accessing the MMIO timer.
>> + *
>> + * The ISA defines mtime as a 64-bit memory-mapped register that
>> +increments at
>> + * a constant frequency, but it doesn't define some other constraints
>> +we depend
>> + * on (most notably ordering constraints, but also some simpler stuff
>> +like the
>> + * memory layout). Thus, this is called "clint_time_val" instead of
>> +something
>> + * like "riscv_mtime", to signify that these non-ISA assumptions must hold.
>> + */
>> +extern u64 __iomem *clint_time_val;
>> +#endif
>> +
>> +#endif
>> diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h
>> index a3fb85d505d4..7f659dda0032 100644
>> --- a/arch/riscv/include/asm/timex.h
>> +++ b/arch/riscv/include/asm/timex.h
>> @@ -10,6 +10,31 @@
>>
>> typedef unsigned long cycles_t;
>
> The entire asm/clint.h can be avoided by adding
> "extern u64 __iomem *riscv_mmio_time_val;"
> here in n asm/timex.h
>
> Also, this will make it bit more CLINT independent.
Except that, as per the comments, it's not CLINT independent.
>> +#ifdef CONFIG_RISCV_M_MODE
>> +
>> +#include <asm/clint.h>
>> +
>> +#ifdef CONFIG_64BIT
>> +static inline cycles_t get_cycles(void) {
>> + return readq_relaxed(clint_time_val);
>> +}
>> +#else /* !CONFIG_64BIT */
>> +static inline u32 get_cycles(void)
>> +{
>> + return readl_relaxed(((u32 *)clint_time_val)); } #define get_cycles
>> +get_cycles
>> +
>> +static inline u32 get_cycles_hi(void)
>> +{
>> + return readl_relaxed(((u32 *)clint_time_val) + 1); } #define
>> +get_cycles_hi get_cycles_hi #endif /* CONFIG_64BIT */
>
> Use riscv_mmio_time_val instead of clint_time_val above.
>
>> +
>> +#else /* CONFIG_RISCV_M_MODE */
>> +
>> static inline cycles_t get_cycles(void) {
>> return csr_read(CSR_TIME);
>> @@ -41,6 +66,8 @@ static inline u64 get_cycles64(void) } #endif /*
>> CONFIG_64BIT */
>>
>> +#endif /* !CONFIG_RISCV_M_MODE */
>> +
>> #define ARCH_HAS_READ_CURRENT_TIMER
>> static inline int read_current_timer(unsigned long *timer_val) { diff --git
>> a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c
>> index 8eeafa82c03d..d17367dee02c 100644
>> --- a/drivers/clocksource/timer-clint.c
>> +++ b/drivers/clocksource/timer-clint.c
>> @@ -19,6 +19,11 @@
>> #include <linux/interrupt.h>
>> #include <linux/of_irq.h>
>> #include <linux/smp.h>
>> +#include <linux/timex.h>
>> +
>> +#ifndef CONFIG_RISCV_M_MODE
>> +#include <asm/clint.h>
>> +#endif
>
> As-per, above suggestion drop this #include.
>
>>
>> #define CLINT_IPI_OFF 0
>> #define CLINT_TIMER_CMP_OFF 0x4000
>> @@ -31,6 +36,10 @@ static u64 __iomem *clint_timer_val; static unsigned
>> long clint_timer_freq; static unsigned int clint_timer_irq;
>>
>> +#ifdef CONFIG_RISCV_M_MODE
>> +u64 __iomem *clint_time_val;
>> +#endif
>
> Define and export "u64 __iomem *riscv_mmio_time_val" in
> arch/riscv/kernel/time.c
>
> This way no "clint_time_val" definition required here as well
> and other MMIO timers can also set riscv_mmio_time_val.
>
>> +
>> static void clint_send_ipi(const struct cpumask *target) {
>> unsigned int cpu;
>> @@ -184,6 +193,14 @@ static int __init clint_timer_init_dt(struct
>> device_node *np)
>> clint_timer_val = base + CLINT_TIMER_VAL_OFF;
>> clint_timer_freq = riscv_timebase;
>>
>> +#ifdef CONFIG_RISCV_M_MODE
>> + /*
>> + * Yes, that's an odd naming scheme. time_val is public, but
>> hopefully
>> + * will die in favor of something cleaner.
>> + */
>> + clint_time_val = clint_timer_val;
>> +#endif
>> +
>
> Just set " riscv_mmio_time_val = clint_timer_val" here.
>
>> pr_info("%pOFP: timer running at %ld Hz\n", np, clint_timer_freq);
>>
>> rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq);
>> --
>> 2.28.0.618.gf4bc123cb7-goog
>
> Regards,
> Anup
More information about the linux-riscv
mailing list