diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sbi/sbi_platform.c | 3 | ||||
-rw-r--r-- | lib/sbi/sbi_timer.c | 55 | ||||
-rw-r--r-- | lib/utils/sys/clint.c | 22 | ||||
-rw-r--r-- | lib/utils/timer/fdt_timer.c | 31 | ||||
-rw-r--r-- | lib/utils/timer/fdt_timer_clint.c | 3 |
5 files changed, 53 insertions, 61 deletions
diff --git a/lib/sbi/sbi_platform.c b/lib/sbi/sbi_platform.c index 568d956..e78119a 100644 --- a/lib/sbi/sbi_platform.c +++ b/lib/sbi/sbi_platform.c @@ -19,9 +19,6 @@ static inline char *sbi_platform_feature_id2string(unsigned long feature) return NULL; switch (feature) { - case SBI_PLATFORM_HAS_TIMER_VALUE: - fstr = "timer"; - break; case SBI_PLATFORM_HAS_HART_HOTPLUG: fstr = "hotplug"; break; diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c index b571b17..63e8ea9 100644 --- a/lib/sbi/sbi_timer.c +++ b/lib/sbi/sbi_timer.c @@ -16,10 +16,11 @@ #include <sbi/sbi_timer.h> static unsigned long time_delta_off; -static u64 (*get_time_val)(const struct sbi_platform *plat); +static u64 (*get_time_val)(void); +static const struct sbi_timer_device *timer_dev = NULL; #if __riscv_xlen == 32 -static u64 get_ticks(const struct sbi_platform *plat) +static u64 get_ticks(void) { u32 lo, hi, tmp; __asm__ __volatile__("1:\n" @@ -31,7 +32,7 @@ static u64 get_ticks(const struct sbi_platform *plat) return ((u64)hi << 32) | lo; } #else -static u64 get_ticks(const struct sbi_platform *plat) +static u64 get_ticks(void) { unsigned long n; @@ -40,9 +41,16 @@ static u64 get_ticks(const struct sbi_platform *plat) } #endif +static u64 get_platform_ticks(void) +{ + return timer_dev->timer_value(); +} + u64 sbi_timer_value(void) { - return get_time_val(sbi_platform_thishart_ptr()); + if (get_time_val) + return get_time_val(); + return 0; } u64 sbi_timer_virt_value(void) @@ -80,7 +88,8 @@ void sbi_timer_set_delta_upper(ulong delta_upper) void sbi_timer_event_start(u64 next_event) { - sbi_platform_timer_event_start(sbi_platform_thishart_ptr(), next_event); + if (timer_dev && timer_dev->timer_event_start) + timer_dev->timer_event_start(next_event); csr_clear(CSR_MIP, MIP_STIP); csr_set(CSR_MIE, MIP_MTIP); } @@ -91,17 +100,34 @@ void sbi_timer_process(void) csr_set(CSR_MIP, MIP_STIP); } +const struct sbi_timer_device *sbi_timer_get_device(void) +{ + return timer_dev; +} + +void sbi_timer_set_device(const struct sbi_timer_device *dev) +{ + if (!dev || timer_dev) + return; + + timer_dev = dev; + if (!get_time_val && timer_dev->timer_value) + get_time_val = get_platform_ticks; +} + int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot) { u64 *time_delta; const struct sbi_platform *plat = sbi_platform_ptr(scratch); - int ret; if (cold_boot) { time_delta_off = sbi_scratch_alloc_offset(sizeof(*time_delta), "TIME_DELTA"); if (!time_delta_off) return SBI_ENOMEM; + + if (sbi_hart_has_feature(scratch, SBI_HART_HAS_TIME)) + get_time_val = get_ticks; } else { if (!time_delta_off) return SBI_ENOMEM; @@ -110,24 +136,13 @@ int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot) time_delta = sbi_scratch_offset_ptr(scratch, time_delta_off); *time_delta = 0; - ret = sbi_platform_timer_init(plat, cold_boot); - if (ret) - return ret; - - if (sbi_hart_has_feature(scratch, SBI_HART_HAS_TIME)) - get_time_val = get_ticks; - else if (sbi_platform_has_timer_value(plat)) - get_time_val = sbi_platform_timer_value; - else - /* There is no method to provide timer value */ - return SBI_ENODEV; - - return 0; + return sbi_platform_timer_init(plat, cold_boot); } void sbi_timer_exit(struct sbi_scratch *scratch) { - sbi_platform_timer_event_stop(sbi_platform_ptr(scratch)); + if (timer_dev && timer_dev->timer_event_stop) + timer_dev->timer_event_stop(); csr_clear(CSR_MIP, MIP_STIP); csr_clear(CSR_MIE, MIP_MTIP); diff --git a/lib/utils/sys/clint.c b/lib/utils/sys/clint.c index 80e04fb..4b1963a 100644 --- a/lib/utils/sys/clint.c +++ b/lib/utils/sys/clint.c @@ -13,6 +13,7 @@ #include <sbi/sbi_domain.h> #include <sbi/sbi_error.h> #include <sbi/sbi_hartmask.h> +#include <sbi/sbi_timer.h> #include <sbi_utils/sys/clint.h> #define CLINT_IPI_OFF 0 @@ -118,7 +119,7 @@ static void clint_time_wr32(u64 value, volatile u64 *addr) writel_relaxed(value >> 32, (void *)(addr) + 0x04); } -u64 clint_timer_value(void) +static u64 clint_timer_value(void) { struct clint_data *clint = clint_timer_hartid2data[current_hartid()]; @@ -126,7 +127,7 @@ u64 clint_timer_value(void) return clint->time_rd(clint->time_val) + clint->time_delta; } -void clint_timer_event_stop(void) +static void clint_timer_event_stop(void) { u32 target_hart = current_hartid(); struct clint_data *clint = clint_timer_hartid2data[target_hart]; @@ -136,7 +137,7 @@ void clint_timer_event_stop(void) &clint->time_cmp[target_hart - clint->first_hartid]); } -void clint_timer_event_start(u64 next_event) +static void clint_timer_event_start(u64 next_event) { u32 target_hart = current_hartid(); struct clint_data *clint = clint_timer_hartid2data[target_hart]; @@ -146,6 +147,13 @@ void clint_timer_event_start(u64 next_event) &clint->time_cmp[target_hart - clint->first_hartid]); } +static struct sbi_timer_device clint_timer = { + .name = "clint", + .timer_value = clint_timer_value, + .timer_event_start = clint_timer_event_start, + .timer_event_stop = clint_timer_event_stop +}; + int clint_warm_timer_init(void) { u64 v1, v2, mv; @@ -224,5 +232,11 @@ int clint_cold_timer_init(struct clint_data *clint, sbi_domain_memregion_init(clint->addr + CLINT_TIME_CMP_OFF, CLINT_TIME_CMP_SIZE, SBI_DOMAIN_MEMREGION_MMIO, ®); - return sbi_domain_root_add_memregion(®); + rc = sbi_domain_root_add_memregion(®); + if (rc) + return rc; + + sbi_timer_set_device(&clint_timer); + + return 0; } diff --git a/lib/utils/timer/fdt_timer.c b/lib/utils/timer/fdt_timer.c index d1d0e0c..92198cd 100644 --- a/lib/utils/timer/fdt_timer.c +++ b/lib/utils/timer/fdt_timer.c @@ -17,46 +17,15 @@ static struct fdt_timer *timer_drivers[] = { &fdt_timer_clint }; -static u64 dummy_value(void) -{ - return 0; -} - -static void dummy_event_stop(void) -{ -} - -static void dummy_event_start(u64 next_event) -{ -} - static struct fdt_timer dummy = { .match_table = NULL, .cold_init = NULL, .warm_init = NULL, .exit = NULL, - .value = dummy_value, - .event_stop = dummy_event_stop, - .event_start = dummy_event_start }; static struct fdt_timer *current_driver = &dummy; -u64 fdt_timer_value(void) -{ - return current_driver->value(); -} - -void fdt_timer_event_stop(void) -{ - current_driver->event_stop(); -} - -void fdt_timer_event_start(u64 next_event) -{ - current_driver->event_start(next_event); -} - void fdt_timer_exit(void) { if (current_driver->exit) diff --git a/lib/utils/timer/fdt_timer_clint.c b/lib/utils/timer/fdt_timer_clint.c index 6ba6c7b..0352e53 100644 --- a/lib/utils/timer/fdt_timer_clint.c +++ b/lib/utils/timer/fdt_timer_clint.c @@ -47,7 +47,4 @@ struct fdt_timer fdt_timer_clint = { .cold_init = timer_clint_cold_init, .warm_init = clint_warm_timer_init, .exit = NULL, - .value = clint_timer_value, - .event_stop = clint_timer_event_stop, - .event_start = clint_timer_event_start, }; |