From 5bbcbc74bb4a97133c2c022a238f928884a609fb Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 14 Dec 2012 14:59:31 +0100 Subject: [PATCH] os & base-hw: freescale EPIT timer driver Fix #576 --- .../timer/hw/epit/platform_timer_base.h | 117 ++++++++++++++++++ os/src/drivers/timer/hw/epit/target.mk | 24 ++++ 2 files changed, 141 insertions(+) create mode 100644 os/src/drivers/timer/hw/epit/platform_timer_base.h create mode 100644 os/src/drivers/timer/hw/epit/target.mk diff --git a/os/src/drivers/timer/hw/epit/platform_timer_base.h b/os/src/drivers/timer/hw/epit/platform_timer_base.h new file mode 100644 index 0000000000..516014fade --- /dev/null +++ b/os/src/drivers/timer/hw/epit/platform_timer_base.h @@ -0,0 +1,117 @@ +/* + * \brief Basic driver behind platform timer + * \author Stefan Kalkowski + * \date 2012-10-25 + */ + +/* + * 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 _HW__EPIT__PLATFORM_TIMER_BASE_H_ +#define _HW__EPIT__PLATFORM_TIMER_BASE_H_ + +/* Genode includes */ +#include +#include +#include +#include +#include + +namespace Genode +{ + /** + * Epit timer + */ + class Epit : public Epit_base + { + private: + + /** + * Timer tics per microsecond + */ + static float tics_per_us() { + return (float)TICS_PER_MS / 1000.0; } + + /** + * Microseconds per timer tic + */ + static float us_per_tic() { return 1.0 / tics_per_us(); } + + public: + + /** + * Constructor + * + * \param base MMIO base + */ + Epit(addr_t const base) : Epit_base(base) { } + + /** + * Count down 'value', raise IRQ output, wrap counter and continue + */ + void run_and_wrap(unsigned long value) { + start_one_shot(value); } + + /** + * Maximum timeout value + */ + unsigned long max_value() { + return read(); } + + /** + * Translate timer tics to microseconds + */ + unsigned long tics_to_us(unsigned long const tics) + { + float const us = tics * us_per_tic(); + return (unsigned long)us; + } + + /** + * Translate microseconds to timer tics + */ + unsigned long us_to_tics(unsigned long const us) + { + float const tics = us * tics_per_us(); + return (unsigned long)tics; + } + + /** + * Sample the timer counter and according wrapped status + */ + unsigned long value(bool & wrapped) + { + unsigned long v = read(); + wrapped = (bool)read(); + return wrapped ? read() : v; + } + }; +} + +/** + * Basic driver behind platform timer + */ +class Platform_timer_base : public Genode::Io_mem_connection, + public Genode::Epit +{ + public: + + enum { IRQ = Genode::Board_base::EPIT_2_IRQ }; + + /** + * Constructor + */ + Platform_timer_base() + : Io_mem_connection(Genode::Board_base::EPIT_2_MMIO_BASE, + Genode::Board_base::EPIT_2_MMIO_SIZE), + Genode::Epit((Genode::addr_t)Genode::env()->rm_session() + ->attach(dataspace())) + { } +}; + +#endif /* _HW__EPIT__PLATFORM_TIMER_BASE_H_ */ + diff --git a/os/src/drivers/timer/hw/epit/target.mk b/os/src/drivers/timer/hw/epit/target.mk new file mode 100644 index 0000000000..ff46cf5cbb --- /dev/null +++ b/os/src/drivers/timer/hw/epit/target.mk @@ -0,0 +1,24 @@ +# +# \brief Timer session server +# \author Stefan Kalkowski +# \date 2012-10-25 +# + +# set program name +TARGET = timer + +# add C++ sources +SRC_CC += main.cc + +# skip build if required specs not fullfilled +REQUIRES += hw epit + +# 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)/../.. +