blob: a86120b51916dd92e09c06060596439dd95cb9f1 [file] [log] [blame]
// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT
#pragma once
#include "plic.h"
#include "thread.h"
#include <platform-timer.hh>
#include <stdint.h>
#include <tick_macros.h>
#include <utils.hh>
namespace
{
/**
* Concept for the interface to setting the system timer.
*/
template<typename T>
concept IsTimer = requires(uint32_t cycles)
{
{T::init()};
{T::setnext(cycles)};
};
static_assert(
IsTimer<TimerCore>,
"Platform's timer implementation does not meet the required interface");
class Timer final : private TimerCore
{
public:
static void interrupt_setup()
{
static_assert(TIMERCYCLES_PER_TICK <= UINT32_MAX,
"Cycles per tick can't be represented in 32 bits. "
"Double check your platform config");
init();
setnext(TIMERCYCLES_PER_TICK);
}
static void do_interrupt()
{
++Thread::ticksSinceBoot;
expiretimers();
setnext(TIMERCYCLES_PER_TICK);
}
private:
static void expiretimers()
{
if (Thread::waitingList == nullptr)
{
return;
}
for (Thread *iter = Thread::waitingList;;)
{
if (iter->expiryTime <= Thread::ticksSinceBoot)
{
Thread *iterNext = iter->timerNext;
iter->ready(Thread::WakeReason::Timer);
iter = iterNext;
if (Thread::waitingList == nullptr ||
iter == Thread::waitingList)
{
break;
}
}
else
{
break;
}
}
}
};
} // namespace