hw: move timer into board.h

Unify the generic timer implementation for ARMv7 and ARMv8.

Ref #3445
This commit is contained in:
Stefan Kalkowski 2019-07-10 16:12:21 +02:00 committed by Christian Helmuth
parent 5c7436bf10
commit 907de9d37f
48 changed files with 242 additions and 318 deletions

View File

@ -10,8 +10,8 @@ INC_DIR += $(REP_DIR)/src/core/spec/rpi
# add C++ sources # add C++ sources
SRC_CC += platform_services.cc SRC_CC += platform_services.cc
SRC_CC += spec/arm/bcm2835_pic.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/arm/cpu.cc
SRC_CC += spec/rpi/timer.cc
# include less specific configuration # include less specific configuration
include $(REP_DIR)/lib/mk/spec/arm_v6/core-hw.inc include $(REP_DIR)/lib/mk/spec/arm_v6/core-hw.inc

View File

@ -9,8 +9,8 @@
INC_DIR += $(REP_DIR)/src/core/spec/imx53_qsb INC_DIR += $(REP_DIR)/src/core/spec/imx53_qsb
INC_DIR += $(REP_DIR)/src/core/spec/imx53 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/arm/imx_tzic.cc
SRC_CC += spec/imx53/timer.cc
# include less specific configuration # include less specific configuration
include $(REP_DIR)/lib/mk/spec/cortex_a8/core-hw.inc include $(REP_DIR)/lib/mk/spec/cortex_a8/core-hw.inc

View File

@ -9,9 +9,9 @@ INC_DIR += $(REP_DIR)/src/core/spec/imx7d_sabre
INC_DIR += $(REP_DIR)/src/core/spec/arm_v7/virtualization INC_DIR += $(REP_DIR)/src/core/spec/arm_v7/virtualization
# add C++ sources # add C++ sources
SRC_CC += spec/arm/generic_timer.cc
SRC_CC += spec/arm/gicv2.cc SRC_CC += spec/arm/gicv2.cc
SRC_CC += spec/arndale/platform_services.cc SRC_CC += spec/arndale/platform_services.cc
SRC_CC += spec/imx7d_sabre/timer.cc
SRC_CC += kernel/vm_thread_on.cc SRC_CC += kernel/vm_thread_on.cc
SRC_CC += spec/arm_v7/virtualization/kernel/vm.cc SRC_CC += spec/arm_v7/virtualization/kernel/vm.cc
SRC_CC += spec/arm_v7/vm_session_component.cc SRC_CC += spec/arm_v7/vm_session_component.cc

View File

@ -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/trustzone/kernel/vm.cc
SRC_CC += spec/arm_v7/vm_session_component.cc SRC_CC += spec/arm_v7/vm_session_component.cc
SRC_CC += spec/arm_v7/trustzone/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/arm/imx_tzic.cc
SRC_CC += spec/imx53/timer.cc
# add assembly sources # add assembly sources
SRC_S += spec/arm_v7/trustzone/exception_vector.s SRC_S += spec/arm_v7/trustzone/exception_vector.s

View File

@ -11,7 +11,7 @@ SRC_CC += spec/arm_v8/kernel/thread.cc
SRC_CC += spec/arm_v8/kernel/cpu.cc SRC_CC += spec/arm_v8/kernel/cpu.cc
SRC_CC += spec/arm/platform_support.cc SRC_CC += spec/arm/platform_support.cc
SRC_CC += spec/arm/bcm2837_pic.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 SRC_CC += spec/64bit/memory_map.cc
#add assembly sources #add assembly sources

View File

@ -9,7 +9,7 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/cortex_a9
# add C++ sources # add C++ sources
SRC_CC += spec/cortex_a9/board.cc 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/gicv2.cc
SRC_CC += spec/arm/kernel/lock.cc SRC_CC += spec/arm/kernel/lock.cc
SRC_CC += kernel/vm_thread_off.cc SRC_CC += kernel/vm_thread_off.cc

View File

@ -8,7 +8,7 @@
INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/exynos5 INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/exynos5
# add C++ sources # add C++ sources
SRC_CC += spec/exynos5/timer.cc SRC_CC += spec/arm/exynos_mct.cc
# include less specific configuration # include less specific configuration
include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a15/core-hw.inc include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a15/core-hw.inc

