xref: /minix/minix/kernel/arch/earm/arch_clock.c (revision 83133719)
1 /* ARM-specific clock functions. */
2 
3 #include "kernel/kernel.h"
4 
5 #include "kernel/clock.h"
6 #include "kernel/proc.h"
7 #include "kernel/interrupt.h"
8 #include <minix/u64.h>
9 #include <minix/board.h>
10 #include "kernel/glo.h"
11 #include "kernel/profile.h"
12 
13 #include <assert.h>
14 
15 
16 #include "kernel/spinlock.h"
17 
18 #ifdef CONFIG_SMP
19 #include "kernel/smp.h"
20 #endif
21 
22 #include "bsp_timer.h"
23 #include "bsp_intr.h"
24 
25 static unsigned tsc_per_ms[CONFIG_MAX_CPUS];
26 
27 int init_local_timer(unsigned freq)
28 {
29 	bsp_timer_init(freq);
30 
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;
35 	} else {
36 		panic("Can not do the clock setup. machine (0x%08x) is unknown\n",machine.board_id);
37 	};
38 
39 	return 0;
40 }
41 
42 void stop_local_timer(void)
43 {
44 	bsp_timer_stop();
45 }
46 
47 void arch_timer_int_handler(void)
48 {
49 	bsp_timer_int_handler();
50 }
51 
52 void cycles_accounting_init(void)
53 {
54 	read_tsc_64(get_cpu_var_ptr(cpu, tsc_ctr_switch));
55 
56 	get_cpu_var(cpu, cpu_last_tsc) = 0;
57 	get_cpu_var(cpu, cpu_last_idle) = 0;
58 }
59 
60 void context_stop(struct proc * p)
61 {
62 	u64_t tsc;
63 	u32_t tsc_delta;
64 	u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch);
65 
66 	read_tsc_64(&tsc);
67 	assert(tsc >= *__tsc_ctr_switch);
68 	tsc_delta = tsc - *__tsc_ctr_switch;
69 	p->p_cycles += tsc_delta;
70 
71 	if(kbill_ipc) {
72 		kbill_ipc->p_kipc_cycles += tsc_delta;
73 		kbill_ipc = NULL;
74 	}
75 
76 	if(kbill_kcall) {
77 		kbill_kcall->p_kcall_cycles += tsc_delta;
78 		kbill_kcall = NULL;
79 	}
80 
81 	/*
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
84 	 * tasks
85 	 */
86 	if (p->p_endpoint >= 0) {
87 #if DEBUG_RACE
88 		p->p_cpu_time_left = 0;
89 #else
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;
93 #endif
94 	}
95 
96 	*__tsc_ctr_switch = tsc;
97 }
98 
99 void context_stop_idle(void)
100 {
101 	int is_idle;
102 #ifdef CONFIG_SMP
103 	unsigned cpu = cpuid;
104 #endif
105 
106 	is_idle = get_cpu_var(cpu, cpu_is_idle);
107 	get_cpu_var(cpu, cpu_is_idle) = 0;
108 
109 	context_stop(get_cpulocal_var_ptr(idle_proc));
110 
111 	if (is_idle)
112 		restart_local_timer();
113 #if SPROFILE
114 	if (sprofiling)
115 		get_cpulocal_var(idle_interrupted) = 1;
116 #endif
117 }
118 
119 void restart_local_timer(void)
120 {
121 }
122 
123 int register_local_timer_handler(const irq_handler_t handler)
124 {
125 	return bsp_register_timer_handler(handler);
126 }
127 
128 u64_t ms_2_cpu_time(unsigned ms)
129 {
130 	return (u64_t)(tsc_per_ms[cpuid]) * ms;
131 }
132 
133 unsigned cpu_time_2_ms(u64_t cpu_time)
134 {
135 	return (unsigned long)(cpu_time / tsc_per_ms[cpuid]);
136 }
137 
138 short cpu_load(void)
139 {
140 	return 0;
141 }
142