diff --git a/arch/aarch64/kernel/timer.c b/arch/aarch64/kernel/timer.c index ed86c1691..62716f402 100644 --- a/arch/aarch64/kernel/timer.c +++ b/arch/aarch64/kernel/timer.c @@ -50,7 +50,7 @@ extern int32_t boot_processor; #ifdef DYNAMIC_TICKS DEFINE_PER_CORE(uint64_t, last_tsc, 0); -static uint64_t boot_tsc = 0; +static uint64_t boot_tsc __attribute__ ((section(".data"))) = 0; void check_ticks(void) { @@ -59,7 +59,7 @@ void check_ticks(void) return; const uint64_t curr_tsc = get_cntpct(); - rmb(); + mb(); const uint64_t diff_tsc = curr_tsc - per_core(last_tsc); const uint64_t diff_ticks = (diff_tsc * (uint64_t) TIMER_FREQ) / freq_hz; @@ -70,7 +70,22 @@ void check_ticks(void) rmb(); } } + +uint64_t get_uptime(void) +{ + const uint64_t curr_tsc = get_cntpct(); + + mb(); + uint64_t diff = curr_tsc - per_core(last_rdtsc); + + return (1000ULL*diff) / freq_hz; +} #else +uint64_t get_uptime(void) +{ + return (get_clock_tick() * 1000) / TIMER_FREQ; +} + static void restart_periodic_timer(void) { set_cntp_tval(freq_hz / TIMER_FREQ); @@ -172,13 +187,19 @@ int timer_wait(unsigned int ticks) return 0; } +int clock_init(void) +{ +#ifdef DYNAMIC_TICKS + if (!boot_tsc) + boot_tsc = get_cntpct(); +#endif + + return 0; +} + int timer_init(void) { #ifdef DYNAMIC_TICKS - if (boot_tsc) - return 0; - - boot_tsc = get_cntpct(); set_per_core(last_tsc, boot_tsc); #endif diff --git a/arch/x86_64/kernel/timer.c b/arch/x86_64/kernel/timer.c index 58172bb72..6fe5412b9 100644 --- a/arch/x86_64/kernel/timer.c +++ b/arch/x86_64/kernel/timer.c @@ -47,7 +47,7 @@ extern int32_t boot_processor; #ifdef DYNAMIC_TICKS DEFINE_PER_CORE(uint64_t, last_rdtsc, 0); -uint64_t boot_tsc = 0; +uint64_t boot_tsc __attribute__ ((section(".data"))) = 0; void check_ticks(void) { @@ -56,7 +56,7 @@ void check_ticks(void) return; const uint64_t curr_rdtsc = rdtsc(); - rmb(); + mb(); const uint64_t diff_cycles = curr_rdtsc - per_core(last_rdtsc); const uint64_t cpu_freq_hz = 1000000ULL * (uint64_t) get_cpu_frequency(); @@ -68,6 +68,22 @@ void check_ticks(void) mb(); } } + +uint64_t get_uptime(void) +{ + const uint64_t cpu_freq_hz = 1000000ULL * (uint64_t) get_cpu_frequency(); + const uint64_t curr_tsc = rdtsc(); + + mb(); + uint64_t diff = curr_tsc - per_core(last_rdtsc); + + return (1000ULL*diff) / cpu_freq_hz; +} +#else +uint64_t get_uptime(void) +{ + return (get_clock_tick() * 1000) / TIMER_FREQ; +} #endif /* @@ -162,6 +178,16 @@ static int pit_init(void) return 0; } +int clock_init(void) +{ +#ifdef DYNAMIC_TICKS + if (!boot_tsc) + boot_tsc = has_rdtscp() ? rdtscp(NULL) : rdtsc(); +#endif + + return 0; +} + /* * Sets up the system clock by installing the timer handler * into IRQ0 @@ -169,11 +195,7 @@ static int pit_init(void) int timer_init(void) { #ifdef DYNAMIC_TICKS - if (boot_tsc) - { - set_per_core(last_rdtsc, boot_tsc); - return 0; - } + set_per_core(last_rdtsc, boot_tsc); #endif /* @@ -183,11 +205,6 @@ int timer_init(void) irq_install_handler(32, timer_handler); irq_install_handler(123, timer_handler); -#ifdef DYNAMIC_TICKS - boot_tsc = has_rdtscp() ? rdtscp(NULL) : rdtsc(); - set_per_core(last_rdtsc, boot_tsc); -#endif - if (cpu_freq) // do we need to configure the timer? return 0; diff --git a/include/hermit/time.h b/include/hermit/time.h index 5c32cd5fe..a1e2a628f 100644 --- a/include/hermit/time.h +++ b/include/hermit/time.h @@ -55,6 +55,9 @@ struct tms { */ int timer_init(void); +/** @brief Initialize clock */ +int clock_init(void); + /** @brief Initialized a timer * * @param ticks Amount of ticks to wait @@ -81,9 +84,8 @@ static inline uint64_t get_clock_tick(void) */ static inline void sleep(unsigned int sec) { timer_wait(sec*TIMER_FREQ); } -/** @brief Get milliseconds since system boot - */ -static inline uint64_t get_uptime() { return (get_clock_tick() * 1000) / TIMER_FREQ; } +/** @brief Get milliseconds since system boot */ +uint64_t get_uptime(void); #ifdef __cplusplus } diff --git a/kernel/main.c b/kernel/main.c index 9da479e85..72681ff93 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -113,14 +113,15 @@ extern void signal_init(); static int hermit_init(void) { - uint32_t i; + clock_init(); + size_t sz = (size_t) &percore_end0 - (size_t) &percore_start; // initialize .kbss sections memset((void*)&tdata_end, 0x00, (size_t) &__bss_start - (size_t) &tdata_end); // initialize .percore section => copy first section to all other sections - for(i=1; i