[PATCH 4/5] lib: sbi: Add generic timer delay loop function

Bin Meng bmeng.cn at gmail.com
Thu Sep 16 00:33:27 PDT 2021


On Wed, Sep 15, 2021 at 5:22 PM Anup Patel <anup.patel at wdc.com> wrote:
>
> We now have frequency of the timer device provided by the platform
> support so we can emulate desired delay using a loop where the number
> loop iterations are based on timer frequency.
>
> This patch provides sbi_timer_delay_loop() for above purpose.
>
> Signed-off-by: Anup Patel <anup.patel at wdc.com>
> ---
>  include/sbi/sbi_timer.h | 16 ++++++++++++++++
>  lib/sbi/sbi_timer.c     | 31 +++++++++++++++++++++++++++++++
>  2 files changed, 47 insertions(+)
>
> diff --git a/include/sbi/sbi_timer.h b/include/sbi/sbi_timer.h
> index 211e83d..63ef1af 100644
> --- a/include/sbi/sbi_timer.h
> +++ b/include/sbi/sbi_timer.h
> @@ -32,6 +32,22 @@ struct sbi_timer_device {
>
>  struct sbi_scratch;
>
> +/** Generic delay loop of desired granularity */
> +void sbi_timer_delay_loop(ulong units, u64 unit_freq,
> +                         void (*delay_fn)(void *), void *opaque);
> +
> +/** Provide delay in terms of milliseconds */
> +static inline void sbi_timer_mdelay(ulong msecs)
> +{
> +       sbi_timer_delay_loop(msecs, 1000, NULL, NULL);
> +}
> +
> +/** Provide delay in terms of microseconds */
> +static inline void sbi_timer_udelay(ulong usecs)
> +{
> +       sbi_timer_delay_loop(usecs, 1000000, NULL, NULL);
> +}
> +
>  /** 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 2759501..0bf91bb 100644
> --- a/lib/sbi/sbi_timer.c
> +++ b/lib/sbi/sbi_timer.c
> @@ -8,6 +8,7 @@
>   */
>
>  #include <sbi/riscv_asm.h>
> +#include <sbi/riscv_barrier.h>
>  #include <sbi/riscv_encoding.h>
>  #include <sbi/sbi_error.h>
>  #include <sbi/sbi_hart.h>
> @@ -47,6 +48,36 @@ static u64 get_platform_ticks(void)
>         return timer_dev->timer_value();
>  }
>
> +static void nop_delay_fn(void *opaque)
> +{
> +       cpu_relax();
> +}
> +
> +void sbi_timer_delay_loop(ulong units, u64 unit_freq,
> +                         void (*delay_fn)(void *), void *opaque)
> +{
> +       u64 start_val, delta;
> +
> +       /* Do nothing if we don't have timer device */
> +       if (!timer_dev || !get_time_val)

Should we output a warning here?

> +               return;
> +
> +       /* Compute desired timer value delta */
> +       delta = ((u64)timer_dev->timer_freq * (u64)units);
> +       delta = delta / unit_freq;
> +
> +       /* Save starting timer value */
> +       start_val = get_time_val();
> +
> +       /* 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 */
> +       while ((get_time_val() - start_val) < delta)
> +               delay_fn(opaque);
> +}
> +
>  u64 sbi_timer_value(void)
>  {
>         if (get_time_val)
> --
>

Reviewed-by: Bin Meng <bmeng.cn at gmail.com>



More information about the opensbi mailing list