summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sbi/sbi_timer.h18
-rw-r--r--lib/sbi/sbi_timer.c13
2 files changed, 31 insertions, 0 deletions
diff --git a/include/sbi/sbi_timer.h b/include/sbi/sbi_timer.h
index 63ef1af..ac48e2b 100644
--- a/include/sbi/sbi_timer.h
+++ b/include/sbi/sbi_timer.h
@@ -48,6 +48,24 @@ static inline void sbi_timer_udelay(ulong usecs)
sbi_timer_delay_loop(usecs, 1000000, NULL, NULL);
}
+/**
+ * A blocking function that will wait until @p predicate returns true or
+ * @p timeout_ms milliseconds elapsed. @p arg will be passed as argument to
+ * @p predicate function.
+ *
+ * @param predicate Pointer to a function that returns true if certain
+ * condition is met. It shouldn't block the code execution.
+ * @param arg Argument to pass to @p predicate.
+ * @param timeout_ms Timeout value in milliseconds. The function will return
+ * false if @p timeout_ms time period elapsed but still @p predicate doesn't
+ * return true.
+ *
+ * @return true if @p predicate returns true within @p timeout_ms, false
+ * otherwise.
+ */
+bool sbi_timer_waitms_until(bool (*predicate)(void *), void *arg,
+ uint64_t timeout_ms);
+
/** Get timer value for current HART */
u64 sbi_timer_value(void);
diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c
index b0a6e63..4b24cbe 100644
--- a/lib/sbi/sbi_timer.c
+++ b/lib/sbi/sbi_timer.c
@@ -76,6 +76,19 @@ void sbi_timer_delay_loop(ulong units, u64 unit_freq,
delay_fn(opaque);
}
+bool sbi_timer_waitms_until(bool (*predicate)(void *), void *arg,
+ uint64_t timeout_ms)
+{
+ uint64_t start_time = sbi_timer_value();
+ uint64_t ticks =
+ (sbi_timer_get_device()->timer_freq / 1000) *
+ timeout_ms;
+ while(!predicate(arg))
+ if (sbi_timer_value() - start_time >= ticks)
+ return false;
+ return true;
+}
+
u64 sbi_timer_value(void)
{
if (get_time_val)