diff options
author | Anup Patel <anup.patel@wdc.com> | 2019-08-18 13:14:44 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2019-09-30 15:36:14 +0530 |
commit | 1e9f88889f8b7c66dd229299715eed87e734aafa (patch) | |
tree | 8c1619786e090dfc7cbb57223ac3edda86607ec5 /lib/sbi/sbi_timer.c | |
parent | 7d4420bd6929ef3f2c761c262dbc3f7f2ae150c2 (diff) |
lib: Emulate HTIMEDELTA CSR for platforms not having TIME CSR
For platforms not having TIME CSR, we trap-n-emulate TIME CSR
read/write in OpenSBI. Same rationale applies to HTIMEDELTA CSR
as well so we trap-n-emulate HTIMEDELTA CSR for platforms not
having TIME CSR.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Diffstat (limited to 'lib/sbi/sbi_timer.c')
-rw-r--r-- | lib/sbi/sbi_timer.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c index c58441d..1ba386f 100644 --- a/lib/sbi/sbi_timer.c +++ b/lib/sbi/sbi_timer.c @@ -9,9 +9,12 @@ #include <sbi/riscv_asm.h> #include <sbi/riscv_encoding.h> +#include <sbi/sbi_error.h> #include <sbi/sbi_platform.h> #include <sbi/sbi_timer.h> +static unsigned long time_delta_off; + #if __riscv_xlen == 32 u64 get_ticks(void) { @@ -44,6 +47,35 @@ u64 sbi_timer_value(struct sbi_scratch *scratch) return get_ticks(); } +u64 sbi_timer_virt_value(struct sbi_scratch *scratch) +{ + u64 *time_delta = sbi_scratch_offset_ptr(scratch, time_delta_off); + + return sbi_timer_value(scratch) + *time_delta; +} + +u64 sbi_timer_get_delta(struct sbi_scratch *scratch) +{ + u64 *time_delta = sbi_scratch_offset_ptr(scratch, time_delta_off); + + return *time_delta; +} + +void sbi_timer_set_delta(struct sbi_scratch *scratch, ulong delta) +{ + u64 *time_delta = sbi_scratch_offset_ptr(scratch, time_delta_off); + + *time_delta = (u64)delta; +} + +void sbi_timer_set_delta_upper(struct sbi_scratch *scratch, ulong delta_upper) +{ + u64 *time_delta = sbi_scratch_offset_ptr(scratch, time_delta_off); + + *time_delta &= 0xffffffffULL; + *time_delta |= ((u64)delta_upper << 32); +} + void sbi_timer_event_stop(struct sbi_scratch *scratch) { sbi_platform_timer_event_stop(sbi_platform_ptr(scratch)); @@ -64,5 +96,20 @@ void sbi_timer_process(struct sbi_scratch *scratch) int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot) { + u64 *time_delta; + + if (cold_boot) { + time_delta_off = sbi_scratch_alloc_offset(sizeof(*time_delta), + "TIME_DELTA"); + if (!time_delta_off) + return SBI_ENOMEM; + } else { + if (!time_delta_off) + return SBI_ENOMEM; + } + + time_delta = sbi_scratch_offset_ptr(scratch, time_delta_off); + *time_delta = 0; + return sbi_platform_timer_init(sbi_platform_ptr(scratch), cold_boot); } |