genode/repos/os/src/drivers/timer/nova/time_source.cc

82 lines
2.1 KiB
C++

/*
* \brief Time source using Nova timed semaphore down
* \author Alexander Boettcher
* \author Martin Stein
* \date 2014-06-24
*/
/*
* Copyright (C) 2014-2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <os/attached_rom_dataspace.h>
/* NOVA includes */
#include <nova/native_thread.h>
/* local includes */
#include <time_source.h>
using namespace Genode;
using namespace Nova;
using Microseconds = Genode::Time_source::Microseconds;
Timer::Time_source::Time_source(Entrypoint &ep) : Threaded_time_source(ep)
{
/* read out the tsc frequenzy once */
Attached_rom_dataspace _ds("hypervisor_info_page");
Nova::Hip * const hip = _ds.local_addr<Nova::Hip>();
_tsc_khz = hip->tsc_freq;
start();
}
void Timer::Time_source::schedule_timeout(Microseconds duration,
Timeout_handler &handler)
{
Threaded_time_source::handler(handler);
/* check whether to cancel last timeout */
if (duration.value == 0 && _sem != ~0UL) {
uint8_t res = Nova::sm_ctrl(_sem, Nova::SEMAPHORE_UP);
if (res != Nova::NOVA_OK)
nova_die();
}
/* remember timeout to be set during wait_for_timeout call */
_timeout_us = duration.value;
}
void Timer::Time_source::_wait_for_irq()
{
if (_sem == ~0UL) {
_sem = Thread::native_thread().exc_pt_sel + SM_SEL_EC; }
addr_t sem = _sem;
/* calculate absolute timeout */
Trace::Timestamp now = Trace::timestamp();
Trace::Timestamp us_64 = _timeout_us;
if (_timeout_us == max_timeout().value) {
/* tsc_absolute == 0 means blocking without timeout */
uint8_t res = sm_ctrl(sem, SEMAPHORE_DOWN, 0);
if (res != Nova::NOVA_OK && res != Nova::NOVA_TIMEOUT) {
nova_die(); }
} else {
/* block until timeout fires or it gets canceled */
unsigned long long tsc_absolute = now + us_64 * (_tsc_khz / TSC_FACTOR);
uint8_t res = sm_ctrl(sem, SEMAPHORE_DOWN, tsc_absolute);
if (res != Nova::NOVA_OK && res != Nova::NOVA_TIMEOUT) {
nova_die(); }
}
}