mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 11:26:12 +08:00
arch/riscv: Fixed hardware timer warps-around issue
This commit fixed the issue where the hardware timer wraps around and causes the system to halt. Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit is contained in:
committed by
Xiang Xiao
parent
908df725ad
commit
733a68002c
@@ -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 *priv =
|
||||||
(struct riscv_mtimer_lowerhalf_s *)lower;
|
(struct riscv_mtimer_lowerhalf_s *)lower;
|
||||||
uint64_t mtime = riscv_mtimer_get_mtime(priv);
|
irqstate_t flags;
|
||||||
uint64_t alarm = mtime + ts->tv_sec * priv->freq +
|
uint64_t mtime;
|
||||||
ts->tv_nsec * priv->freq / NSEC_PER_SEC;
|
uint64_t alarm;
|
||||||
|
|
||||||
if (alarm < mtime)
|
flags = up_irq_save();
|
||||||
{
|
|
||||||
priv->alarm = UINT64_MAX;
|
|
||||||
priv->callback = NULL;
|
|
||||||
priv->arg = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
priv->alarm = alarm;
|
|
||||||
priv->callback = callback;
|
|
||||||
priv->arg = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!up_interrupt_context())
|
mtime = riscv_mtimer_get_mtime(priv);
|
||||||
{
|
alarm = mtime + ts->tv_sec * priv->freq +
|
||||||
riscv_mtimer_set_mtimecmp(priv, priv->alarm);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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 *priv =
|
||||||
(struct riscv_mtimer_lowerhalf_s *)lower;
|
(struct riscv_mtimer_lowerhalf_s *)lower;
|
||||||
uint64_t mtime;
|
uint64_t mtime;
|
||||||
uint64_t alarm = priv->alarm;
|
uint64_t alarm;
|
||||||
|
uint64_t nsec;
|
||||||
|
irqstate_t flags;
|
||||||
|
|
||||||
priv->alarm = UINT64_MAX;
|
flags = up_irq_save();
|
||||||
if (!up_interrupt_context())
|
|
||||||
{
|
alarm = priv->alarm;
|
||||||
riscv_mtimer_set_mtimecmp(priv, priv->alarm);
|
|
||||||
}
|
|
||||||
|
|
||||||
mtime = riscv_mtimer_get_mtime(priv);
|
mtime = riscv_mtimer_get_mtime(priv);
|
||||||
if (alarm > mtime)
|
|
||||||
{
|
riscv_mtimer_set_mtimecmp(priv, mtime + UINT64_MAX);
|
||||||
uint64_t nsec = (alarm - mtime) * NSEC_PER_SEC / priv->freq;
|
|
||||||
ts->tv_sec = nsec / NSEC_PER_SEC;
|
nsec = (alarm - mtime) * NSEC_PER_SEC / priv->freq;
|
||||||
ts->tv_nsec = nsec % NSEC_PER_SEC;
|
ts->tv_sec = nsec / NSEC_PER_SEC;
|
||||||
}
|
ts->tv_nsec = nsec % NSEC_PER_SEC;
|
||||||
else
|
|
||||||
{
|
|
||||||
ts->tv_sec = 0;
|
|
||||||
ts->tv_nsec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->alarm = 0;
|
priv->alarm = 0;
|
||||||
priv->callback = NULL;
|
priv->callback = NULL;
|
||||||
priv->arg = NULL;
|
priv->arg = NULL;
|
||||||
|
|
||||||
|
up_irq_restore(flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,14 +324,11 @@ static int riscv_mtimer_interrupt(int irq, void *context, void *arg)
|
|||||||
{
|
{
|
||||||
struct riscv_mtimer_lowerhalf_s *priv = arg;
|
struct riscv_mtimer_lowerhalf_s *priv = arg;
|
||||||
|
|
||||||
priv->alarm = UINT64_MAX;
|
|
||||||
|
|
||||||
if (priv->callback != NULL)
|
if (priv->callback != NULL)
|
||||||
{
|
{
|
||||||
priv->callback(&priv->lower, priv->arg);
|
priv->callback(&priv->lower, priv->arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
riscv_mtimer_set_mtimecmp(priv, priv->alarm);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user