From 2d2373a03be80fb92b1a1fb2f2bc796cf6f4ad53 Mon Sep 17 00:00:00 2001 From: Markus Partheymueller Date: Mon, 5 Nov 2012 16:48:40 +0100 Subject: [PATCH] vancouver: Timer support This required usleep to be added to the timer interface. --- os/include/timer_session/client.h | 4 + os/include/timer_session/timer_session.h | 10 +- .../timer/foc/timer_session_component.h | 9 ++ .../timer/include/timer_session_component.h | 9 +- .../timer/nova/timer_session_component.h | 9 +- ports/src/vancouver/main.cc | 91 +++++++++++++++++-- ports/src/vancouver/target.mk | 2 +- 7 files changed, 123 insertions(+), 11 deletions(-) diff --git a/os/include/timer_session/client.h b/os/include/timer_session/client.h index af76dbc17..93add33fa 100644 --- a/os/include/timer_session/client.h +++ b/os/include/timer_session/client.h @@ -1,11 +1,13 @@ /* * \brief Client-side timer session interface * \author Norman Feske + * \author Markus Partheymueller * \date 2006-05-31 */ /* * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2012 Intel Corporation * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -26,6 +28,8 @@ namespace Timer { void msleep(unsigned ms) { call(ms); } + void usleep(unsigned us) { call(us); } + unsigned long elapsed_ms() const { return call(); } }; } diff --git a/os/include/timer_session/timer_session.h b/os/include/timer_session/timer_session.h index 99b1771ab..92013ea9f 100644 --- a/os/include/timer_session/timer_session.h +++ b/os/include/timer_session/timer_session.h @@ -1,11 +1,13 @@ /* * \brief Timer session interface * \author Norman Feske + * \author Markus Partheymueller * \date 2006-08-15 */ /* * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2012 Intel Corporation * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -29,6 +31,11 @@ namespace Timer { */ virtual void msleep(unsigned ms) = 0; + /** + * Sleep number of microseconds + */ + virtual void usleep(unsigned us) = 0; + /** * Return number of elapsed milliseconds since session creation */ @@ -46,9 +53,10 @@ namespace Timer { *********************/ GENODE_RPC(Rpc_msleep, void, msleep, unsigned); + GENODE_RPC(Rpc_usleep, void, usleep, unsigned); GENODE_RPC(Rpc_elapsed_ms, unsigned long, elapsed_ms); - GENODE_RPC_INTERFACE(Rpc_msleep, Rpc_elapsed_ms); + GENODE_RPC_INTERFACE(Rpc_msleep, Rpc_usleep, Rpc_elapsed_ms); }; } diff --git a/os/src/drivers/timer/foc/timer_session_component.h b/os/src/drivers/timer/foc/timer_session_component.h index cb896b3f7..bba9b3a66 100644 --- a/os/src/drivers/timer/foc/timer_session_component.h +++ b/os/src/drivers/timer/foc/timer_session_component.h @@ -2,11 +2,13 @@ * \brief Instance of the timer session interface * \author Norman Feske * \author Stefan Kalkowski + * \author Markus Partheymueller * \date 2010-01-30 */ /* * Copyright (C) 2010-2013 Genode Labs GmbH + * Copyright (C) 2012 Intel Corporation * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -120,6 +122,13 @@ namespace Timer { l4_ipc_sleep(l4_timeout(L4_IPC_TIMEOUT_NEVER, mus_to_timeout(1000*ms))); } + void usleep(unsigned us) + { + using namespace Fiasco; + + l4_ipc_sleep(l4_timeout(L4_IPC_TIMEOUT_NEVER, mus_to_timeout(us))); + } + unsigned long elapsed_ms() const { return (_kip->clock - _initial_clock_value) / 1000; diff --git a/os/src/drivers/timer/include/timer_session_component.h b/os/src/drivers/timer/include/timer_session_component.h index cfe2a4df0..eaa351b4e 100644 --- a/os/src/drivers/timer/include/timer_session_component.h +++ b/os/src/drivers/timer/include/timer_session_component.h @@ -1,11 +1,13 @@ /* * \brief Instance of the timer session interface * \author Norman Feske + * \author Markus Partheymueller * \date 2006-08-15 */ /* * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2012 Intel Corporation * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -234,9 +236,14 @@ namespace Timer { *****************************/ void msleep(unsigned ms) + { + usleep(1000*ms); + } + + void usleep(unsigned us) { _wake_up_alarm.reply_cap(_entrypoint->reply_dst()); - _timeout_scheduler->schedule_timeout(&_wake_up_alarm, 1000*ms); + _timeout_scheduler->schedule_timeout(&_wake_up_alarm, us); /* * Prevent the server activation from immediately answering the diff --git a/os/src/drivers/timer/nova/timer_session_component.h b/os/src/drivers/timer/nova/timer_session_component.h index a320cc26f..7ed42a9ba 100644 --- a/os/src/drivers/timer/nova/timer_session_component.h +++ b/os/src/drivers/timer/nova/timer_session_component.h @@ -1,11 +1,13 @@ /* * \brief Instance of the timer session interface * \author Norman Feske + * \author Markus Partheymueller * \date 2010-01-30 */ /* * Copyright (C) 2010-2013 Genode Labs GmbH + * Copyright (C) 2012 Intel Corporation * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -182,7 +184,12 @@ namespace Timer { void msleep(unsigned ms) { - _timeout_scheduler->schedule_timeout(&_wake_up_alarm, 1000*ms); + usleep(1000*ms); + } + + void usleep(unsigned us) + { + _timeout_scheduler->schedule_timeout(&_wake_up_alarm, us); /* * Prevent the server activation from immediately answering the diff --git a/ports/src/vancouver/main.cc b/ports/src/vancouver/main.cc index 2af27a5e5..c55de3a39 100644 --- a/ports/src/vancouver/main.cc +++ b/ports/src/vancouver/main.cc @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include /* NOVA includes that come with Genode */ @@ -77,6 +79,66 @@ enum { verbose_io = false }; * Used for startup synchronization and coarse-grained locking. */ Genode::Lock global_lock(Genode::Lock::LOCKED); +Genode::Lock timeouts_lock(Genode::Lock::UNLOCKED); + + +/* Timer Service */ +using Genode::Thread; +using Genode::Alarm_scheduler; +using Genode::Alarm; + +class Alarm_thread : Thread<4096>, public Alarm_scheduler +{ + private: + + Timer::Connection _timer; + Alarm::Time _curr_time; /* jiffies value */ + + Motherboard &_motherboard; + TimeoutList<32, void> &_timeouts; + + /** + * Thread entry function + */ + void entry() + { + while (true) { + unsigned long long now = _motherboard.clock()->time(); + unsigned nr; + + timeouts_lock.lock(); + + while ((nr = _timeouts.trigger(now))) { + + MessageTimeout msg(nr, _timeouts.timeout()); + + if (_timeouts.cancel(nr) < 0) + Logging::printf("Timeout not cancelled.\n"); + + timeouts_lock.unlock(); + + _motherboard.bus_timeout.send(msg); + + timeouts_lock.lock(); + } + + timeouts_lock.unlock(); + + _timer.usleep(1000); + } + } + + public: + + /** + * Constructor + */ + Alarm_thread(Motherboard &mb, TimeoutList<32, void> &timeouts) + : _curr_time(0), _motherboard(mb), _timeouts(timeouts) { start(); } + + Alarm::Time curr_time() { return _curr_time; } + unsigned long long curr_time_long() { return _motherboard.clock()->time(); } +}; /** @@ -898,6 +960,7 @@ class Machine : public StaticReceiver TimeoutList<32, void> _timeouts; Guest_memory &_guest_memory; Boot_module_provider &_boot_modules; + Alarm_thread *_alarm_thread; public: @@ -1086,14 +1149,26 @@ class Machine : public StaticReceiver if (verbose_debug) Logging::printf("TIMER_NEW\n"); + + if (_alarm_thread == NULL) { + Logging::printf("Creating alarm thread\n"); + _alarm_thread = new Alarm_thread(_motherboard, _timeouts); + } + + timeouts_lock.lock(); msg.nr = _timeouts.alloc(); + timeouts_lock.unlock(); + return true; case MessageTimer::TIMER_REQUEST_TIMEOUT: + timeouts_lock.lock(); + + if (_timeouts.request(msg.nr, msg.abstime) < 0) + Logging::printf("Could not program timeout.\n"); + + timeouts_lock.unlock(); - if (verbose_debug) - Logging::printf("TIMER_REQUEST_TIMEOUT\n"); - _timeouts.request(msg.nr, msg.abstime); return true; default: @@ -1103,13 +1178,15 @@ class Machine : public StaticReceiver bool receive(MessageTime &msg) { - if (verbose_debug) - Logging::printf("MessageTime - not implemented\n"); - return false; + // XXX: Use RTC time + msg.wallclocktime = 0; + msg.timestamp = 0; + + return true; } bool receive(MessageNetwork &msg) - { + { if (verbose_debug) PDBG("MessageNetwork"); return false; diff --git a/ports/src/vancouver/target.mk b/ports/src/vancouver/target.mk index 3799dfe26..8f98c8341 100644 --- a/ports/src/vancouver/target.mk +++ b/ports/src/vancouver/target.mk @@ -10,7 +10,7 @@ ifeq ($(wildcard $(VANCOUVER_DIR)),) REQUIRES += prepare_ports_vancouver endif -LIBS += cxx env thread server +LIBS += cxx env thread alarm signal server SRC_CC = main.cc nova_user_env.cc device_model_registry.cc #