2 /* ARM-specific clock functions. */
4 #include "kernel/kernel.h"
6 #include "kernel/clock.h"
7 #include "kernel/proc.h"
8 #include "kernel/interrupt.h"
10 #include "kernel/glo.h"
11 #include "kernel/profile.h"
14 #include "kernel/spinlock.h"
17 #include "kernel/smp.h"
20 #include "omap_timer.h"
21 #include "omap_intr.h"
23 static unsigned tsc_per_ms
[CONFIG_MAX_CPUS
];
25 int init_local_timer(unsigned freq
)
27 omap3_timer_init(freq
);
29 /* always only 1 cpu in the system */
35 void stop_local_timer(void)
40 void arch_timer_int_handler(void)
42 omap3_timer_int_handler();
45 void cycles_accounting_init(void)
47 read_tsc_64(get_cpu_var_ptr(cpu
, tsc_ctr_switch
));
49 make_zero64(get_cpu_var(cpu
, cpu_last_tsc
));
50 make_zero64(get_cpu_var(cpu
, cpu_last_idle
));
53 void context_stop(struct proc
* p
)
57 u64_t
* __tsc_ctr_switch
= get_cpulocal_var_ptr(tsc_ctr_switch
);
60 tsc_delta
= tsc
- *__tsc_ctr_switch
;
61 p
->p_cycles
+= tsc_delta
;
64 kbill_ipc
->p_kipc_cycles
=
65 add64(kbill_ipc
->p_kipc_cycles
, tsc_delta
);
70 kbill_kcall
->p_kcall_cycles
=
71 add64(kbill_kcall
->p_kcall_cycles
, tsc_delta
);
76 * deduct the just consumed cpu cycles from the cpu time left for this
77 * process during its current quantum. Skip IDLE and other pseudo kernel
80 if (p
->p_endpoint
>= 0) {
82 p
->p_cpu_time_left
= 0;
84 if (tsc_delta
< p
->p_cpu_time_left
) {
85 p
->p_cpu_time_left
-= tsc_delta
;
86 } else p
->p_cpu_time_left
= 0;
90 *__tsc_ctr_switch
= tsc
;
93 void context_stop_idle(void)
100 is_idle
= get_cpu_var(cpu
, cpu_is_idle
);
101 get_cpu_var(cpu
, cpu_is_idle
) = 0;
103 context_stop(get_cpulocal_var_ptr(idle_proc
));
106 restart_local_timer();
109 get_cpulocal_var(idle_interrupted
) = 1;
113 void restart_local_timer(void)
117 int register_local_timer_handler(const irq_handler_t handler
)
119 return omap3_register_timer_handler(handler
);
122 u64_t
ms_2_cpu_time(unsigned ms
)
124 return mul64u(tsc_per_ms
[cpuid
], ms
);
127 unsigned cpu_time_2_ms(u64_t cpu_time
)
129 return div64u(cpu_time
, tsc_per_ms
[cpuid
]);