genode/repos/base/src/timer/pit/time_source.h

104 lines
2.6 KiB
C++

/*
* \brief Time source that uses the Programmable Interval Timer (PIT)
* \author Norman Feske
* \author Martin Stein
* \date 2009-06-16
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _TIME_SOURCE_H_
#define _TIME_SOURCE_H_
/* Genode includes */
#include <io_port_session/connection.h>
#include <irq_session/connection.h>
#include <base/duration.h>
/* local includes */
#include <signalled_time_source.h>
namespace Timer {
using Genode::uint64_t;
using Microseconds = Genode::Microseconds;
using Duration = Genode::Duration;
class Time_source;
}
class Timer::Time_source : public Genode::Signalled_time_source
{
private:
enum {
PIT_TICKS_PER_SECOND = 1193182,
PIT_TICKS_PER_MSEC = PIT_TICKS_PER_SECOND/1000,
PIT_MAX_COUNT = 65535,
PIT_DATA_PORT_0 = 0x40, /* data port for PIT channel 0,
connected to the PIC */
PIT_CMD_PORT = 0x43, /* PIT command port */
PIT_MAX_USEC = (PIT_MAX_COUNT*1000)/(PIT_TICKS_PER_MSEC),
IRQ_PIT = 0, /* timer interrupt at the PIC */
/*
* Bit definitions for accessing the PIT command port
*/
PIT_CMD_SELECT_CHANNEL_0 = 0 << 6,
PIT_CMD_ACCESS_LO = 1 << 4,
PIT_CMD_ACCESS_LO_HI = 3 << 4,
PIT_CMD_MODE_IRQ = 0 << 1,
PIT_CMD_MODE_RATE = 2 << 1,
PIT_CMD_READ_BACK = 3 << 6,
PIT_CMD_RB_COUNT = 0 << 5,
PIT_CMD_RB_STATUS = 0 << 4,
PIT_CMD_RB_CHANNEL_0 = 1 << 1,
/*
* Bit definitions of the PIT status byte
*/
PIT_STAT_INT_LINE = 1 << 7,
};
Genode::Io_port_connection _io_port;
Genode::Irq_connection _timer_irq;
uint64_t mutable _curr_time_us = 0;
Genode::uint16_t mutable _counter_init_value = 0;
bool mutable _handled_wrap = false;
void _set_counter(Genode::uint16_t value);
Genode::uint16_t _read_counter(bool *wrapped);
Genode::uint32_t _ticks_since_update_one_wrap(Genode::uint16_t curr_counter);
Genode::uint32_t _ticks_since_update_no_wrap(Genode::uint16_t curr_counter);
Duration _curr_time();
public:
Time_source(Genode::Env &env);
/*************************
** Genode::Time_source **
*************************/
Duration curr_time() override;
void schedule_timeout(Microseconds duration, Timeout_handler &handler) override;
Microseconds max_timeout() const override {
return Microseconds(PIT_MAX_USEC); }
};
#endif /* _TIME_SOURCE_H_ */