From a4c3733d32a72f11dee86d0731d7565aa6ebe22d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 28 Oct 2019 13:10:32 +0100 Subject: riscv: abstract out CSR names for supervisor vs machine mode Many of the privileged CSRs exist in a supervisor and machine version that are used very similarly. Provide versions of the CSR names and fields that map to either the S-mode or M-mode variant depending on a new CONFIG_RISCV_M_MODE kconfig symbol. Contains contributions from Damien Le Moal and Paul Walmsley . Signed-off-by: Christoph Hellwig Acked-by: Thomas Gleixner # for drivers/clocksource, drivers/irqchip [paul.walmsley@sifive.com: updated to apply] Signed-off-by: Paul Walmsley --- drivers/clocksource/timer-riscv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/clocksource/timer-riscv.c') diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index 470c7ef02ea4..d083bfb535f6 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -19,7 +19,7 @@ static int riscv_clock_next_event(unsigned long delta, struct clock_event_device *ce) { - csr_set(sie, SIE_STIE); + csr_set(CSR_IE, IE_TIE); sbi_set_timer(get_cycles64() + delta); return 0; } @@ -61,13 +61,13 @@ static int riscv_timer_starting_cpu(unsigned int cpu) ce->cpumask = cpumask_of(cpu); clockevents_config_and_register(ce, riscv_timebase, 100, 0x7fffffff); - csr_set(sie, SIE_STIE); + csr_set(CSR_IE, IE_TIE); return 0; } static int riscv_timer_dying_cpu(unsigned int cpu) { - csr_clear(sie, SIE_STIE); + csr_clear(CSR_IE, IE_TIE); return 0; } @@ -76,7 +76,7 @@ void riscv_timer_interrupt(void) { struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event); - csr_clear(sie, SIE_STIE); + csr_clear(CSR_IE, IE_TIE); evdev->event_handler(evdev); } -- cgit v1.2.3 From 4f9bbcefa142862782275a4b29f390ca8d8b9242 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 28 Oct 2019 13:10:37 +0100 Subject: riscv: add support for MMIO access to the timer registers When running in M-mode we can't use the SBI to set the timer, and don't have access to the time CSR as that usually is emulated by M-mode. Instead provide code that directly accesses the MMIO for the timer. Signed-off-by: Christoph Hellwig Reviewed-by: Anup Patel Acked-by: Thomas Gleixner # for drivers/clocksource [paul.walmsley@sifive.com: updated to apply; fixed checkpatch issue; timex.h now includes asm/mmio.h to resolve header file problems] Signed-off-by: Paul Walmsley --- arch/riscv/include/asm/sbi.h | 3 ++- arch/riscv/include/asm/timex.h | 19 +++++++++++++++++-- drivers/clocksource/timer-riscv.c | 23 +++++++++++++++++++---- 3 files changed, 38 insertions(+), 7 deletions(-) (limited to 'drivers/clocksource/timer-riscv.c') diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 204af718df61..8e14d4819d0f 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -95,7 +95,8 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid); } #else /* CONFIG_RISCV_SBI */ -/* stub for code that is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */ +/* stubs for code that is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */ +void sbi_set_timer(uint64_t stime_value); void sbi_remote_fence_i(const unsigned long *hart_mask); #endif /* CONFIG_RISCV_SBI */ #endif /* _ASM_RISCV_SBI_H */ diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h index c7ef131b9e4c..bad2a7c2cda5 100644 --- a/arch/riscv/include/asm/timex.h +++ b/arch/riscv/include/asm/timex.h @@ -7,12 +7,25 @@ #define _ASM_RISCV_TIMEX_H #include +#include typedef unsigned long cycles_t; +extern u64 __iomem *riscv_time_val; +extern u64 __iomem *riscv_time_cmp; + +#ifdef CONFIG_64BIT +#define mmio_get_cycles() readq_relaxed(riscv_time_val) +#else +#define mmio_get_cycles() readl_relaxed(riscv_time_val) +#define mmio_get_cycles_hi() readl_relaxed(((u32 *)riscv_time_val) + 1) +#endif + static inline cycles_t get_cycles(void) { - return csr_read(CSR_TIME); + if (IS_ENABLED(CONFIG_RISCV_SBI)) + return csr_read(CSR_TIME); + return mmio_get_cycles(); } #define get_cycles get_cycles @@ -24,7 +37,9 @@ static inline u64 get_cycles64(void) #else /* CONFIG_64BIT */ static inline u32 get_cycles_hi(void) { - return csr_read(CSR_TIMEH); + if (IS_ENABLED(CONFIG_RISCV_SBI)) + return csr_read(CSR_TIMEH); + return mmio_get_cycles_hi(); } static inline u64 get_cycles64(void) diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index d083bfb535f6..4e54856ce2a5 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -3,9 +3,9 @@ * Copyright (C) 2012 Regents of the University of California * Copyright (C) 2017 SiFive * - * All RISC-V systems have a timer attached to every hart. These timers can be - * read from the "time" and "timeh" CSRs, and can use the SBI to setup - * events. + * All RISC-V systems have a timer attached to every hart. These timers can + * either be read from the "time" and "timeh" CSRs, and can use the SBI to + * setup events, or directly accessed using MMIO registers. */ #include #include @@ -13,14 +13,29 @@ #include #include #include +#include #include #include +u64 __iomem *riscv_time_cmp; +u64 __iomem *riscv_time_val; + +static inline void mmio_set_timer(u64 val) +{ + void __iomem *r; + + r = riscv_time_cmp + cpuid_to_hartid_map(smp_processor_id()); + writeq_relaxed(val, r); +} + static int riscv_clock_next_event(unsigned long delta, struct clock_event_device *ce) { csr_set(CSR_IE, IE_TIE); - sbi_set_timer(get_cycles64() + delta); + if (IS_ENABLED(CONFIG_RISCV_SBI)) + sbi_set_timer(get_cycles64() + delta); + else + mmio_set_timer(get_cycles64() + delta); return 0; } -- cgit v1.2.3 From 9d05c18e8d7de566ff68f221fcae65e78708dd1d Mon Sep 17 00:00:00 2001 From: Zong Li Date: Mon, 23 Dec 2019 16:46:14 +0800 Subject: clocksource: riscv: add notrace to riscv_sched_clock When enabling ftrace graph tracer, it gets the tracing clock in ftrace_push_return_trace(). Eventually, it invokes riscv_sched_clock() to get the clock value. If riscv_sched_clock() isn't marked with 'notrace', it will call ftrace_push_return_trace() and cause infinite loop. The result of failure as follow: command: echo function_graph >current_tracer [ 46.176787] Unable to handle kernel paging request at virtual address ffffffe04fb38c48 [ 46.177309] Oops [#1] [ 46.177478] Modules linked in: [ 46.177770] CPU: 0 PID: 256 Comm: $d Not tainted 5.5.0-rc1 #47 [ 46.177981] epc: ffffffe00035e59a ra : ffffffe00035e57e sp : ffffffe03a7569b0 [ 46.178216] gp : ffffffe000d29b90 tp : ffffffe03a756180 t0 : ffffffe03a756968 [ 46.178430] t1 : ffffffe00087f408 t2 : ffffffe03a7569a0 s0 : ffffffe03a7569f0 [ 46.178643] s1 : ffffffe00087f408 a0 : 0000000ac054cda4 a1 : 000000000087f411 [ 46.178856] a2 : 0000000ac054cda4 a3 : 0000000000373ca0 a4 : ffffffe04fb38c48 [ 46.179099] a5 : 00000000153e22a8 a6 : 00000000005522ff a7 : 0000000000000005 [ 46.179338] s2 : ffffffe03a756a90 s3 : ffffffe00032811c s4 : ffffffe03a756a58 [ 46.179570] s5 : ffffffe000d29fe0 s6 : 0000000000000001 s7 : 0000000000000003 [ 46.179809] s8 : 0000000000000003 s9 : 0000000000000002 s10: 0000000000000004 [ 46.180053] s11: 0000000000000000 t3 : 0000003fc815749c t4 : 00000000000efc90 [ 46.180293] t5 : ffffffe000d29658 t6 : 0000000000040000 [ 46.180482] status: 0000000000000100 badaddr: ffffffe04fb38c48 cause: 000000000000000f Signed-off-by: Zong Li Reviewed-by: Steven Rostedt (VMware) [paul.walmsley@sifive.com: cleaned up patch description] Fixes: 92e0d143fdef ("clocksource/drivers/riscv_timer: Provide the sched_clock") Cc: stable@vger.kernel.org Signed-off-by: Paul Walmsley --- drivers/clocksource/timer-riscv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clocksource/timer-riscv.c') diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index 4e54856ce2a5..c4f15c4068c0 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -56,7 +56,7 @@ static unsigned long long riscv_clocksource_rdtime(struct clocksource *cs) return get_cycles64(); } -static u64 riscv_sched_clock(void) +static u64 notrace riscv_sched_clock(void) { return get_cycles64(); } -- cgit v1.2.3