void context_stop(struct proc * p)
{
- u64_t tsc, tsc_delta;
+ u64_t tsc;
+ u32_t tsc_delta;
u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch);
read_tsc_64(&tsc);
- p->p_cycles = add64(p->p_cycles, sub64(tsc, *__tsc_ctr_switch));
-
- tsc_delta = sub64(tsc, *__tsc_ctr_switch);
+ tsc_delta = tsc - *__tsc_ctr_switch;
+ p->p_cycles += tsc_delta;
if(kbill_ipc) {
kbill_ipc->p_kipc_cycles =
*/
if (p->p_endpoint >= 0) {
#if DEBUG_RACE
- make_zero64(p->p_cpu_time_left);
+ p->p_cpu_time_left = 0;
#else
- /* if (tsc_delta < p->p_cpu_time_left) in 64bit */
- if (ex64hi(tsc_delta) < ex64hi(p->p_cpu_time_left) ||
- (ex64hi(tsc_delta) == ex64hi(p->p_cpu_time_left) &&
- ex64lo(tsc_delta) < ex64lo(p->p_cpu_time_left)))
- {
- p->p_cpu_time_left = sub64(p->p_cpu_time_left, tsc_delta);
- }
- else {
- make_zero64(p->p_cpu_time_left);
- }
+ if (tsc_delta < p->p_cpu_time_left) {
+ p->p_cpu_time_left -= tsc_delta;
+ } else p->p_cpu_time_left = 0;
#endif
}
static u32_t phys_get32(phys_bytes v);
+extern vir_bytes omap3_gptimer10_base = OMAP3_GPTIMER10_BASE;
+
void mem_clear_mapcache(void)
{
int i;
return OK;
}
else if (index == frclock_index) {
- minix_kerninfo.minix_frclock = addr;
+ omap3_gptimer10_base = minix_kerninfo.minix_frclock = addr;
return OK;
}
#include "omap_intr.h"
static irq_hook_t omap3_timer_hook; /* interrupt handler hook */
-static u64_t tsc;
+static u64_t high_frc;
+
+vir_bytes omap3_gptimer10_base;
int omap3_register_timer_handler(const irq_handler_t handler)
{
mmio_clear(OMAP3_GPTIMER1_TCLR, OMAP3_TCLR_ST);
}
+static u32_t read_frc(void)
+{
+ u32_t frc = *(u32_t *) ((char *) omap3_gptimer10_base + OMAP3_TCRR);
+ return frc;
+}
+
+static void frc_overflow_check(void)
+{
+ static int prev_frc_valid;
+ static u32_t prev_frc;
+ u32_t cur_frc = read_frc();
+ if(prev_frc_valid && prev_frc > cur_frc)
+ high_frc++;
+ prev_frc = cur_frc;
+ prev_frc_valid = 1;
+}
+
void omap3_timer_int_handler()
{
/* Clear all interrupts */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG;
mmio_write(OMAP3_GPTIMER1_TISR, tisr);
- tsc++;
+ frc_overflow_check();
}
-/* Don't use libminlib's read_tsc_64, but our own version instead. We emulate
- * the ARM Cycle Counter (CCNT) with 1 cycle per ms. We can't rely on the
- * actual counter hardware to be working (i.e., qemu doesn't emulate it at all)
- */
+/* Use the free running clock as TSC */
void read_tsc_64(u64_t *t)
{
- *t = tsc;
+ u32_t now;
+ frc_overflow_check();
+ now = read_frc();
+ *t = (u64_t) now + (high_frc << 32);
}