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