[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