Enable Xen to handle timer reprogramming on RISC-V using standard SBI calls.
Add a RISC-V implementation of reprogram_timer() to replace the stub: - Re-enable the function previously stubbed in stubs.c. - Use sbi_set_timer() to program the timer for the given timeout. - Disable the timer when timeout == 0 by clearing the SIE.STIE bit. - Calculate the deadline based on the current boot clock cycle count and timer ticks. - Ensure correct behavior when the deadline is already passed. Signed-off-by: Oleksii Kurochko <[email protected]> --- xen/arch/riscv/stubs.c | 5 ----- xen/arch/riscv/time.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/xen/arch/riscv/stubs.c b/xen/arch/riscv/stubs.c index 68ee859ca1a8..d120274af2fe 100644 --- a/xen/arch/riscv/stubs.c +++ b/xen/arch/riscv/stubs.c @@ -21,11 +21,6 @@ nodemask_t __read_mostly node_online_map = { { [0] = 1UL } }; /* time.c */ -int reprogram_timer(s_time_t timeout) -{ - BUG_ON("unimplemented"); -} - void send_timer_event(struct vcpu *v) { BUG_ON("unimplemented"); diff --git a/xen/arch/riscv/time.c b/xen/arch/riscv/time.c index e962f8518d78..53ba1cfb4a99 100644 --- a/xen/arch/riscv/time.c +++ b/xen/arch/riscv/time.c @@ -4,8 +4,12 @@ #include <xen/init.h> #include <xen/lib.h> #include <xen/sections.h> +#include <xen/time.h> #include <xen/types.h> +#include <asm/csr.h> +#include <asm/sbi.h> + unsigned long __ro_after_init cpu_khz; /* CPU clock frequency in kHz. */ uint64_t __ro_after_init boot_clock_cycles; @@ -39,6 +43,33 @@ static void __init preinit_dt_xen_time(void) cpu_khz = rate / 1000; } +int reprogram_timer(s_time_t timeout) +{ + uint64_t deadline, now; + int rc; + + if ( timeout == 0 ) + { + /* Disable timers */ + csr_clear(CSR_SIE, BIT(IRQ_S_TIMER, UL)); + + return 1; + } + + deadline = ns_to_ticks(timeout) + boot_clock_cycles; + now = get_cycles(); + if ( deadline <= now ) + return 0; + + /* Enable timer */ + csr_set(CSR_SIE, BIT(IRQ_S_TIMER, UL)); + + if ( (rc = sbi_set_timer(deadline)) ) + panic("%s: timer wasn't set because: %d\n", __func__, rc); + + return 1; +} + void __init preinit_xen_time(void) { if ( acpi_disabled ) -- 2.52.0
