1 /* ARM-specific clock functions. */
3 #include "kernel/kernel.h"
5 #include "kernel/clock.h"
6 #include "kernel/proc.h"
7 #include "kernel/interrupt.h"
9 #include <minix/board.h>
10 #include "kernel/glo.h"
11 #include "kernel/profile.h"
16 #include "kernel/spinlock.h"
19 #include "kernel/smp.h"
22 #include "bsp_timer.h"
25 static unsigned tsc_per_ms
[CONFIG_MAX_CPUS
];
27 int init_local_timer(unsigned freq
)
31 if (BOARD_IS_BBXM(machine
.board_id
)) {
32 tsc_per_ms
[0] = 16250;
33 } else if (BOARD_IS_BB(machine
.board_id
)) {
34 tsc_per_ms
[0] = 15000;
36 panic("Can not do the clock setup. machine (0x%08x) is unknown\n",machine
.board_id
);
42 void stop_local_timer(void)
47 void arch_timer_int_handler(void)
49 bsp_timer_int_handler();
52 void cycles_accounting_init(void)
54 read_tsc_64(get_cpu_var_ptr(cpu
, tsc_ctr_switch
));
56 get_cpu_var(cpu
, cpu_last_tsc
) = 0;
57 get_cpu_var(cpu
, cpu_last_idle
) = 0;
60 void context_stop(struct proc
* p
)
64 u64_t
* __tsc_ctr_switch
= get_cpulocal_var_ptr(tsc_ctr_switch
);
67 assert(tsc
>= *__tsc_ctr_switch
);
68 tsc_delta
= tsc
- *__tsc_ctr_switch
;
69 p
->p_cycles
+= tsc_delta
;
72 kbill_ipc
->p_kipc_cycles
+= tsc_delta
;
77 kbill_kcall
->p_kcall_cycles
+= tsc_delta
;
82 * deduct the just consumed cpu cycles from the cpu time left for this
83 * process during its current quantum. Skip IDLE and other pseudo kernel
86 if (p
->p_endpoint
>= 0) {
88 p
->p_cpu_time_left
= 0;
90 if (tsc_delta
< p
->p_cpu_time_left
) {
91 p
->p_cpu_time_left
-= tsc_delta
;
92 } else p
->p_cpu_time_left
= 0;
96 *__tsc_ctr_switch
= tsc
;
99 void context_stop_idle(void)
103 unsigned cpu
= cpuid
;
106 is_idle
= get_cpu_var(cpu
, cpu_is_idle
);
107 get_cpu_var(cpu
, cpu_is_idle
) = 0;
109 context_stop(get_cpulocal_var_ptr(idle_proc
));
112 restart_local_timer();
115 get_cpulocal_var(idle_interrupted
) = 1;
119 void restart_local_timer(void)
123 int register_local_timer_handler(const irq_handler_t handler
)
125 return bsp_register_timer_handler(handler
);
128 u64_t
ms_2_cpu_time(unsigned ms
)
130 return (u64_t
)(tsc_per_ms
[cpuid
]) * ms
;
133 unsigned cpu_time_2_ms(u64_t cpu_time
)
135 return (unsigned long)(cpu_time
/ tsc_per_ms
[cpuid
]);