hw_x86_64_muen: Use timed events to implement timer

Switch kernel timer driver to timed event interface. The base-hw kernel
expects a configured self-event with ID 31 and target vector 32 to be
present in the system policy.

ssue #2016
This commit is contained in:
Reto Buerki 2016-04-21 14:56:25 +02:00 committed by Norman Feske
parent 6d28ea1c5c
commit 7d00763861
2 changed files with 16 additions and 14 deletions

View File

@ -23,6 +23,7 @@ namespace Genode
TIMER_SIZE = 0x1000,
VECTOR_REMAP_BASE = 48,
TIMER_EVENT_KERNEL = 31,
TIMER_VECTOR_KERNEL = 32,
TIMER_VECTOR_USER = 50,
};

View File

@ -40,13 +40,13 @@ class Genode::Timer
uint64_t _tics_per_ms;
struct Subject_timer
struct Subject_timed_event
{
uint64_t value;
uint8_t vector;
uint64_t tsc_trigger;
uint8_t event_nr :5;
} __attribute__((packed));
struct Subject_timer * _timer_page;
struct Subject_timed_event * _event_page;
inline uint64_t rdtsc()
@ -68,22 +68,23 @@ class Genode::Timer
sinfo()->log_status();
struct Sinfo::Memregion_info region;
if (!sinfo()->get_memregion_info("timer", &region)) {
PERR("muen-timer: Unable to retrieve time memory region");
if (!sinfo()->get_memregion_info("timed_event", &region)) {
PERR("muen-timer: Unable to retrieve timed event region");
throw Invalid_region();
}
_timer_page = (Subject_timer *)region.address;
_timer_page->vector = Board::TIMER_VECTOR_KERNEL;
PINF("muen-timer: page @0x%llx, frequency %llu kHz, vector %u",
region.address, _tics_per_ms, _timer_page->vector);
_event_page = (Subject_timed_event *)region.address;
_event_page->event_nr = Board::TIMER_EVENT_KERNEL;
PINF("muen-timer: page @0x%llx, frequency %llu kHz, event %u",
region.address, _tics_per_ms, _event_page->event_nr);
}
static unsigned interrupt_id(int) {
return Board::TIMER_VECTOR_KERNEL; }
inline void start_one_shot(time_t const tics, unsigned) {
_timer_page->value = rdtsc() + tics; }
_event_page->tsc_trigger = rdtsc() + tics; }
}
time_t tics_to_us(time_t const tics) const {
return (tics / _tics_per_ms) * 1000; }
@ -96,9 +97,9 @@ class Genode::Timer
time_t value(unsigned)
{
const uint64_t now = rdtsc();
if (_timer_page->value != TIMER_DISABLED
&& _timer_page->value > now) {
return _timer_page->value - now;
if (_event_page->tsc_trigger != TIMER_DISABLED
&& _event_page->tsc_trigger > now) {
return _event_page->tsc_trigger - now;
}
return 0;
}