diff --git a/repos/base-nova/include/nova/syscall-generic.h b/repos/base-nova/include/nova/syscall-generic.h index 75a7f8e179..2aa12d948d 100644 --- a/repos/base-nova/include/nova/syscall-generic.h +++ b/repos/base-nova/include/nova/syscall-generic.h @@ -756,6 +756,7 @@ namespace Nova { PT_SEL_PARENT = 0x1a, /* convention on Genode */ PT_SEL_MAIN_EC = 0x1c, /* convention on Genode */ PT_SEL_STARTUP = 0x1e, + SM_SEL_SIGNAL = 0x1e, /* alias of PT_SEL_STARTUP */ PT_SEL_RECALL = 0x1f, SM_SEL_EC = 0x1d, /* convention on Genode */ }; diff --git a/repos/base-nova/src/include/signal_source/client.h b/repos/base-nova/src/include/signal_source/client.h index 83a2caf9d7..1ff928e52b 100644 --- a/repos/base-nova/src/include/signal_source/client.h +++ b/repos/base-nova/src/include/signal_source/client.h @@ -54,9 +54,10 @@ namespace Genode { { /* request mapping of semaphore capability selector */ Thread * myself = Thread::myself(); - request_signal_sm_cap(myself->native_thread().exc_pt_sel + Nova::PT_SEL_PAGE_FAULT, - myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP); - _sem = Capability_space::import(myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP); + auto const &exc_base = myself->native_thread().exc_pt_sel; + request_signal_sm_cap(exc_base + Nova::PT_SEL_PAGE_FAULT, + exc_base + Nova::SM_SEL_SIGNAL); + _sem = Capability_space::import(exc_base + Nova::SM_SEL_SIGNAL); call(_sem); } diff --git a/repos/base-nova/src/timer/nova/time_source.cc b/repos/base-nova/src/timer/nova/time_source.cc index ebf83fb4a5..d1b9fb697b 100644 --- a/repos/base-nova/src/timer/nova/time_source.cc +++ b/repos/base-nova/src/timer/nova/time_source.cc @@ -28,7 +28,7 @@ void Timer::Time_source::schedule_timeout(Microseconds duration, Threaded_time_source::handler(handler); /* check whether to cancel last timeout */ - if (duration.value == 0 && _sem != ~0UL) { + if (duration.value == 0 && _sem) { uint8_t res = Nova::sm_ctrl(_sem, Nova::SEMAPHORE_UP); if (res != Nova::NOVA_OK) nova_die(); @@ -40,10 +40,14 @@ void Timer::Time_source::schedule_timeout(Microseconds duration, void Timer::Time_source::_wait_for_irq() { - if (_sem == ~0UL) { - _sem = Thread::native_thread().exc_pt_sel + SM_SEL_EC; } + if (!_sem) { + /* initialize first time in context of running thread */ + auto const &exc_base = Thread::native_thread().exc_pt_sel; + request_signal_sm_cap(exc_base + Nova::PT_SEL_PAGE_FAULT, + exc_base + Nova::SM_SEL_SIGNAL); - addr_t sem = _sem; + _sem = Thread::native_thread().exc_pt_sel + SM_SEL_SIGNAL; + } /* calculate absolute timeout */ Trace::Timestamp now = Trace::timestamp(); @@ -52,7 +56,7 @@ void Timer::Time_source::_wait_for_irq() if (_timeout_us == max_timeout().value) { /* tsc_absolute == 0 means blocking without timeout */ - uint8_t res = sm_ctrl(sem, SEMAPHORE_DOWN, 0); + uint8_t res = sm_ctrl(_sem, SEMAPHORE_DOWN, 0); if (res != Nova::NOVA_OK && res != Nova::NOVA_TIMEOUT) { nova_die(); } @@ -60,7 +64,7 @@ void Timer::Time_source::_wait_for_irq() /* block until timeout fires or it gets canceled */ unsigned long long tsc_absolute = now + us_64 * (_tsc_khz / TSC_FACTOR); - uint8_t res = sm_ctrl(sem, SEMAPHORE_DOWN, tsc_absolute); + uint8_t res = sm_ctrl(_sem, SEMAPHORE_DOWN, tsc_absolute); if (res != Nova::NOVA_OK && res != Nova::NOVA_TIMEOUT) { nova_die(); } } diff --git a/repos/base-nova/src/timer/nova/time_source.h b/repos/base-nova/src/timer/nova/time_source.h index fa3fe8beb4..7145d57a41 100644 --- a/repos/base-nova/src/timer/nova/time_source.h +++ b/repos/base-nova/src/timer/nova/time_source.h @@ -57,7 +57,7 @@ class Timer::Time_source : public Threaded_time_source return 1000*1000; } - Genode::addr_t _sem { ~0UL }; + Genode::addr_t _sem { 0 }; uint64_t _timeout_us { 0 }; unsigned long const _tsc_khz; Duration _curr_time { Microseconds(0) };