mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
hw: move timer into board.h
Unify the generic timer implementation for ARMv7 and ARMv8. Ref #3445
This commit is contained in:
parent
5c7436bf10
commit
907de9d37f
@ -10,8 +10,8 @@ INC_DIR += $(REP_DIR)/src/core/spec/rpi
|
||||
# add C++ sources
|
||||
SRC_CC += platform_services.cc
|
||||
SRC_CC += spec/arm/bcm2835_pic.cc
|
||||
SRC_CC += spec/arm/bcm2835_system_timer.cc
|
||||
SRC_CC += spec/arm/cpu.cc
|
||||
SRC_CC += spec/rpi/timer.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/spec/arm_v6/core-hw.inc
|
||||
|
@ -9,8 +9,8 @@
|
||||
INC_DIR += $(REP_DIR)/src/core/spec/imx53_qsb
|
||||
INC_DIR += $(REP_DIR)/src/core/spec/imx53
|
||||
|
||||
SRC_CC += spec/arm/imx_epit.cc
|
||||
SRC_CC += spec/arm/imx_tzic.cc
|
||||
SRC_CC += spec/imx53/timer.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/spec/cortex_a8/core-hw.inc
|
||||
|
@ -9,9 +9,9 @@ INC_DIR += $(REP_DIR)/src/core/spec/imx7d_sabre
|
||||
INC_DIR += $(REP_DIR)/src/core/spec/arm_v7/virtualization
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += spec/arm/generic_timer.cc
|
||||
SRC_CC += spec/arm/gicv2.cc
|
||||
SRC_CC += spec/arndale/platform_services.cc
|
||||
SRC_CC += spec/imx7d_sabre/timer.cc
|
||||
SRC_CC += kernel/vm_thread_on.cc
|
||||
SRC_CC += spec/arm_v7/virtualization/kernel/vm.cc
|
||||
SRC_CC += spec/arm_v7/vm_session_component.cc
|
||||
|
@ -16,8 +16,8 @@ SRC_CC += kernel/vm_thread_on.cc
|
||||
SRC_CC += spec/arm_v7/trustzone/kernel/vm.cc
|
||||
SRC_CC += spec/arm_v7/vm_session_component.cc
|
||||
SRC_CC += spec/arm_v7/trustzone/vm_session_component.cc
|
||||
SRC_CC += spec/arm/imx_epit.cc
|
||||
SRC_CC += spec/arm/imx_tzic.cc
|
||||
SRC_CC += spec/imx53/timer.cc
|
||||
|
||||
# add assembly sources
|
||||
SRC_S += spec/arm_v7/trustzone/exception_vector.s
|
||||
|
@ -11,7 +11,7 @@ SRC_CC += spec/arm_v8/kernel/thread.cc
|
||||
SRC_CC += spec/arm_v8/kernel/cpu.cc
|
||||
SRC_CC += spec/arm/platform_support.cc
|
||||
SRC_CC += spec/arm/bcm2837_pic.cc
|
||||
SRC_CC += spec/rpi3/timer.cc
|
||||
SRC_CC += spec/arm/generic_timer.cc
|
||||
SRC_CC += spec/64bit/memory_map.cc
|
||||
|
||||
#add assembly sources
|
||||
|
@ -9,7 +9,7 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/cortex_a9
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += spec/cortex_a9/board.cc
|
||||
SRC_CC += spec/cortex_a9/timer.cc
|
||||
SRC_CC += spec/arm/cortex_a9_private_timer.cc
|
||||
SRC_CC += spec/arm/gicv2.cc
|
||||
SRC_CC += spec/arm/kernel/lock.cc
|
||||
SRC_CC += kernel/vm_thread_off.cc
|
||||
|
@ -8,7 +8,7 @@
|
||||
INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/exynos5
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += spec/exynos5/timer.cc
|
||||
SRC_CC += spec/arm/exynos_mct.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a15/core-hw.inc
|
||||
|
@ -17,7 +17,7 @@ SRC_CC += kernel/cpu_mp.cc
|
||||
SRC_CC += kernel/vm_thread_off.cc
|
||||
SRC_CC += kernel/lock.cc
|
||||
SRC_CC += spec/x86_64/pic.cc
|
||||
SRC_CC += spec/x86_64/timer.cc
|
||||
SRC_CC += spec/x86_64/pit.cc
|
||||
SRC_CC += spec/x86_64/kernel/thread_exception.cc
|
||||
SRC_CC += spec/x86_64/platform_support.cc
|
||||
SRC_CC += spec/x86/platform_services.cc
|
||||
|
@ -91,7 +91,7 @@ void Timer::process_timeouts()
|
||||
|
||||
|
||||
Timer::Timer(Cpu & cpu)
|
||||
: _driver(cpu.id()), _irq(interrupt_id(), cpu),
|
||||
: _device(cpu.id()), _irq(interrupt_id(), cpu),
|
||||
_last_timeout_duration(_max_value())
|
||||
{
|
||||
/*
|
||||
|
@ -21,8 +21,7 @@
|
||||
/* Genode includes */
|
||||
#include <util/list.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <timer_driver.h>
|
||||
#include <board.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@ -74,9 +73,7 @@ class Kernel::Timer
|
||||
void occurred() override;
|
||||
};
|
||||
|
||||
using Driver = Timer_driver;
|
||||
|
||||
Driver _driver;
|
||||
Board::Timer _device;
|
||||
Irq _irq;
|
||||
time_t _time = 0;
|
||||
time_t _last_timeout_duration;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* \brief Timer implementation specific to Rpi
|
||||
* \brief Timer implementation specific to BCM2835 System Timer
|
||||
* \author Norman Feske
|
||||
* \author Stefan Kalkowski
|
||||
* \author Martin Stein
|
||||
@ -14,32 +14,37 @@
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <board.h>
|
||||
#include <platform.h>
|
||||
#include <kernel/timer.h>
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Kernel;
|
||||
using Device = Board::Timer;
|
||||
|
||||
|
||||
Timer_driver::Timer_driver(unsigned)
|
||||
Board::Timer::Timer(unsigned)
|
||||
: Mmio(Platform::mmio_to_virt(Board::SYSTEM_TIMER_MMIO_BASE)) { }
|
||||
|
||||
|
||||
void Timer::_start_one_shot(time_t const ticks)
|
||||
{
|
||||
_driver.write<Driver::Cs::M1>(1);
|
||||
_driver.read<Driver::Cs>();
|
||||
_driver.write<Driver::Cmp>(_driver.read<Driver::Clo>()
|
||||
_device.write<Device::Cs::M1>(1);
|
||||
_device.read<Device::Cs>();
|
||||
_device.write<Device::Cmp>(_device.read<Device::Clo>()
|
||||
+ (ticks < 2 ? 2 : ticks));
|
||||
}
|
||||
|
||||
|
||||
enum { TICS_PER_US = Board::SYSTEM_TIMER_CLOCK / 1000 / 1000 };
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return ticks / Driver::TICS_PER_US; }
|
||||
return ticks / TICS_PER_US; }
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return us * Driver::TICS_PER_US; }
|
||||
return us * TICS_PER_US; }
|
||||
|
||||
|
||||
time_t Timer::_max_value() const {
|
||||
@ -48,9 +53,9 @@ time_t Timer::_max_value() const {
|
||||
|
||||
time_t Timer::_duration() const
|
||||
{
|
||||
Driver::Clo::access_t const clo = _driver.read<Driver::Clo>();
|
||||
Driver::Cmp::access_t const cmp = _driver.read<Driver::Cmp>();
|
||||
Driver::Cs::access_t const irq = _driver.read<Driver::Cs::M1>();
|
||||
Device::Clo::access_t const clo = _device.read<Device::Clo>();
|
||||
Device::Cmp::access_t const cmp = _device.read<Device::Cmp>();
|
||||
Device::Cs::access_t const irq = _device.read<Device::Cs::M1>();
|
||||
uint32_t d = (irq) ? (uint32_t)_last_timeout_duration + (clo - cmp)
|
||||
: clo - (cmp - _last_timeout_duration);
|
||||
return d;
|
@ -11,31 +11,26 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_DRIVER_H_
|
||||
#define _TIMER_DRIVER_H_
|
||||
#ifndef _SRC__CORE__SPEC__ARM__BCM2835_SYSTEM_TIMER_H_
|
||||
#define _SRC__CORE__SPEC__ARM__BCM2835_SYSTEM_TIMER_H_
|
||||
|
||||
/* Kernel includes */
|
||||
#include <util/mmio.h>
|
||||
|
||||
/* core includes */
|
||||
#include <board.h>
|
||||
|
||||
namespace Kernel { class Timer_driver; }
|
||||
namespace Board { class Timer; }
|
||||
|
||||
/**
|
||||
* Timer driver for core
|
||||
*
|
||||
* Timer channel 0 apparently doesn't work on the RPI, so we use channel 1
|
||||
*/
|
||||
struct Kernel::Timer_driver : Genode::Mmio
|
||||
struct Board::Timer : Genode::Mmio
|
||||
{
|
||||
enum { TICS_PER_US = Board::SYSTEM_TIMER_CLOCK / 1000 / 1000 };
|
||||
|
||||
struct Cs : Register<0x0, 32> { struct M1 : Bitfield<1, 1> { }; };
|
||||
struct Clo : Register<0x4, 32> { };
|
||||
struct Cmp : Register<0x10, 32> { };
|
||||
|
||||
Timer_driver(unsigned);
|
||||
Timer(unsigned);
|
||||
};
|
||||
|
||||
#endif /* _TIMER_DRIVER_H_ */
|
||||
#endif /* _SRC__CORE__SPEC__ARM__BCM2835_SYSTEM_TIMER_H_ */
|
@ -23,7 +23,6 @@ class Board::Pic : Genode::Mmio
|
||||
public:
|
||||
|
||||
enum {
|
||||
TIMER_IRQ = 1,
|
||||
NR_OF_IRQ = 64,
|
||||
|
||||
/*
|
||||
|
@ -22,9 +22,17 @@
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Kernel;
|
||||
using Device = Board::Timer;
|
||||
|
||||
|
||||
Timer_driver::Timer_driver(unsigned)
|
||||
enum {
|
||||
TICS_PER_MS =
|
||||
Board::CORTEX_A9_PRIVATE_TIMER_CLK /
|
||||
Board::CORTEX_A9_PRIVATE_TIMER_DIV / 1000
|
||||
};
|
||||
|
||||
|
||||
Board::Timer::Timer(unsigned)
|
||||
: Mmio(Platform::mmio_to_virt(Board::Cpu_mmio::PRIVATE_TIMER_MMIO_BASE))
|
||||
{
|
||||
enum { PRESCALER = Board::CORTEX_A9_PRIVATE_TIMER_DIV - 1 };
|
||||
@ -51,13 +59,13 @@ void Timer::_start_one_shot(time_t const ticks)
|
||||
* First unset the interrupt flag,
|
||||
* otherwise if the tick is small enough, we loose an interrupt
|
||||
*/
|
||||
_driver.write<Driver::Interrupt_status::Event>(1);
|
||||
_driver.write<Driver::Counter>(ticks);
|
||||
_device.write<Device::Interrupt_status::Event>(1);
|
||||
_device.write<Device::Counter>(ticks);
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return timer_ticks_to_us(ticks, Driver::TICS_PER_MS); }
|
||||
return timer_ticks_to_us(ticks, TICS_PER_MS); }
|
||||
|
||||
|
||||
unsigned Timer::interrupt_id() const {
|
||||
@ -65,14 +73,14 @@ unsigned Timer::interrupt_id() const {
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return (us / 1000) * Driver::TICS_PER_MS; }
|
||||
return (us / 1000) * TICS_PER_MS; }
|
||||
|
||||
|
||||
time_t Timer::_duration() const
|
||||
{
|
||||
Driver::Counter::access_t last = _last_timeout_duration;
|
||||
Driver::Counter::access_t cnt = _driver.read<Driver::Counter>();
|
||||
Driver::Counter::access_t ret = (_driver.read<Driver::Interrupt_status::Event>())
|
||||
Device::Counter::access_t last = _last_timeout_duration;
|
||||
Device::Counter::access_t cnt = _device.read<Device::Counter>();
|
||||
Device::Counter::access_t ret = (_device.read<Device::Interrupt_status::Event>())
|
||||
? _max_value() - cnt + last : last - cnt;
|
||||
return ret;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* \brief Timer implementation specific to Cortex A9
|
||||
* \brief Private Timer implementation specific to Cortex A9
|
||||
* \author Martin stein
|
||||
* \date 2011-12-13
|
||||
*/
|
||||
@ -11,28 +11,19 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_DRIVER_H_
|
||||
#define _TIMER_DRIVER_H_
|
||||
#ifndef _SRC__CORE__SPEC__ARM__CORTEX_A9_PRIVATE_TIMER_H_
|
||||
#define _SRC__CORE__SPEC__ARM__CORTEX_A9_PRIVATE_TIMER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
|
||||
/* core includes */
|
||||
#include <board.h>
|
||||
|
||||
namespace Kernel { class Timer_driver; }
|
||||
namespace Board { class Timer; }
|
||||
|
||||
/**
|
||||
* Timer driver for core
|
||||
*/
|
||||
struct Kernel::Timer_driver : Genode::Mmio
|
||||
struct Board::Timer : Genode::Mmio
|
||||
{
|
||||
enum {
|
||||
TICS_PER_MS =
|
||||
Board::CORTEX_A9_PRIVATE_TIMER_CLK /
|
||||
Board::CORTEX_A9_PRIVATE_TIMER_DIV / 1000
|
||||
};
|
||||
|
||||
/**
|
||||
* Load value register
|
||||
*/
|
||||
@ -62,7 +53,7 @@ struct Kernel::Timer_driver : Genode::Mmio
|
||||
struct Event : Bitfield<0,1> { }; /* if counter hit zero */
|
||||
};
|
||||
|
||||
Timer_driver(unsigned);
|
||||
Timer(unsigned);
|
||||
};
|
||||
|
||||
#endif /* _TIMER_DRIVER_H_ */
|
||||
#endif /* _SRC__CORE__SPEC__ARM__CORTEX_A9_PRIVATE_TIMER_H_ */
|
@ -25,7 +25,7 @@ using namespace Kernel;
|
||||
|
||||
unsigned Timer::interrupt_id() const
|
||||
{
|
||||
switch (_driver.cpu_id) {
|
||||
switch (_device.cpu_id) {
|
||||
case 0: return Board::MCT_IRQ_L0;
|
||||
case 1: return Board::MCT_IRQ_L1;
|
||||
default: return 0;
|
||||
@ -33,7 +33,7 @@ unsigned Timer::interrupt_id() const
|
||||
}
|
||||
|
||||
|
||||
Timer_driver::Timer_driver(unsigned cpu_id)
|
||||
Board::Timer::Timer(unsigned cpu_id)
|
||||
:
|
||||
Mmio(Platform::mmio_to_virt(Board::MCT_MMIO_BASE)),
|
||||
local(Platform::mmio_to_virt(Board::MCT_MMIO_BASE)
|
||||
@ -51,7 +51,7 @@ Timer_driver::Timer_driver(unsigned cpu_id)
|
||||
}
|
||||
|
||||
|
||||
Timer_driver::Local::Local(Genode::addr_t base)
|
||||
Board::Timer::Local::Local(Genode::addr_t base)
|
||||
: Mmio(base)
|
||||
{
|
||||
write<Int_enb>(Int_enb::Frceie::bits(1));
|
||||
@ -68,27 +68,29 @@ Timer_driver::Local::Local(Genode::addr_t base)
|
||||
|
||||
void Timer::_start_one_shot(time_t const ticks)
|
||||
{
|
||||
_driver.local.cnt = _driver.local.read<Driver::Local::Tcnto>();
|
||||
_driver.local.write<Driver::Local::Int_cstat::Frccnt>(1);
|
||||
_driver.local.acked_write<Driver::Local::Frcntb,
|
||||
Driver::Local::Wstat::Frcntb>(ticks);
|
||||
using Device = Board::Timer;
|
||||
_device.local.cnt = _device.local.read<Device::Local::Tcnto>();
|
||||
_device.local.write<Device::Local::Int_cstat::Frccnt>(1);
|
||||
_device.local.acked_write<Device::Local::Frcntb,
|
||||
Device::Local::Wstat::Frcntb>(ticks);
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::_duration() const
|
||||
{
|
||||
unsigned long ret = _driver.local.cnt - _driver.local.read<Driver::Local::Tcnto>();
|
||||
using Tcnto = Board::Timer::Local::Tcnto;
|
||||
unsigned long ret = _device.local.cnt - _device.local.read<Tcnto>();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return timer_ticks_to_us(ticks, _driver.ticks_per_ms); }
|
||||
return timer_ticks_to_us(ticks, _device.ticks_per_ms); }
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return (us / 1000) * _driver.ticks_per_ms; }
|
||||
return (us / 1000) * _device.ticks_per_ms; }
|
||||
|
||||
|
||||
time_t Timer::_max_value() const {
|
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_DRIVER_H_
|
||||
#define _TIMER_DRIVER_H_
|
||||
#ifndef _SRC__CORE__SPEC__ARM__EXYNOS_MCT_H_
|
||||
#define _SRC__CORE__SPEC__ARM__EXYNOS_MCT_H_
|
||||
|
||||
/* Kernel includes */
|
||||
#include <util/mmio.h>
|
||||
@ -20,10 +20,10 @@
|
||||
/* base-hw includes */
|
||||
#include <kernel/types.h>
|
||||
|
||||
namespace Kernel { class Timer_driver; }
|
||||
namespace Board { class Timer; }
|
||||
|
||||
|
||||
struct Kernel::Timer_driver : Genode::Mmio
|
||||
struct Board::Timer : Genode::Mmio
|
||||
{
|
||||
enum {
|
||||
PRESCALER = 1,
|
||||
@ -108,14 +108,14 @@ struct Kernel::Timer_driver : Genode::Mmio
|
||||
*
|
||||
* \param clock input clock
|
||||
*/
|
||||
time_t static calc_ticks_per_ms(unsigned const clock) {
|
||||
Kernel::time_t static calc_ticks_per_ms(unsigned const clock) {
|
||||
return clock / (PRESCALER + 1) / (1 << DIV_MUX) / 1000; }
|
||||
|
||||
Local local;
|
||||
unsigned const ticks_per_ms;
|
||||
unsigned const cpu_id;
|
||||
|
||||
Timer_driver(unsigned cpu_id);
|
||||
Timer(unsigned cpu_id);
|
||||
};
|
||||
|
||||
#endif /* _TIMER_DRIVER_H_ */
|
||||
#endif /* _SRC__CORE__SPEC__ARM__EXYNOS_MCT_H_ */
|
60
repos/base-hw/src/core/spec/arm/generic_timer.cc
Normal file
60
repos/base-hw/src/core/spec/arm/generic_timer.cc
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* \brief Timer driver for core
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2019-05-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
#include <drivers/timer/util.h>
|
||||
#include <kernel/timer.h>
|
||||
#include <kernel/cpu.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
unsigned Timer::interrupt_id() const { return Board::TIMER_IRQ; }
|
||||
|
||||
|
||||
unsigned long Board::Timer::_freq() { return Genode::Cpu::Cntfrq::read(); }
|
||||
|
||||
|
||||
Board::Timer::Timer(unsigned) : ticks_per_ms(_freq() / 1000)
|
||||
{
|
||||
Cpu::Cntp_ctl::access_t ctl = 0;
|
||||
Cpu::Cntp_ctl::Enable::set(ctl, 1);
|
||||
Cpu::Cntp_ctl::write(ctl);
|
||||
}
|
||||
|
||||
|
||||
void Timer::_start_one_shot(time_t const ticks)
|
||||
{
|
||||
_device.last_time = Cpu::Cntpct::read();
|
||||
Cpu::Cntp_tval::write(ticks);
|
||||
Cpu::Cntp_ctl::access_t ctl = Cpu::Cntp_ctl::read();
|
||||
Cpu::Cntp_ctl::Istatus::set(ctl, 0);
|
||||
Cpu::Cntp_ctl::write(ctl);
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::_duration() const
|
||||
{
|
||||
return Cpu::Cntpct::read() - _device.last_time;
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return Genode::timer_ticks_to_us(ticks, _device.ticks_per_ms); }
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return (us / 1000) * _device.ticks_per_ms; }
|
||||
|
||||
|
||||
time_t Timer::_max_value() const {
|
||||
return _device.ticks_per_ms * 5000; }
|
@ -11,24 +11,23 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_DRIVER_H_
|
||||
#define _TIMER_DRIVER_H_
|
||||
#ifndef _SRC__CORE__SPEC__ARM__GENERIC_TIMER_H_
|
||||
#define _SRC__CORE__SPEC__ARM__GENERIC_TIMER_H_
|
||||
|
||||
/* base-hw includes */
|
||||
#include <kernel/types.h>
|
||||
|
||||
namespace Kernel { class Timer_driver; }
|
||||
namespace Board { class Timer; }
|
||||
|
||||
|
||||
struct Kernel::Timer_driver
|
||||
struct Board::Timer
|
||||
{
|
||||
unsigned long _freq();
|
||||
|
||||
unsigned const ticks_per_ms;
|
||||
|
||||
time_t last_time { 0 };
|
||||
Kernel::time_t last_time { 0 };
|
||||
|
||||
Timer_driver(unsigned);
|
||||
Timer(unsigned);
|
||||
};
|
||||
|
||||
#endif /* _TIMER_DRIVER_H_ */
|
||||
#endif /* _SRC__CORE__SPEC__ARM__GENERIC_TIMER_H_ */
|
@ -26,7 +26,7 @@ using namespace Kernel;
|
||||
unsigned Timer::interrupt_id() const { return Board::EPIT_1_IRQ; }
|
||||
|
||||
|
||||
Timer_driver::Timer_driver(unsigned)
|
||||
Board::Timer::Timer(unsigned)
|
||||
: Mmio(Platform::mmio_to_virt(Board::EPIT_1_MMIO_BASE))
|
||||
{
|
||||
reset();
|
||||
@ -52,17 +52,17 @@ void Timer::_start_one_shot(time_t const ticks)
|
||||
* First unset the interrupt flag,
|
||||
* otherwise if the tick is small enough, we loose an interrupt
|
||||
*/
|
||||
_driver.write<Driver::Sr::Ocif>(1);
|
||||
_driver.write<Driver::Lr>(ticks - 1);
|
||||
_device.write<Board::Timer::Sr::Ocif>(1);
|
||||
_device.write<Board::Timer::Lr>(ticks - 1);
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return timer_ticks_to_us(ticks, Driver::TICS_PER_MS); }
|
||||
return timer_ticks_to_us(ticks, Board::Timer::TICS_PER_MS); }
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return (us / 1000UL) * Driver::TICS_PER_MS; }
|
||||
return (us / 1000UL) * Board::Timer::TICS_PER_MS; }
|
||||
|
||||
|
||||
time_t Timer::_max_value() const {
|
||||
@ -71,9 +71,10 @@ time_t Timer::_max_value() const {
|
||||
|
||||
time_t Timer::_duration() const
|
||||
{
|
||||
Driver::Cnt::access_t last = _last_timeout_duration;
|
||||
Driver::Cnt::access_t cnt = _driver.read<Driver::Cnt>();
|
||||
Driver::Cnt::access_t ret = (_driver.read<Driver::Sr::Ocif>())
|
||||
using Device = Board::Timer;
|
||||
Device::Cnt::access_t last = _last_timeout_duration;
|
||||
Device::Cnt::access_t cnt = _device.read<Device::Cnt>();
|
||||
Device::Cnt::access_t ret = (_device.read<Device::Sr::Ocif>())
|
||||
? _max_value() - cnt + last : last - cnt;
|
||||
return ret;
|
||||
}
|
@ -11,18 +11,18 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_DRIVER_H_
|
||||
#define _TIMER_DRIVER_H_
|
||||
#ifndef _SRC__CORE__SPEC__ARM__IMX_EPIT_H_
|
||||
#define _SRC__CORE__SPEC__ARM__IMX_EPIT_H_
|
||||
|
||||
/* Kernel includes */
|
||||
#include <util/mmio.h>
|
||||
|
||||
namespace Kernel { class Timer_driver; }
|
||||
namespace Board { class Timer; }
|
||||
|
||||
/**
|
||||
* Timer driver for core
|
||||
*/
|
||||
struct Kernel::Timer_driver : Genode::Mmio
|
||||
struct Board::Timer : Genode::Mmio
|
||||
{
|
||||
enum { TICS_PER_MS = 33333 };
|
||||
|
||||
@ -86,7 +86,7 @@ struct Kernel::Timer_driver : Genode::Mmio
|
||||
write<Sr::Ocif>(1);
|
||||
}
|
||||
|
||||
Timer_driver(unsigned);
|
||||
Timer(unsigned);
|
||||
};
|
||||
|
||||
#endif /* _TIMER_DRIVER_H_ */
|
||||
#endif /* _SRC__CORE__SPEC__ARM__IMX_EPIT_H_ */
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/arndale_board.h>
|
||||
#include <spec/arm/exynos_mct.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Arndale_board;
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <hw/spec/arm/imx_tzic.h>
|
||||
#include <hw/spec/arm/imx53_qsb_board.h>
|
||||
#include <spec/arm/imx_epit.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Imx53_qsb_board;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/imx6q_sabrelite_board.h>
|
||||
#include <spec/arm/cortex_a9_private_timer.h>
|
||||
|
||||
namespace Board {
|
||||
|
||||
|
@ -16,11 +16,14 @@
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/imx7d_sabre_board.h>
|
||||
#include <spec/arm/generic_timer.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Imx7d_sabre_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
|
||||
enum { TIMER_IRQ = 30 };
|
||||
}
|
||||
|
||||
#endif /* _CORE__SPEC__IMX7_SABRELITE__BOARD_H_ */
|
||||
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* \brief Timer driver for core
|
||||
* \author Stefan Kalkowski
|
||||
* \author Martin stein
|
||||
* \date 2013-01-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-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.
|
||||
*/
|
||||
|
||||
#include <drivers/timer/util.h>
|
||||
#include <kernel/timer.h>
|
||||
#include <board.h>
|
||||
#include <platform.h>
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
unsigned Timer::interrupt_id() const
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
unsigned long Timer_driver::_freq()
|
||||
{
|
||||
unsigned long freq;
|
||||
asm volatile("mrc p15, 0, %0, c14, c0, 0\n" : "=r" (freq));
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
||||
Timer_driver::Timer_driver(unsigned) : ticks_per_ms(_freq() / 1000)
|
||||
{
|
||||
unsigned long ctrl;
|
||||
asm volatile("mrc p15, 0, %0, c14, c2, 1\n" : "=r" (ctrl));
|
||||
asm volatile("mcr p15, 0, %0, c14, c2, 1\n" :: "r" (ctrl | 1));
|
||||
}
|
||||
|
||||
|
||||
void Timer::_start_one_shot(time_t const ticks)
|
||||
{
|
||||
unsigned long ctrl;
|
||||
unsigned long v0, v1;
|
||||
asm volatile("mrrc p15, 0, %0, %1, c14\n" : "=r" (v0), "=r" (v1));
|
||||
_driver.last_time = (Genode::uint64_t)v0 | (Genode::uint64_t)v1 << 32;
|
||||
asm volatile("mcr p15, 0, %0, c14, c2, 0\n" :: "r" (ticks));
|
||||
asm volatile("mrc p15, 0, %0, c14, c2, 1\n" : "=r" (ctrl));
|
||||
asm volatile("mcr p15, 0, %0, c14, c2, 1\n" :: "r" (ctrl & ~4UL));
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::_duration() const
|
||||
{
|
||||
unsigned long v0, v1;
|
||||
asm volatile("mrrc p15, 0, %0, %1, c14\n" : "=r" (v0), "=r" (v1));
|
||||
Genode::uint64_t v = (Genode::uint64_t)v0 | (Genode::uint64_t)v1 << 32;
|
||||
return v - _driver.last_time;
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return timer_ticks_to_us(ticks, _driver.ticks_per_ms); }
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return (us / 1000) * _driver.ticks_per_ms; }
|
||||
|
||||
|
||||
time_t Timer::_max_value() const {
|
||||
return _driver.ticks_per_ms * 5000; }
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* \brief Timer driver for core
|
||||
* \author Martin stein
|
||||
* \date 2013-01-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Kernel OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_DRIVER_H_
|
||||
#define _TIMER_DRIVER_H_
|
||||
|
||||
/* base-hw includes */
|
||||
#include <kernel/types.h>
|
||||
|
||||
namespace Kernel { class Timer_driver; }
|
||||
|
||||
|
||||
struct Kernel::Timer_driver
|
||||
{
|
||||
unsigned long _freq();
|
||||
|
||||
unsigned const ticks_per_ms;
|
||||
|
||||
time_t last_time { 0 };
|
||||
|
||||
Timer_driver(unsigned);
|
||||
};
|
||||
|
||||
#endif /* _TIMER_DRIVER_H_ */
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/nit6_solox_board.h>
|
||||
#include <spec/arm/cortex_a9_private_timer.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Nit6_solox_board;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/odroid_xu_board.h>
|
||||
#include <spec/arm/exynos_mct.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Odroid_xu_board;
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/panda_board.h>
|
||||
#include <spec/arm/cortex_a9_private_timer.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Panda_board;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/pbxa9_board.h>
|
||||
#include <spec/arm/cortex_a9_private_timer.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Pbxa9_board;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <hw/spec/riscv/board.h>
|
||||
#include <spec/riscv/pic.h>
|
||||
#include <spec/riscv/timer.h>
|
||||
|
||||
namespace Board { using namespace Hw::Riscv_board; }
|
||||
|
||||
|
@ -19,28 +19,28 @@ using namespace Genode;
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
Timer_driver::Timer_driver(unsigned)
|
||||
Board::Timer::Timer(unsigned)
|
||||
{
|
||||
/* enable timer interrupt */
|
||||
enum { STIE = 0x20 };
|
||||
asm volatile ("csrs sie, %0" : : "r"(STIE));
|
||||
}
|
||||
|
||||
time_t Timer_driver::stime() const { return Hw::get_sys_timer(); }
|
||||
time_t Board::Timer::stime() const { return Hw::get_sys_timer(); }
|
||||
|
||||
void Timer::_start_one_shot(time_t const ticks)
|
||||
{
|
||||
_driver.timeout = _driver.stime() + ticks;
|
||||
Hw::set_sys_timer(_driver.timeout);
|
||||
_device.timeout = _device.stime() + ticks;
|
||||
Hw::set_sys_timer(_device.timeout);
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return ticks / Driver::TICS_PER_US; }
|
||||
return ticks / Board::Timer::TICS_PER_US; }
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return us * Driver::TICS_PER_MS; }
|
||||
return us * Board::Timer::TICS_PER_MS; }
|
||||
|
||||
|
||||
time_t Timer::_max_value() const {
|
||||
@ -49,11 +49,10 @@ time_t Timer::_max_value() const {
|
||||
|
||||
time_t Timer::_duration() const
|
||||
{
|
||||
addr_t time = _driver.stime();
|
||||
return time < _driver.timeout ? _driver.timeout - time
|
||||
: _last_timeout_duration + (time - _driver.timeout);
|
||||
addr_t time = _device.stime();
|
||||
return time < _device.timeout ? _device.timeout - time
|
||||
: _last_timeout_duration + (time - _device.timeout);
|
||||
}
|
||||
|
||||
|
||||
unsigned Timer::interrupt_id() const {
|
||||
return 5; }
|
||||
unsigned Timer::interrupt_id() const { return 5; }
|
||||
|
@ -11,19 +11,20 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
#ifndef _SRC__CORE__SPEC__RISCV__TIMER_H_
|
||||
#define _SRC__CORE__SPEC__RISCV__TIMER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
#include <kernel/types.h>
|
||||
|
||||
namespace Kernel { class Timer_driver; }
|
||||
namespace Board { class Timer; }
|
||||
|
||||
|
||||
/**
|
||||
* Timer driver for core
|
||||
*/
|
||||
struct Kernel::Timer_driver
|
||||
struct Board::Timer
|
||||
{
|
||||
enum {
|
||||
SPIKE_TIMER_HZ = 1000000,
|
||||
@ -31,11 +32,11 @@ struct Kernel::Timer_driver
|
||||
TICS_PER_US = TICS_PER_MS / 1000,
|
||||
};
|
||||
|
||||
time_t timeout = 0;
|
||||
Kernel::time_t timeout = 0;
|
||||
|
||||
time_t stime() const;
|
||||
Kernel::time_t stime() const;
|
||||
|
||||
Timer_driver(unsigned);
|
||||
Timer(unsigned);
|
||||
};
|
||||
|
||||
#endif /* _TIMER_H_ */
|
||||
#endif /* _SRC__CORE__SPEC__RISCV__TIMER_H_ */
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <hw/spec/arm/rpi_board.h>
|
||||
#include <spec/arm/bcm2835_pic.h>
|
||||
#include <spec/arm/bcm2835_system_timer.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Rpi_board;
|
||||
|
@ -16,9 +16,12 @@
|
||||
|
||||
#include <hw/spec/arm_64/rpi3_board.h>
|
||||
#include <spec/arm/bcm2837_pic.h>
|
||||
#include <spec/arm/generic_timer.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Rpi3_board;
|
||||
|
||||
enum { TIMER_IRQ = 1 };
|
||||
};
|
||||
|
||||
#endif /* _CORE__SPEC__RPI3__BOARD_H_ */
|
||||
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* \brief Timer driver for core
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2019-05-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
#include <drivers/timer/util.h>
|
||||
#include <kernel/timer.h>
|
||||
#include <kernel/cpu.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
unsigned Timer::interrupt_id() const { return Board::Pic::TIMER_IRQ; }
|
||||
|
||||
|
||||
unsigned long Timer_driver::_freq() { return Genode::Cpu::Cntfrq_el0::read(); }
|
||||
|
||||
|
||||
Timer_driver::Timer_driver(unsigned) : ticks_per_ms(_freq() / 1000)
|
||||
{
|
||||
Cpu::Cntp_ctl_el0::access_t ctl = 0;
|
||||
Cpu::Cntp_ctl_el0::Enable::set(ctl, 1);
|
||||
Cpu::Cntp_ctl_el0::write(ctl);
|
||||
}
|
||||
|
||||
|
||||
void Timer::_start_one_shot(time_t const ticks)
|
||||
{
|
||||
_driver.last_time = Cpu::Cntpct_el0::read();
|
||||
Cpu::Cntp_tval_el0::write(ticks);
|
||||
Cpu::Cntp_ctl_el0::access_t ctl = Cpu::Cntp_ctl_el0::read();
|
||||
Cpu::Cntp_ctl_el0::Istatus::set(ctl, 0);
|
||||
Cpu::Cntp_ctl_el0::write(ctl);
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::_duration() const
|
||||
{
|
||||
return Cpu::Cntpct_el0::read() - _driver.last_time;
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return Genode::timer_ticks_to_us(ticks, _driver.ticks_per_ms); }
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return (us / 1000) * _driver.ticks_per_ms; }
|
||||
|
||||
|
||||
time_t Timer::_max_value() const {
|
||||
return _driver.ticks_per_ms * 5000; }
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <hw/spec/arm/imx_tzic.h>
|
||||
#include <hw/spec/arm/usb_armory_board.h>
|
||||
#include <spec/arm/imx_epit.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Usb_armory_board;
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/wand_quad_board.h>
|
||||
#include <spec/arm/cortex_a9_private_timer.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Wand_quad_board;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <hw/spec/x86_64/pc_board.h>
|
||||
#include <spec/x86_64/pic.h>
|
||||
#include <spec/x86_64/pit.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Pc_board;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <hw/spec/x86_64/pc_board.h>
|
||||
#include <spec/x86_64/muen/pic.h>
|
||||
#include <spec/x86_64/muen/timer.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Pc_board;
|
||||
|
@ -26,7 +26,7 @@ using namespace Genode;
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
Timer_driver::Timer_driver(unsigned) : ticks_per_ms(sinfo()->get_tsc_khz()), start(0)
|
||||
Board::Timer::Timer(unsigned) : ticks_per_ms(sinfo()->get_tsc_khz()), start(0)
|
||||
{
|
||||
/* first sinfo instance, output status */
|
||||
sinfo()->log_status();
|
||||
@ -67,21 +67,21 @@ void Timer::_start_one_shot(time_t const ticks)
|
||||
{
|
||||
static const time_t MIN_TICKS = 10UL;
|
||||
|
||||
_driver.start = _driver.rdtsc();
|
||||
uint64_t t = _driver.start + ((ticks > MIN_TICKS) ? ticks : MIN_TICKS);
|
||||
_driver.event_page->tsc_trigger = t;
|
||||
_device.start = _device.rdtsc();
|
||||
uint64_t t = _device.start + ((ticks > MIN_TICKS) ? ticks : MIN_TICKS);
|
||||
_device.event_page->tsc_trigger = t;
|
||||
|
||||
if (_driver.guest_event_page)
|
||||
_driver.guest_event_page->tsc_trigger = t;
|
||||
if (_device.guest_event_page)
|
||||
_device.guest_event_page->tsc_trigger = t;
|
||||
}
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return timer_ticks_to_us(ticks, _driver.ticks_per_ms); }
|
||||
return timer_ticks_to_us(ticks, _device.ticks_per_ms); }
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return us * (_driver.ticks_per_ms / 1000); }
|
||||
return us * (_device.ticks_per_ms / 1000); }
|
||||
|
||||
|
||||
time_t Timer::_max_value() const { return ~0UL; }
|
||||
@ -89,5 +89,5 @@ time_t Timer::_max_value() const { return ~0UL; }
|
||||
|
||||
time_t Timer::_duration() const
|
||||
{
|
||||
return _driver.rdtsc() - _driver.start;
|
||||
return _device.rdtsc() - _device.start;
|
||||
}
|
||||
|
@ -17,10 +17,10 @@
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Kernel { class Timer_driver; }
|
||||
namespace Board { class Timer; }
|
||||
|
||||
|
||||
struct Kernel::Timer_driver
|
||||
struct Board::Timer
|
||||
{
|
||||
enum { TIMER_DISABLED = ~0ULL };
|
||||
|
||||
@ -45,7 +45,7 @@ struct Kernel::Timer_driver
|
||||
|
||||
class Invalid_region { };
|
||||
|
||||
Timer_driver(unsigned);
|
||||
Timer(unsigned);
|
||||
};
|
||||
|
||||
#endif /* _TIMER_DRIVER_H_ */
|
@ -26,7 +26,7 @@ using namespace Genode;
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
uint32_t Timer_driver::pit_calc_timer_freq(void)
|
||||
uint32_t Board::Timer::pit_calc_timer_freq(void)
|
||||
{
|
||||
uint32_t t_start, t_end;
|
||||
|
||||
@ -53,7 +53,7 @@ uint32_t Timer_driver::pit_calc_timer_freq(void)
|
||||
}
|
||||
|
||||
|
||||
Timer_driver::Timer_driver(unsigned)
|
||||
Board::Timer::Timer(unsigned)
|
||||
: Mmio(Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()))
|
||||
{
|
||||
/* Enable LAPIC timer in one-shot mode */
|
||||
@ -84,30 +84,30 @@ void Timer::init_cpu_local()
|
||||
* Disable PIT timer channel. This is necessary since BIOS sets up
|
||||
* channel 0 to fire periodically.
|
||||
*/
|
||||
outb(Driver::PIT_MODE, 0x30);
|
||||
outb(Driver::PIT_CH0_DATA, 0);
|
||||
outb(Driver::PIT_CH0_DATA, 0);
|
||||
outb(Board::Timer::PIT_MODE, 0x30);
|
||||
outb(Board::Timer::PIT_CH0_DATA, 0);
|
||||
outb(Board::Timer::PIT_CH0_DATA, 0);
|
||||
}
|
||||
|
||||
|
||||
void Timer::_start_one_shot(time_t const ticks) {
|
||||
_driver.write<Driver::Tmr_initial>(ticks); }
|
||||
_device.write<Board::Timer::Tmr_initial>(ticks); }
|
||||
|
||||
|
||||
time_t Timer::ticks_to_us(time_t const ticks) const {
|
||||
return timer_ticks_to_us(ticks, _driver.ticks_per_ms); }
|
||||
return timer_ticks_to_us(ticks, _device.ticks_per_ms); }
|
||||
|
||||
|
||||
time_t Timer::us_to_ticks(time_t const us) const {
|
||||
return (us / 1000) * _driver.ticks_per_ms; }
|
||||
return (us / 1000) * _device.ticks_per_ms; }
|
||||
|
||||
|
||||
time_t Timer::_max_value() const {
|
||||
return (Driver::Tmr_initial::access_t)~0; }
|
||||
return (Board::Timer::Tmr_initial::access_t)~0; }
|
||||
|
||||
|
||||
time_t Timer::_duration() const {
|
||||
return _last_timeout_duration - _driver.read<Driver::Tmr_current>(); }
|
||||
return _last_timeout_duration - _device.read<Board::Timer::Tmr_current>(); }
|
||||
|
||||
|
||||
unsigned Timer::interrupt_id() const {
|
@ -12,8 +12,8 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_DRIVER_H_
|
||||
#define _TIMER_DRIVER_H_
|
||||
#ifndef _SRC__CORE__SPEC__ARM__PIT_H_
|
||||
#define _SRC__CORE__SPEC__ARM__PIT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
@ -23,12 +23,12 @@
|
||||
#include <port_io.h>
|
||||
#include <board.h>
|
||||
|
||||
namespace Kernel { class Timer_driver; }
|
||||
namespace Board { class Timer; }
|
||||
|
||||
/**
|
||||
* LAPIC-based timer driver for core
|
||||
*/
|
||||
struct Kernel::Timer_driver : Genode::Mmio
|
||||
struct Board::Timer: Genode::Mmio
|
||||
{
|
||||
enum {
|
||||
/* PIT constants */
|
||||
@ -70,7 +70,7 @@ struct Kernel::Timer_driver : Genode::Mmio
|
||||
/* Measure LAPIC timer frequency using PIT channel 2 */
|
||||
Genode::uint32_t pit_calc_timer_freq(void);
|
||||
|
||||
Timer_driver(unsigned);
|
||||
Timer(unsigned);
|
||||
};
|
||||
|
||||
#endif /* _TIMER_DRIVER_H_ */
|
||||
#endif /* _SRC__CORE__SPEC__ARM__PIT_H_ */
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/zynq_qemu_board.h>
|
||||
#include <spec/arm/cortex_a9_private_timer.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Zynq_qemu_board;
|
||||
|
@ -237,6 +237,18 @@ struct Hw::Arm_cpu
|
||||
/* Counter Frequency register */
|
||||
ARM_CP15_REGISTER_32BIT(Cntfrq, c14, c0, 0, 0);
|
||||
|
||||
/* Physical Timer Value register */
|
||||
ARM_CP15_REGISTER_32BIT(Cntp_tval, c14, c2, 0, 0);
|
||||
|
||||
/* Physical Timer Control register */
|
||||
ARM_CP15_REGISTER_32BIT(Cntp_ctl, c14, c2, 0, 1,
|
||||
struct Enable : Bitfield<0, 1> {};
|
||||
struct Istatus : Bitfield<2, 1> {};
|
||||
);
|
||||
|
||||
/* Physical Count register */
|
||||
ARM_CP15_REGISTER_64BIT(Cntpct, c14, 0);
|
||||
|
||||
/******************************
|
||||
** Program status registers **
|
||||
******************************/
|
||||
@ -267,7 +279,6 @@ struct Hw::Arm_cpu
|
||||
|
||||
ARM_BANKED_REGISTER(Cpsr, cpsr);
|
||||
|
||||
|
||||
/**********************************
|
||||
** Cache maintainance functions **
|
||||
**********************************/
|
||||
|
@ -40,8 +40,6 @@ struct Hw::Arm_64_cpu
|
||||
struct El3 : Bitfield<8, 4> {};
|
||||
);
|
||||
|
||||
SYSTEM_REGISTER(64, Cntfrq_el0, cntfrq_el0);
|
||||
|
||||
SYSTEM_REGISTER(64, Current_el, currentel,
|
||||
enum Level { EL0, EL1, EL2, EL3 };
|
||||
struct El : Bitfield<2, 2> {};
|
||||
@ -164,6 +162,8 @@ struct Hw::Arm_64_cpu
|
||||
** Generic timer interface **
|
||||
*****************************/
|
||||
|
||||
SYSTEM_REGISTER(64, Cntfrq_el0, cntfrq_el0);
|
||||
|
||||
SYSTEM_REGISTER(32, Cntp_ctl_el0, cntp_ctl_el0,
|
||||
struct Enable : Bitfield<0, 1> {};
|
||||
struct Istatus : Bitfield<2, 1> {};
|
||||
@ -171,6 +171,11 @@ struct Hw::Arm_64_cpu
|
||||
|
||||
SYSTEM_REGISTER(64, Cntpct_el0, cntpct_el0);
|
||||
SYSTEM_REGISTER(32, Cntp_tval_el0, cntp_tval_el0);
|
||||
|
||||
using Cntfrq = Cntfrq_el0;
|
||||
using Cntp_ctl = Cntp_ctl_el0;
|
||||
using Cntpct = Cntpct_el0;
|
||||
using Cntp_tval = Cntp_tval_el0;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user