mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/riscv: introduce sbi_set_timer()
Introduce a function pointer for sbi_set_timer(), since different OpenSBI versions may implement the TIME extension with different extension IDs and/or function IDs. If the TIME extension is not available, fall back to the legacy timer mechanism. This is useful when Xen runs as a guest under another Xen, because the TIME extension is not currently virtualised and therefore will not appear as available. Despite of the fact that sbi_set_timer_v01 is introduced and used as fall back, SBI v0.1 still isn't fully supported (with the current SBI calls usage, sbi_rfence_v01 should be introduced too), so panic() in sbi_init() isn't removed. The sbi_set_timer() pointer will be used by reprogram_timer() to program Xen’s physical timer as without SSTC extension there is no any other option except SBI call to do that as only M-timer is available for us. Use dprintk() for all the cases to print that a speicifc SBI extension is available as it isn't really necessary in case of release builds. Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
647542cdf1
commit
e56decd0a2
2 files changed
+61
-1
No files matched your search
@@ -13,6 +13,7 @@
|
||||
#define ASM__RISCV__SBI_H
|
||||
|
||||
#include <xen/cpumask.h>
|
||||
#include <xen/sections.h>
|
||||
|
||||
/* SBI-defined implementation ID */
|
||||
#define SBI_XEN_IMPID 7
|
||||
@@ -29,6 +30,7 @@
|
||||
|
||||
#define SBI_EXT_BASE 0x10
|
||||
#define SBI_EXT_RFENCE 0x52464E43
|
||||
#define SBI_EXT_TIME 0x54494D45
|
||||
|
||||
/* SBI function IDs for BASE extension */
|
||||
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
|
||||
@@ -48,6 +50,9 @@
|
||||
#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5
|
||||
#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6
|
||||
|
||||
/* SBI function IDs for TIME extension */
|
||||
#define SBI_EXT_TIME_SET_TIMER 0x0
|
||||
|
||||
#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f000000
|
||||
#define SBI_SPEC_VERSION_MINOR_MASK 0x00ffffff
|
||||
|
||||
@@ -134,6 +139,23 @@ int sbi_remote_hfence_gvma(const cpumask_t *cpu_mask, vaddr_t start,
|
||||
int sbi_remote_hfence_gvma_vmid(const cpumask_t *cpu_mask, vaddr_t start,
|
||||
size_t size, unsigned long vmid);
|
||||
|
||||
/*
|
||||
* Programs the clock for next event at (or after) stime_value. stime_value is
|
||||
* in absolute time. This function must clear the pending timer interrupt bit
|
||||
* as well.
|
||||
*
|
||||
* If the supervisor wishes to clear the timer interrupt without scheduling the
|
||||
* next timer event, it can either request a timer interrupt infinitely far
|
||||
* into the future (i.e., (uint64_t)-1), or it can instead mask the timer
|
||||
* interrupt by clearing sie.STIE CSR bit.
|
||||
*
|
||||
* The stime_value parameter represents absolute time measured in ticks.
|
||||
*
|
||||
* This SBI call returns 0 upon success or an implementation specific negative
|
||||
* error code.
|
||||
*/
|
||||
extern int (* __ro_after_init sbi_set_timer)(uint64_t stime_value);
|
||||
|
||||
/*
|
||||
* Initialize SBI library
|
||||
*
|
||||
|
||||
+39
-1
@@ -249,6 +249,38 @@ static int (* __ro_after_init sbi_rfence)(unsigned long fid,
|
||||
unsigned long arg4,
|
||||
unsigned long arg5);
|
||||
|
||||
static int cf_check sbi_set_timer_v02(uint64_t stime_value)
|
||||
{
|
||||
struct sbiret ret;
|
||||
|
||||
ret = sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value,
|
||||
#ifdef CONFIG_RISCV_32
|
||||
stime_value >> 32,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
0, 0, 0, 0);
|
||||
|
||||
return sbi_err_map_xen_errno(ret.error);
|
||||
}
|
||||
|
||||
static int cf_check sbi_set_timer_v01(uint64_t stime_value)
|
||||
{
|
||||
struct sbiret ret;
|
||||
|
||||
ret = sbi_ecall(SBI_EXT_0_1_SET_TIMER, 0, stime_value,
|
||||
#ifdef CONFIG_RISCV_32
|
||||
stime_value >> 32,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
0, 0, 0, 0);
|
||||
|
||||
return sbi_err_map_xen_errno(ret.error);
|
||||
}
|
||||
|
||||
int (* __ro_after_init sbi_set_timer)(uint64_t stime_value) = sbi_set_timer_v01;
|
||||
|
||||
int sbi_remote_sfence_vma(const cpumask_t *cpu_mask, vaddr_t start,
|
||||
size_t size)
|
||||
{
|
||||
@@ -324,7 +356,13 @@ int __init sbi_init(void)
|
||||
if ( sbi_probe_extension(SBI_EXT_RFENCE) > 0 )
|
||||
{
|
||||
sbi_rfence = sbi_rfence_v02;
|
||||
printk("SBI v0.2 RFENCE extension detected\n");
|
||||
dprintk(XENLOG_INFO, "SBI v0.2 RFENCE extension detected\n");
|
||||
}
|
||||
|
||||
if ( sbi_probe_extension(SBI_EXT_TIME) > 0 )
|
||||
{
|
||||
sbi_set_timer = sbi_set_timer_v02;
|
||||
dprintk(XENLOG_INFO, "SBI v0.2 TIME extension detected\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||