libsel4platsupport: allow tsc timer to be constructed with previously established frequency
diff --git a/libsel4platsupport/plat_include/pc99/sel4platsupport/plat/timer.h b/libsel4platsupport/plat_include/pc99/sel4platsupport/plat/timer.h index 2b44ebf..842e3cb 100644 --- a/libsel4platsupport/plat_include/pc99/sel4platsupport/plat/timer.h +++ b/libsel4platsupport/plat_include/pc99/sel4platsupport/plat/timer.h
@@ -17,9 +17,21 @@ /** * Get a tsc backed seL4_timer_t; * + * @param freq frequency of the tsc. + * @return NULL on error. + */ +seL4_timer_t *sel4platsupport_get_tsc_timer_freq(uint64_t freq); + +/** + * Get a tsc backed seL4_timer_t; + * + * Note that measuring the tsc frequency is expensive, so use of this function should be minimal. + * * @param timeout_timer timer that implements timeouts to calculate the CPU frequency with. * @return NULL on error. */ + seL4_timer_t *sel4platsupport_get_tsc_timer(seL4_timer_t *timeout_timer); + #endif /* _SEL4PLATSUPPORT_PLAT_TIMER_H */
diff --git a/libsel4platsupport/src/plat/pc99/timer.c b/libsel4platsupport/src/plat/pc99/timer.c index 658e335..84536bd 100644 --- a/libsel4platsupport/src/plat/pc99/timer.c +++ b/libsel4platsupport/src/plat/pc99/timer.c
@@ -31,19 +31,50 @@ return pit; } -seL4_timer_t * -sel4platsupport_get_tsc_timer(seL4_timer_t *timeout_timer) +static seL4_timer_t * +finish_get_tsc(seL4_timer_t *seL4_timer, pstimer_t *ps_timer) { - - seL4_timer_t *timer = calloc(1, sizeof(seL4_timer_t)); - if (timer == NULL) { + if (ps_timer == NULL) { + ZF_LOGE("Failed to init tsc"); + free(seL4_timer); return NULL; } - timer->timer = tsc_get_timer(timeout_timer->timer); - - return timer; + seL4_timer->timer = ps_timer; + return seL4_timer; } +seL4_timer_t * +sel4platsupport_get_tsc_timer_freq(uint64_t freq) +{ + if (freq == 0) { + ZF_LOGE("Can't init tsc with 0 freq"); + return NULL; + } + seL4_timer_t *timer = calloc(1, sizeof(seL4_timer_t)); + if (timer == NULL) { + ZF_LOGE("Failed to allocate timer"); + return NULL; + } + + return finish_get_tsc(timer, tsc_get_timer_with_freq(freq)); +} + +seL4_timer_t * +sel4platsupport_get_tsc_timer(seL4_timer_t *timeout_timer) +{ + if (timeout_timer == NULL) { + ZF_LOGE("Cannot initialise tsc frequency, timeout timer is NULL"); + return NULL; + } + + seL4_timer_t *timer = calloc(1, sizeof(seL4_timer_t)); + if (timer == NULL) { + ZF_LOGE("Failed to allocate timer"); + return NULL; + } + + return finish_get_tsc(timer, tsc_get_timer(timeout_timer)); +}
diff --git a/libsel4platsupport/src/timer_common.c b/libsel4platsupport/src/timer_common.c index 704c1c8..bb5e649 100644 --- a/libsel4platsupport/src/timer_common.c +++ b/libsel4platsupport/src/timer_common.c
@@ -91,6 +91,7 @@ /* map in the frame */ timer_data->vaddr = vspace_map_pages(vspace, &frame_cap, NULL, seL4_AllRights, 1, seL4_PageBits, 0); + ZF_LOGV("Mapped timer at %p\n", timer_data->vaddr); if (timer_data->vaddr == NULL) { LOG_ERROR("Failed to map page at vaddr %p\n", timer_data->vaddr); goto error; @@ -108,6 +109,7 @@ goto error; } + ZF_LOGV("Timer initialised\n"); /* success */ return timer_data;