Skip to content

Commit

Permalink
arch/riscv: Fixed hardware timer warps-around issue
Browse files Browse the repository at this point in the history
This commit fixed the issue where the hardware timer wraps around and causes the system to halt.

Signed-off-by: ouyangxiangzhen <[email protected]>
  • Loading branch information
Fix-Point authored and xiaoxiang781216 committed Sep 13, 2024
1 parent 908df72 commit 733a680
Showing 1 changed file with 28 additions and 39 deletions.
67 changes: 28 additions & 39 deletions arch/risc-v/src/common/riscv_mtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,28 +211,23 @@ static int riscv_mtimer_start(struct oneshot_lowerhalf_s *lower,
{
struct riscv_mtimer_lowerhalf_s *priv =
(struct riscv_mtimer_lowerhalf_s *)lower;
uint64_t mtime = riscv_mtimer_get_mtime(priv);
uint64_t alarm = mtime + ts->tv_sec * priv->freq +
ts->tv_nsec * priv->freq / NSEC_PER_SEC;
irqstate_t flags;
uint64_t mtime;
uint64_t alarm;

if (alarm < mtime)
{
priv->alarm = UINT64_MAX;
priv->callback = NULL;
priv->arg = NULL;
}
else
{
priv->alarm = alarm;
priv->callback = callback;
priv->arg = arg;
}
flags = up_irq_save();

if (!up_interrupt_context())
{
riscv_mtimer_set_mtimecmp(priv, priv->alarm);
}
mtime = riscv_mtimer_get_mtime(priv);
alarm = mtime + ts->tv_sec * priv->freq +
ts->tv_nsec * priv->freq / NSEC_PER_SEC;

priv->alarm = alarm;
priv->callback = callback;
priv->arg = arg;

riscv_mtimer_set_mtimecmp(priv, priv->alarm);

up_irq_restore(flags);
return 0;
}

Expand Down Expand Up @@ -266,31 +261,28 @@ static int riscv_mtimer_cancel(struct oneshot_lowerhalf_s *lower,
struct riscv_mtimer_lowerhalf_s *priv =
(struct riscv_mtimer_lowerhalf_s *)lower;
uint64_t mtime;
uint64_t alarm = priv->alarm;
uint64_t alarm;
uint64_t nsec;
irqstate_t flags;

priv->alarm = UINT64_MAX;
if (!up_interrupt_context())
{
riscv_mtimer_set_mtimecmp(priv, priv->alarm);
}
flags = up_irq_save();

alarm = priv->alarm;

mtime = riscv_mtimer_get_mtime(priv);
if (alarm > mtime)
{
uint64_t nsec = (alarm - mtime) * NSEC_PER_SEC / priv->freq;
ts->tv_sec = nsec / NSEC_PER_SEC;
ts->tv_nsec = nsec % NSEC_PER_SEC;
}
else
{
ts->tv_sec = 0;
ts->tv_nsec = 0;
}

riscv_mtimer_set_mtimecmp(priv, mtime + UINT64_MAX);

nsec = (alarm - mtime) * NSEC_PER_SEC / priv->freq;
ts->tv_sec = nsec / NSEC_PER_SEC;
ts->tv_nsec = nsec % NSEC_PER_SEC;

priv->alarm = 0;
priv->callback = NULL;
priv->arg = NULL;

up_irq_restore(flags);

return 0;
}

Expand Down Expand Up @@ -332,14 +324,11 @@ static int riscv_mtimer_interrupt(int irq, void *context, void *arg)
{
struct riscv_mtimer_lowerhalf_s *priv = arg;

priv->alarm = UINT64_MAX;

if (priv->callback != NULL)
{
priv->callback(&priv->lower, priv->arg);
}

riscv_mtimer_set_mtimecmp(priv, priv->alarm);
return 0;
}

Expand Down

0 comments on commit 733a680

Please sign in to comment.