View File

@ -17,7 +17,7 @@ SRC_CC += kernel/cpu_mp.cc
SRC_CC += kernel/vm_thread_off.cc SRC_CC += kernel/vm_thread_off.cc
SRC_CC += kernel/lock.cc SRC_CC += kernel/lock.cc
SRC_CC += spec/x86_64/pic.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/kernel/thread_exception.cc
SRC_CC += spec/x86_64/platform_support.cc SRC_CC += spec/x86_64/platform_support.cc
SRC_CC += spec/x86/platform_services.cc SRC_CC += spec/x86/platform_services.cc

View File

@ -91,7 +91,7 @@ void Timer::process_timeouts()
Timer::Timer(Cpu & cpu) Timer::Timer(Cpu & cpu)
: _driver(cpu.id()), _irq(interrupt_id(), cpu), : _device(cpu.id()), _irq(interrupt_id(), cpu),
_last_timeout_duration(_max_value()) _last_timeout_duration(_max_value())
{ {
/* /*

View File

@ -21,8 +21,7 @@
/* Genode includes */ /* Genode includes */
#include <util/list.h> #include <util/list.h>
/* Core includes */ #include <board.h>
#include <timer_driver.h>
namespace Kernel namespace Kernel
{ {
@ -74,9 +73,7 @@ class Kernel::Timer
void occurred() override; void occurred() override;
}; };
using Driver = Timer_driver; Board::Timer _device;
Driver _driver;
Irq _irq; Irq _irq;
time_t _time = 0; time_t _time = 0;
time_t _last_timeout_duration; time_t _last_timeout_duration;

View File

@ -1,5 +1,5 @@
/* /*
* \brief Timer implementation specific to Rpi * \brief Timer implementation specific to BCM2835 System Timer
* \author Norman Feske * \author Norman Feske
* \author Stefan Kalkowski * \author Stefan Kalkowski
* \author Martin Stein * \author Martin Stein
@ -14,32 +14,37 @@
*/ */
/* core includes */ /* core includes */
#include <board.h>
#include <platform.h> #include <platform.h>
#include <kernel/timer.h> #include <kernel/timer.h>
using namespace Genode; using namespace Genode;
using namespace Kernel; 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)) { } : Mmio(Platform::mmio_to_virt(Board::SYSTEM_TIMER_MMIO_BASE)) { }
void Timer::_start_one_shot(time_t const ticks) void Timer::_start_one_shot(time_t const ticks)
{ {
_driver.write<Driver::Cs::M1>(1); _device.write<Device::Cs::M1>(1);
_driver.read<Driver::Cs>(); _device.read<Device::Cs>();
_driver.write<Driver::Cmp>(_driver.read<Driver::Clo>() _device.write<Device::Cmp>(_device.read<Device::Clo>()
+ (ticks < 2 ? 2 : ticks)); + (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 { 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 { 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 { time_t Timer::_max_value() const {
@ -48,9 +53,9 @@ time_t Timer::_max_value() const {
time_t Timer::_duration() const time_t Timer::_duration() const
{ {
Driver::Clo::access_t const clo = _driver.read<Driver::Clo>(); Device::Clo::access_t const clo = _device.read<Device::Clo>();
Driver::Cmp::access_t const cmp = _driver.read<Driver::Cmp>(); Device::Cmp::access_t const cmp = _device.read<Device::Cmp>();
Driver::Cs::access_t const irq = _driver.read<Driver::Cs::M1>(); Device::Cs::access_t const irq = _device.read<Device::Cs::M1>();
uint32_t d = (irq) ? (uint32_t)_last_timeout_duration + (clo - cmp) uint32_t d = (irq) ? (uint32_t)_last_timeout_duration + (clo - cmp)
: clo - (cmp - _last_timeout_duration); : clo - (cmp - _last_timeout_duration);
return d; return d;

View File

@ -11,31 +11,26 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#ifndef _TIMER_DRIVER_H_ #ifndef _SRC__CORE__SPEC__ARM__BCM2835_SYSTEM_TIMER_H_
#define _TIMER_DRIVER_H_ #define _SRC__CORE__SPEC__ARM__BCM2835_SYSTEM_TIMER_H_
/* Kernel includes */ /* Kernel includes */
#include <util/mmio.h> #include <util/mmio.h>
/* core includes */ namespace Board { class Timer; }
#include <board.h>
namespace Kernel { class Timer_driver; }
/** /**
* Timer driver for core * Timer driver for core
* *
* Timer channel 0 apparently doesn't work on the RPI, so we use channel 1 * 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 Cs : Register<0x0, 32> { struct M1 : Bitfield<1, 1> { }; };
struct Clo : Register<0x4, 32> { }; struct Clo : Register<0x4, 32> { };
struct Cmp : Register<0x10, 32> { }; struct Cmp : Register<0x10, 32> { };
Timer_driver(unsigned); Timer(unsigned);
}; };
#endif /* _TIMER_DRIVER_H_ */ #endif /* _SRC__CORE__SPEC__ARM__BCM2835_SYSTEM_TIMER_H_ */

View File

@ -23,7 +23,6 @@ class Board::Pic : Genode::Mmio
public: public:
enum { enum {
TIMER_IRQ = 1,
NR_OF_IRQ = 64, NR_OF_IRQ = 64,
/* /*

View File

@ -22,9 +22,17 @@
using namespace Genode; using namespace Genode;
using namespace Kernel; 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)) : Mmio(Platform::mmio_to_virt(Board::Cpu_mmio::PRIVATE_TIMER_MMIO_BASE))
{ {
enum { PRESCALER = Board::CORTEX_A9_PRIVATE_TIMER_DIV - 1 }; 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, * First unset the interrupt flag,
* otherwise if the tick is small enough, we loose an interrupt * otherwise if the tick is small enough, we loose an interrupt
*/ */
_driver.write<Driver::Interrupt_status::Event>(1); _device.write<Device::Interrupt_status::Event>(1);
_driver.write<Driver::Counter>(ticks); _device.write<Device::Counter>(ticks);
} }
time_t Timer::ticks_to_us(time_t const ticks) const { 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 { 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 { 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 time_t Timer::_duration() const
{ {
Driver::Counter::access_t last = _last_timeout_duration; Device::Counter::access_t last = _last_timeout_duration;
Driver::Counter::access_t cnt = _driver.read<Driver::Counter>(); Device::Counter::access_t cnt = _device.read<Device::Counter>();
Driver::Counter::access_t ret = (_driver.read<Driver::Interrupt_status::Event>()) Device::Counter::access_t ret = (_device.read<Device::Interrupt_status::Event>())
? _max_value() - cnt + last : last - cnt; ? _max_value() - cnt + last : last - cnt;
return ret; return ret;
} }

View File

@ -1,5 +1,5 @@
/* /*
* \brief Timer implementation specific to Cortex A9 * \brief Private Timer implementation specific to Cortex A9
* \author Martin stein * \author Martin stein
* \date 2011-12-13 * \date 2011-12-13
*/ */
@ -11,28 +11,19 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#ifndef _TIMER_DRIVER_H_ #ifndef _SRC__CORE__SPEC__ARM__CORTEX_A9_PRIVATE_TIMER_H_
#define _TIMER_DRIVER_H_ #define _SRC__CORE__SPEC__ARM__CORTEX_A9_PRIVATE_TIMER_H_
/* Genode includes */ /* Genode includes */
#include <util/mmio.h> #include <util/mmio.h>
/* core includes */ namespace Board { class Timer; }
#include <board.h>
namespace Kernel { class Timer_driver; }
/** /**
* Timer driver for core * 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 * Load value register
*/ */
@ -62,7 +53,7 @@ struct Kernel::Timer_driver : Genode::Mmio
struct Event : Bitfield<0,1> { }; /* if counter hit zero */ 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_ */

View File

@ -25,7 +25,7 @@ using namespace Kernel;
unsigned Timer::interrupt_id() const unsigned Timer::interrupt_id() const
{ {
switch (_driver.cpu_id) { switch (_device.cpu_id) {
case 0: return Board::MCT_IRQ_L0; case 0: return Board::MCT_IRQ_L0;
case 1: return Board::MCT_IRQ_L1; case 1: return Board::MCT_IRQ_L1;
default: return 0; 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)), Mmio(Platform::mmio_to_virt(Board::MCT_MMIO_BASE)),
local(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) : Mmio(base)
{ {
write<Int_enb>(Int_enb::Frceie::bits(1)); 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) void Timer::_start_one_shot(time_t const ticks)
{ {
_driver.local.cnt = _driver.local.read<Driver::Local::Tcnto>(); using Device = Board::Timer;
_driver.local.write<Driver::Local::Int_cstat::Frccnt>(1); _device.local.cnt = _device.local.read<Device::Local::Tcnto>();
_driver.local.acked_write<Driver::Local::Frcntb, _device.local.write<Device::Local::Int_cstat::Frccnt>(1);
Driver::Local::Wstat::Frcntb>(ticks); _device.local.acked_write<Device::Local::Frcntb,
Device::Local::Wstat::Frcntb>(ticks);
} }
time_t Timer::_duration() const 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; return ret;
} }
time_t Timer::ticks_to_us(time_t const ticks) const { 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 { 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 { time_t Timer::_max_value() const {

View File

@ -11,8 +11,8 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#ifndef _TIMER_DRIVER_H_ #ifndef _SRC__CORE__SPEC__ARM__EXYNOS_MCT_H_
#define _TIMER_DRIVER_H_ #define _SRC__CORE__SPEC__ARM__EXYNOS_MCT_H_
/* Kernel includes */ /* Kernel includes */
#include <util/mmio.h> #include <util/mmio.h>
@ -20,10 +20,10 @@
/* base-hw includes */ /* base-hw includes */
#include <kernel/types.h> #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 { enum {
PRESCALER = 1, PRESCALER = 1,
@ -108,14 +108,14 @@ struct Kernel::Timer_driver : Genode::Mmio
* *
* \param clock input clock * \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; } return clock / (PRESCALER + 1) / (1 << DIV_MUX) / 1000; }
Local local; Local local;
unsigned const ticks_per_ms; unsigned const ticks_per_ms;
unsigned const cpu_id; 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_ */

View 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; }

View File

@ -11,24 +11,23 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#ifndef _TIMER_DRIVER_H_ #ifndef _SRC__CORE__SPEC__ARM__GENERIC_TIMER_H_
#define _TIMER_DRIVER_H_ #define _SRC__CORE__SPEC__ARM__GENERIC_TIMER_H_
/* base-hw includes */ /* base-hw includes */
#include <kernel/types.h> #include <kernel/types.h>
namespace Kernel { class Timer_driver; } namespace Board { class Timer; }
struct Board::Timer
struct Kernel::Timer_driver
{ {
unsigned long _freq(); unsigned long _freq();
unsigned const ticks_per_ms; 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_ */

View File

@ -26,7 +26,7 @@ using namespace Kernel;
unsigned Timer::interrupt_id() const { return Board::EPIT_1_IRQ; } 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)) : Mmio(Platform::mmio_to_virt(Board::EPIT_1_MMIO_BASE))
{ {
reset(); reset();
@ -52,17 +52,17 @@ void Timer::_start_one_shot(time_t const ticks)
* First unset the interrupt flag, * First unset the interrupt flag,
* otherwise if the tick is small enough, we loose an interrupt * otherwise if the tick is small enough, we loose an interrupt
*/ */
_driver.write<Driver::Sr::Ocif>(1); _device.write<Board::Timer::Sr::Ocif>(1);
_driver.write<Driver::Lr>(ticks - 1); _device.write<Board::Timer::Lr>(ticks - 1);
} }
time_t Timer::ticks_to_us(time_t const ticks) const { 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 { 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 { time_t Timer::_max_value() const {
@ -71,9 +71,10 @@ time_t Timer::_max_value() const {
time_t Timer::_duration() const time_t Timer::_duration() const
{ {
Driver::Cnt::access_t last = _last_timeout_duration; using Device = Board::Timer;
Driver::Cnt::access_t cnt = _driver.read<Driver::Cnt>(); Device::Cnt::access_t last = _last_timeout_duration;
Driver::Cnt::access_t ret = (_driver.read<Driver::Sr::Ocif>()) 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; ? _max_value() - cnt + last : last - cnt;
return ret; return ret;
} }

View File

@ -11,18 +11,18 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#ifndef _TIMER_DRIVER_H_ #ifndef _SRC__CORE__SPEC__ARM__IMX_EPIT_H_
#define _TIMER_DRIVER_H_ #define _SRC__CORE__SPEC__ARM__IMX_EPIT_H_
/* Kernel includes */ /* Kernel includes */
#include <util/mmio.h> #include <util/mmio.h>
namespace Kernel { class Timer_driver; } namespace Board { class Timer; }
/** /**
* Timer driver for core * Timer driver for core
*/ */
struct Kernel::Timer_driver : Genode::Mmio struct Board::Timer : Genode::Mmio
{ {
enum { TICS_PER_MS = 33333 }; enum { TICS_PER_MS = 33333 };
@ -86,7 +86,7 @@ struct Kernel::Timer_driver : Genode::Mmio
write<Sr::Ocif>(1); write<Sr::Ocif>(1);
} }
Timer_driver(unsigned); Timer(unsigned);
}; };
#endif /* _TIMER_DRIVER_H_ */ #endif /* _SRC__CORE__SPEC__ARM__IMX_EPIT_H_ */

View File

@ -16,6 +16,7 @@
#include <hw/spec/arm/gicv2.h> #include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/arndale_board.h> #include <hw/spec/arm/arndale_board.h>
#include <spec/arm/exynos_mct.h>
namespace Board { namespace Board {
using namespace Hw::Arndale_board; using namespace Hw::Arndale_board;

View File

@ -17,6 +17,7 @@
#include <hw/spec/arm/imx_tzic.h> #include <hw/spec/arm/imx_tzic.h>
#include <hw/spec/arm/imx53_qsb_board.h> #include <hw/spec/arm/imx53_qsb_board.h>
#include <spec/arm/imx_epit.h>
namespace Board { namespace Board {
using namespace Hw::Imx53_qsb_board; using namespace Hw::Imx53_qsb_board;

View File

@ -16,6 +16,7 @@
#include <hw/spec/arm/gicv2.h> #include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/imx6q_sabrelite_board.h> #include <hw/spec/arm/imx6q_sabrelite_board.h>
#include <spec/arm/cortex_a9_private_timer.h>
namespace Board { namespace Board {

View File

@ -16,11 +16,14 @@
#include <hw/spec/arm/gicv2.h> #include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/imx7d_sabre_board.h> #include <hw/spec/arm/imx7d_sabre_board.h>
#include <spec/arm/generic_timer.h>
namespace Board { namespace Board {
using namespace Hw::Imx7d_sabre_board; using namespace Hw::Imx7d_sabre_board;
using Pic = Hw::Gicv2; using Pic = Hw::Gicv2;
enum { TIMER_IRQ = 30 };
} }
#endif /* _CORE__SPEC__IMX7_SABRELITE__BOARD_H_ */ #endif /* _CORE__SPEC__IMX7_SABRELITE__BOARD_H_ */

View File

@ -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; }

View File

@ -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_ */

View File

@ -16,6 +16,7 @@
#include <hw/spec/arm/gicv2.h> #include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/nit6_solox_board.h> #include <hw/spec/arm/nit6_solox_board.h>
#include <spec/arm/cortex_a9_private_timer.h>
namespace Board { namespace Board {
using namespace Hw::Nit6_solox_board; using namespace Hw::Nit6_solox_board;

View File

@ -16,6 +16,7 @@
#include <hw/spec/arm/gicv2.h> #include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/odroid_xu_board.h> #include <hw/spec/arm/odroid_xu_board.h>
#include <spec/arm/exynos_mct.h>
namespace Board { namespace Board {
using namespace Hw::Odroid_xu_board; using namespace Hw::Odroid_xu_board;

View File

@ -17,6 +17,7 @@
#include <hw/spec/arm/gicv2.h> #include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/panda_board.h> #include <hw/spec/arm/panda_board.h>
#include <spec/arm/cortex_a9_private_timer.h>
namespace Board { namespace Board {
using namespace Hw::Panda_board; using namespace Hw::Panda_board;

View File

@ -16,6 +16,7 @@
#include <hw/spec/arm/gicv2.h> #include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/pbxa9_board.h> #include <hw/spec/arm/pbxa9_board.h>
#include <spec/arm/cortex_a9_private_timer.h>
namespace Board { namespace Board {
using namespace Hw::Pbxa9_board; using namespace Hw::Pbxa9_board;

View File

@ -16,6 +16,7 @@
#include <hw/spec/riscv/board.h> #include <hw/spec/riscv/board.h>
#include <spec/riscv/pic.h> #include <spec/riscv/pic.h>
#include <spec/riscv/timer.h>
namespace Board { using namespace Hw::Riscv_board; } namespace Board { using namespace Hw::Riscv_board; }

View File

@ -19,28 +19,28 @@ using namespace Genode;
using namespace Kernel; using namespace Kernel;
Timer_driver::Timer_driver(unsigned) Board::Timer::Timer(unsigned)
{ {
/* enable timer interrupt */ /* enable timer interrupt */
enum { STIE = 0x20 }; enum { STIE = 0x20 };
asm volatile ("csrs sie, %0" : : "r"(STIE)); 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) void Timer::_start_one_shot(time_t const ticks)
{ {
_driver.timeout = _driver.stime() + ticks; _device.timeout = _device.stime() + ticks;
Hw::set_sys_timer(_driver.timeout); Hw::set_sys_timer(_device.timeout);
} }
time_t Timer::ticks_to_us(time_t const ticks) const { 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 { 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 { time_t Timer::_max_value() const {
@ -49,11 +49,10 @@ time_t Timer::_max_value() const {
time_t Timer::_duration() const time_t Timer::_duration() const
{ {
addr_t time = _driver.stime(); addr_t time = _device.stime();
return time < _driver.timeout ? _driver.timeout - time return time < _device.timeout ? _device.timeout - time
: _last_timeout_duration + (time - _driver.timeout); : _last_timeout_duration + (time - _device.timeout);
} }
unsigned Timer::interrupt_id() const { unsigned Timer::interrupt_id() const { return 5; }
return 5; }

View File

@ -11,19 +11,20 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#ifndef _TIMER_H_ #ifndef _SRC__CORE__SPEC__RISCV__TIMER_H_
#define _TIMER_H_ #define _SRC__CORE__SPEC__RISCV__TIMER_H_
/* Genode includes */ /* Genode includes */
#include <base/stdint.h> #include <base/stdint.h>
#include <kernel/types.h>
namespace Kernel { class Timer_driver; } namespace Board { class Timer; }
/** /**
* Timer driver for core * Timer driver for core
*/ */
struct Kernel::Timer_driver struct Board::Timer
{ {
enum { enum {
SPIKE_TIMER_HZ = 1000000, SPIKE_TIMER_HZ = 1000000,
@ -31,11 +32,11 @@ struct Kernel::Timer_driver
TICS_PER_US = TICS_PER_MS / 1000, 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_ */

View File

@ -17,6 +17,7 @@
#include <hw/spec/arm/rpi_board.h> #include <hw/spec/arm/rpi_board.h>
#include <spec/arm/bcm2835_pic.h> #include <spec/arm/bcm2835_pic.h>
#include <spec/arm/bcm2835_system_timer.h>
namespace Board { namespace Board {
using namespace Hw::Rpi_board; using namespace Hw::Rpi_board;

View File

@ -16,9 +16,12 @@
#include <hw/spec/arm_64/rpi3_board.h> #include <hw/spec/arm_64/rpi3_board.h>
#include <spec/arm/bcm2837_pic.h> #include <spec/arm/bcm2837_pic.h>
#include <spec/arm/generic_timer.h>
namespace Board { namespace Board {
using namespace Hw::Rpi3_board; using namespace Hw::Rpi3_board;
enum { TIMER_IRQ = 1 };
}; };
#endif /* _CORE__SPEC__RPI3__BOARD_H_ */ #endif /* _CORE__SPEC__RPI3__BOARD_H_ */

View File

@ -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; }

View File

@ -17,6 +17,7 @@
#include <hw/spec/arm/imx_tzic.h> #include <hw/spec/arm/imx_tzic.h>
#include <hw/spec/arm/usb_armory_board.h> #include <hw/spec/arm/usb_armory_board.h>
#include <spec/arm/imx_epit.h>
namespace Board { namespace Board {
using namespace Hw::Usb_armory_board; using namespace Hw::Usb_armory_board;

View File

@ -17,6 +17,7 @@
#include <hw/spec/arm/gicv2.h> #include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/wand_quad_board.h> #include <hw/spec/arm/wand_quad_board.h>
#include <spec/arm/cortex_a9_private_timer.h>
namespace Board { namespace Board {
using namespace Hw::Wand_quad_board; using namespace Hw::Wand_quad_board;

View File

@ -16,6 +16,7 @@
#include <hw/spec/x86_64/pc_board.h> #include <hw/spec/x86_64/pc_board.h>
#include <spec/x86_64/pic.h> #include <spec/x86_64/pic.h>
#include <spec/x86_64/pit.h>
namespace Board { namespace Board {
using namespace Hw::Pc_board; using namespace Hw::Pc_board;

View File

@ -16,6 +16,7 @@
#include <hw/spec/x86_64/pc_board.h> #include <hw/spec/x86_64/pc_board.h>
#include <spec/x86_64/muen/pic.h> #include <spec/x86_64/muen/pic.h>
#include <spec/x86_64/muen/timer.h>
namespace Board { namespace Board {
using namespace Hw::Pc_board; using namespace Hw::Pc_board;

View File

@ -26,7 +26,7 @@ using namespace Genode;
using namespace Kernel; 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 */ /* first sinfo instance, output status */
sinfo()->log_status(); sinfo()->log_status();
@ -67,21 +67,21 @@ void Timer::_start_one_shot(time_t const ticks)
{ {
static const time_t MIN_TICKS = 10UL; static const time_t MIN_TICKS = 10UL;
_driver.start = _driver.rdtsc(); _device.start = _device.rdtsc();
uint64_t t = _driver.start + ((ticks > MIN_TICKS) ? ticks : MIN_TICKS); uint64_t t = _device.start + ((ticks > MIN_TICKS) ? ticks : MIN_TICKS);
_driver.event_page->tsc_trigger = t; _device.event_page->tsc_trigger = t;
if (_driver.guest_event_page) if (_device.guest_event_page)
_driver.guest_event_page->tsc_trigger = t; _device.guest_event_page->tsc_trigger = t;
} }
time_t Timer::ticks_to_us(time_t const ticks) const { 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 { 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; } 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 time_t Timer::_duration() const
{ {
return _driver.rdtsc() - _driver.start; return _device.rdtsc() - _device.start;
} }

View File

@ -17,10 +17,10 @@
/* Genode includes */ /* Genode includes */
#include <base/stdint.h> #include <base/stdint.h>
namespace Kernel { class Timer_driver; } namespace Board { class Timer; }
struct Kernel::Timer_driver struct Board::Timer
{ {
enum { TIMER_DISABLED = ~0ULL }; enum { TIMER_DISABLED = ~0ULL };
@ -45,7 +45,7 @@ struct Kernel::Timer_driver
class Invalid_region { }; class Invalid_region { };
Timer_driver(unsigned); Timer(unsigned);
}; };
#endif /* _TIMER_DRIVER_H_ */ #endif /* _TIMER_DRIVER_H_ */

View File

@ -26,7 +26,7 @@ using namespace Genode;
using namespace Kernel; 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; 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())) : Mmio(Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()))
{ {
/* Enable LAPIC timer in one-shot mode */ /* 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 * Disable PIT timer channel. This is necessary since BIOS sets up
* channel 0 to fire periodically. * channel 0 to fire periodically.
*/ */
outb(Driver::PIT_MODE, 0x30); outb(Board::Timer::PIT_MODE, 0x30);
outb(Driver::PIT_CH0_DATA, 0); outb(Board::Timer::PIT_CH0_DATA, 0);
outb(Driver::PIT_CH0_DATA, 0); outb(Board::Timer::PIT_CH0_DATA, 0);
} }
void Timer::_start_one_shot(time_t const ticks) { 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 { 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 { 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 { 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 { 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 { unsigned Timer::interrupt_id() const {

View File

@ -12,8 +12,8 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#ifndef _TIMER_DRIVER_H_ #ifndef _SRC__CORE__SPEC__ARM__PIT_H_
#define _TIMER_DRIVER_H_ #define _SRC__CORE__SPEC__ARM__PIT_H_
/* Genode includes */ /* Genode includes */
#include <util/mmio.h> #include <util/mmio.h>
@ -23,12 +23,12 @@
#include <port_io.h> #include <port_io.h>
#include <board.h> #include <board.h>
namespace Kernel { class Timer_driver; } namespace Board { class Timer; }
/** /**
* LAPIC-based timer driver for core * LAPIC-based timer driver for core
*/ */
struct Kernel::Timer_driver : Genode::Mmio struct Board::Timer: Genode::Mmio
{ {
enum { enum {
/* PIT constants */ /* PIT constants */
@ -70,7 +70,7 @@ struct Kernel::Timer_driver : Genode::Mmio
/* Measure LAPIC timer frequency using PIT channel 2 */ /* Measure LAPIC timer frequency using PIT channel 2 */
Genode::uint32_t pit_calc_timer_freq(void); Genode::uint32_t pit_calc_timer_freq(void);
Timer_driver(unsigned); Timer(unsigned);
}; };
#endif /* _TIMER_DRIVER_H_ */ #endif /* _SRC__CORE__SPEC__ARM__PIT_H_ */

View File

@ -18,6 +18,7 @@
#include <hw/spec/arm/gicv2.h> #include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/zynq_qemu_board.h> #include <hw/spec/arm/zynq_qemu_board.h>
#include <spec/arm/cortex_a9_private_timer.h>
namespace Board { namespace Board {
using namespace Hw::Zynq_qemu_board; using namespace Hw::Zynq_qemu_board;

View File

@ -237,6 +237,18 @@ struct Hw::Arm_cpu
/* Counter Frequency register */ /* Counter Frequency register */
ARM_CP15_REGISTER_32BIT(Cntfrq, c14, c0, 0, 0); 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 ** ** Program status registers **
******************************/ ******************************/
@ -267,7 +279,6 @@ struct Hw::Arm_cpu
ARM_BANKED_REGISTER(Cpsr, cpsr); ARM_BANKED_REGISTER(Cpsr, cpsr);
/********************************** /**********************************
** Cache maintainance functions ** ** Cache maintainance functions **
**********************************/ **********************************/

View File

@ -40,8 +40,6 @@ struct Hw::Arm_64_cpu
struct El3 : Bitfield<8, 4> {}; struct El3 : Bitfield<8, 4> {};
); );
SYSTEM_REGISTER(64, Cntfrq_el0, cntfrq_el0);
SYSTEM_REGISTER(64, Current_el, currentel, SYSTEM_REGISTER(64, Current_el, currentel,
enum Level { EL0, EL1, EL2, EL3 }; enum Level { EL0, EL1, EL2, EL3 };
struct El : Bitfield<2, 2> {}; struct El : Bitfield<2, 2> {};
@ -164,6 +162,8 @@ struct Hw::Arm_64_cpu
** Generic timer interface ** ** Generic timer interface **
*****************************/ *****************************/
SYSTEM_REGISTER(64, Cntfrq_el0, cntfrq_el0);
SYSTEM_REGISTER(32, Cntp_ctl_el0, cntp_ctl_el0, SYSTEM_REGISTER(32, Cntp_ctl_el0, cntp_ctl_el0,
struct Enable : Bitfield<0, 1> {}; struct Enable : Bitfield<0, 1> {};
struct Istatus : Bitfield<2, 1> {}; struct Istatus : Bitfield<2, 1> {};
@ -171,6 +171,11 @@ struct Hw::Arm_64_cpu
SYSTEM_REGISTER(64, Cntpct_el0, cntpct_el0); SYSTEM_REGISTER(64, Cntpct_el0, cntpct_el0);
SYSTEM_REGISTER(32, Cntp_tval_el0, cntp_tval_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;
}; };