diff --git a/os/src/drivers/timer/hw/pbxa9/platform_timer_base.h b/os/src/drivers/timer/hw/pbxa9/platform_timer_base.h new file mode 100644 index 0000000000..e01521b27e --- /dev/null +++ b/os/src/drivers/timer/hw/pbxa9/platform_timer_base.h @@ -0,0 +1,46 @@ +/* + * \brief Platform-timer base specific for base-hw and PBXA9 + * \author Martin Stein + * \date 2012-05-03 + */ + +/* + * Copyright (C) 2012 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. + */ + +#ifndef _OS__SRC__DRIVERS__TIMER__HW__PBXA9__PLATFORM_TIMER_BASE_H_ +#define _OS__SRC__DRIVERS__TIMER__HW__PBXA9__PLATFORM_TIMER_BASE_H_ + +/* Genode includes */ +#include +#include +#include + +/** + * Platform-timer base specific for base-hw and PBXA9 + */ +class Platform_timer_base : + public Genode::Io_mem_connection, + public Genode::Sp804_base +{ + public: + + enum { IRQ = Genode::Pbxa9::SP804_0_IRQ }; + + /** + * Constructor + */ + Platform_timer_base() : + Io_mem_connection(Genode::Pbxa9::SP804_0_MMIO_BASE, + Genode::Pbxa9::SP804_0_MMIO_SIZE), + + Sp804_base((Genode::addr_t)Genode::env()->rm_session()-> + attach(dataspace())) + { } +}; + +#endif /* _OS__SRC__DRIVERS__TIMER__HW__PBXA9__PLATFORM_TIMER_BASE_H_ */ + diff --git a/os/src/drivers/timer/hw/pbxa9/target.mk b/os/src/drivers/timer/hw/pbxa9/target.mk new file mode 100755 index 0000000000..7090d75fdc --- /dev/null +++ b/os/src/drivers/timer/hw/pbxa9/target.mk @@ -0,0 +1,23 @@ +# +# \brief Timer session server specific for base-hw and PBXA9 +# \author Martin Stein +# \date 2012-05-03 +# + +# Set program name +TARGET = timer + +# Add C++ sources +SRC_CC += main.cc + +# Skip build if required specs not fullfilled +REQUIRES += hw_pbxa9 + +# Add libraries +LIBS += cxx server env alarm + +# Add include paths +INC_DIR += $(PRG_DIR) $(PRG_DIR)/../ $(PRG_DIR)/../../nova/ + +# Declare source paths +vpath main.cc $(PRG_DIR)/../.. diff --git a/os/src/drivers/timer/hw/platform_timer.h b/os/src/drivers/timer/hw/platform_timer.h new file mode 100755 index 0000000000..fd6bdb24c8 --- /dev/null +++ b/os/src/drivers/timer/hw/platform_timer.h @@ -0,0 +1,110 @@ +/* + * \brief Platform timer specific for base-hw + * \author Martin Stein + * \date 2012-05-03 + */ + +/* + * Copyright (C) 2012 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. + */ + +#ifndef _OS__SRC__DRIVERS__TIMER__HW__PLATFORM_TIMER_H_ +#define _OS__SRC__DRIVERS__TIMER__HW__PLATFORM_TIMER_H_ + +/* Genode includes */ +#include + +/* Local includes */ +#include + +/** + * Platform timer specific for base-hw + */ +class Platform_timer : public Platform_timer_base, + public Genode::Irq_connection +{ + private: + + enum { MAX_TIMER_IRQS_PER_MS = 1 }; + + unsigned long const _max_timeout_us; /* Maximum timeout in microsecs */ + unsigned long _curr_time_us; /* Accumulate already measured timeouts */ + unsigned long _init_value; /* Mark last processed timer value */ + Genode::Lock _update_curr_time_lock; /* Serialize curr_time access */ + + public: + + /** + * Constructor + */ + Platform_timer() : Irq_connection(Platform_timer_base::IRQ), + _max_timeout_us(tics_to_us(max_value())), + _curr_time_us(0), _init_value(0) + { } + + /** + * Refresh and return our instance-own "now"-time in microseconds + * + * This function has to be executed regulary, + * at least all max_timeout() us. + */ + unsigned long curr_time() + { + /* Serialize updates on timeout counter */ + Genode::Lock::Guard lock(_update_curr_time_lock); + + /* Get time that passed since last time we've read the timer */ + bool wrapped; + unsigned long const v = value(wrapped); + unsigned long passed_time; + if (wrapped) passed_time = _init_value + max_value() - v; + else passed_time = _init_value - v; + + /* Update initial value for subsequent calculations */ + _init_value = v; + + /* Refresh our timeout counter and return it */ + _curr_time_us += tics_to_us(passed_time); + return _curr_time_us; + } + + /** + * Return maximum timeout as supported by the platform + */ + unsigned long max_timeout() const { return _max_timeout_us; } + + /** + * Schedule next timeout, oversized timeouts are truncated + * + * \param timeout_us Timeout in microseconds + */ + void schedule_timeout(unsigned long timeout_us) + { + /* Serialize updates on timeout counter */ + Genode::Lock::Guard lock(_update_curr_time_lock); + + /* Constraint timout value with our maximum IRQ rate + * and the maximum possible timout */ + if (timeout_us < 1000/MAX_TIMER_IRQS_PER_MS) + timeout_us = 1000/MAX_TIMER_IRQS_PER_MS; + if (timeout_us > _max_timeout_us) + timeout_us = _max_timeout_us; + + /* Once the timer runs, one can wait for the its IRQ and update our + * timeout counter through 'curr_time()' (We rely on the fact that + * this is done at least one time in every max-timeout period) */ + _init_value = us_to_tics(timeout_us); + run_and_wrap(_init_value); + } + + /** + * Await the lastly scheduled timeout + */ + void wait_for_timeout(Genode::Thread_base *) { wait_for_irq(); } +}; + +#endif /* _OS__SRC__DRIVERS__TIMER__HW__PLATFORM_TIMER_H_ */ + diff --git a/os/src/drivers/timer/hw/vea9x4/platform_timer_base.h b/os/src/drivers/timer/hw/vea9x4/platform_timer_base.h new file mode 100644 index 0000000000..8735c2e41c --- /dev/null +++ b/os/src/drivers/timer/hw/vea9x4/platform_timer_base.h @@ -0,0 +1,46 @@ +/* + * \brief Platform-timer base specific for base-hw and VEA9X4 + * \author Martin Stein + * \date 2012-05-03 + */ + +/* + * Copyright (C) 2012 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. + */ + +#ifndef _OS__SRC__DRIVERS__TIMER__HW__VEA9X4__PLATFORM_TIMER_BASE_H_ +#define _OS__SRC__DRIVERS__TIMER__HW__VEA9X4__PLATFORM_TIMER_BASE_H_ + +/* Genode includes */ +#include +#include +#include + +/** + * Platform-timer base specific for base-hw and VEA9X4 + */ +class Platform_timer_base : + public Genode::Io_mem_connection, + public Genode::Sp804_base +{ + public: + + enum { IRQ = Genode::Vea9x4::SP804_0_1_IRQ }; + + /** + * Constructor + */ + Platform_timer_base() : + Io_mem_connection(Genode::Vea9x4::SP804_0_1_MMIO_BASE, + Genode::Vea9x4::SP804_0_1_MMIO_SIZE), + + Sp804_base((Genode::addr_t)Genode::env()->rm_session()-> + attach(dataspace())) + { } +}; + +#endif /* _OS__SRC__DRIVERS__TIMER__HW__VEA9X4__PLATFORM_TIMER_BASE_H_ */ + diff --git a/os/src/drivers/timer/hw/vea9x4/target.mk b/os/src/drivers/timer/hw/vea9x4/target.mk new file mode 100755 index 0000000000..5aaa43b0fe --- /dev/null +++ b/os/src/drivers/timer/hw/vea9x4/target.mk @@ -0,0 +1,24 @@ +# +# \brief Timer session server specific for base-hw and VEA9X4 +# \author Martin Stein +# \date 2012-05-03 +# + +# Set program name +TARGET = timer + +# Add C++ sources +SRC_CC += main.cc + +# Skip build if required specs not fullfilled +REQUIRES += hw_vea9x4 + +# Add libraries +LIBS += cxx server env alarm + +# Add include paths +INC_DIR += $(PRG_DIR) $(PRG_DIR)/../ $(PRG_DIR)/../../nova/ + +# Declare source paths +vpath main.cc $(PRG_DIR)/../.. +