summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sbi/sbi_timer.h27
-rw-r--r--lib/sbi/sbi_timer.c14
2 files changed, 37 insertions, 4 deletions
diff --git a/include/sbi/sbi_timer.h b/include/sbi/sbi_timer.h
index 914a5f12..2a040927 100644
--- a/include/sbi/sbi_timer.h
+++ b/include/sbi/sbi_timer.h
@@ -88,6 +88,21 @@ struct sbi_timer_device {
struct sbi_scratch;
+/** Compute timer value delta based on arbitary units */
+u64 sbi_timer_compute_delta(ulong units, u64 unit_freq);
+
+/** Compute timer value delta from milliseconds */
+static inline u64 sbi_timer_compute_mdelta(ulong msecs)
+{
+ return sbi_timer_compute_delta(msecs, 1000);
+}
+
+/** Compute timer value delta from microseconds */
+static inline u64 sbi_timer_compute_udelta(ulong usecs)
+{
+ return sbi_timer_compute_delta(usecs, 1000000);
+}
+
/** Generic delay loop of desired granularity */
void sbi_timer_delay_loop(ulong units, u64 unit_freq,
void (*delay_fn)(void *), void *opaque);
@@ -125,6 +140,18 @@ bool sbi_timer_waitms_until(bool (*predicate)(void *), void *arg,
/** Get timer value for current HART */
u64 sbi_timer_value(void);
+/** Compute timer value after specified milliseconds */
+static inline u64 sbi_timer_value_after_msecs(ulong msecs)
+{
+ return sbi_timer_value() + sbi_timer_compute_mdelta(msecs);
+}
+
+/** Compute timer value after specified microseconds */
+static inline u64 sbi_timer_value_after_usecs(ulong usecs)
+{
+ return sbi_timer_value() + sbi_timer_compute_udelta(usecs);
+}
+
/** Get virtualized timer value for current HART */
u64 sbi_timer_virt_value(void);
diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c
index 70b8b5d2..4d737d22 100644
--- a/lib/sbi/sbi_timer.c
+++ b/lib/sbi/sbi_timer.c
@@ -58,6 +58,15 @@ static void nop_delay_fn(void *opaque)
cpu_relax();
}
+u64 sbi_timer_compute_delta(ulong units, u64 unit_freq)
+{
+ u64 delta;
+
+ delta = ((u64)timer_dev->timer_freq * (u64)units);
+ delta = delta / unit_freq;
+ return delta;
+}
+
void sbi_timer_delay_loop(ulong units, u64 unit_freq,
void (*delay_fn)(void *), void *opaque)
{
@@ -72,15 +81,12 @@ void sbi_timer_delay_loop(ulong units, u64 unit_freq,
/* Save starting timer value */
start_val = get_time_val();
- /* Compute desired timer value delta */
- delta = ((u64)timer_dev->timer_freq * (u64)units);
- delta = delta / unit_freq;
-
/* Use NOP delay function if delay function not available */
if (!delay_fn)
delay_fn = nop_delay_fn;
/* Busy loop until desired timer value delta reached */
+ delta = sbi_timer_compute_delta(units, unit_freq);
while ((get_time_val() - start_val) < delta)
delay_fn(opaque);
}