1 /* i386-specific clock functions. */ 2 3 #include <machine/ports.h> 4 5 #include "kernel/clock.h" 6 #include "kernel/interrupt.h" 7 #include <minix/u64.h> 8 9 #include <sys/sched.h> /* for CP_*, CPUSTATES */ 10 #if CPUSTATES != MINIX_CPUSTATES 11 /* If this breaks, the code in this file may have to be adapted accordingly. */ 12 #error "MINIX_CPUSTATES value is out of sync with NetBSD's!" 13 #endif 14 15 #ifdef USE_APIC 16 #include "apic.h" 17 #endif 18 19 #include "kernel/spinlock.h" 20 21 #ifdef CONFIG_SMP 22 #include "kernel/smp.h" 23 #endif 24 25 #define CLOCK_ACK_BIT 0x80 /* PS/2 clock interrupt acknowledge bit */ 26 27 /* Clock parameters. */ 28 #define COUNTER_FREQ (2*TIMER_FREQ) /* counter frequency using square wave */ 29 #define LATCH_COUNT 0x00 /* cc00xxxx, c = channel, x = any */ 30 #define SQUARE_WAVE 0x36 /* ccaammmb, a = access, m = mode, b = BCD */ 31 /* 11x11, 11 = LSB then MSB, x11 = sq wave */ 32 #define TIMER_FREQ 1193182 /* clock frequency for timer in PC and AT */ 33 #define TIMER_COUNT(freq) (TIMER_FREQ/(freq)) /* initial value for counter*/ 34 35 static irq_hook_t pic_timer_hook; /* interrupt handler hook */ 36 37 static unsigned probe_ticks; 38 static u64_t tsc0, tsc1; 39 #define PROBE_TICKS (system_hz / 10) 40 41 static unsigned tsc_per_ms[CONFIG_MAX_CPUS]; 42 static unsigned tsc_per_tick[CONFIG_MAX_CPUS]; 43 static uint64_t tsc_per_state[CONFIG_MAX_CPUS][CPUSTATES]; 44 45 /*===========================================================================* 46 * init_8235A_timer * 47 *===========================================================================*/ 48 int init_8253A_timer(const unsigned freq) 49 { 50 /* Initialize channel 0 of the 8253A timer to, e.g., 60 Hz, 51 * and register the CLOCK task's interrupt handler to be run 52 * on every clock tick. 53 */ 54 outb(TIMER_MODE, SQUARE_WAVE); /* run continuously */ 55 outb(TIMER0, (TIMER_COUNT(freq) & 0xff)); /* timer low byte */ 56 outb(TIMER0, TIMER_COUNT(freq) >> 8); /* timer high byte */ 57 58 return OK; 59 } 60 61 /*===========================================================================* 62 * stop_8235A_timer * 63 *===========================================================================*/ 64 void stop_8253A_timer(void) 65 { 66 /* Reset the clock to the BIOS rate. (For rebooting.) */ 67 outb(TIMER_MODE, 0x36); 68 outb(TIMER0, 0); 69 outb(TIMER0, 0); 70 } 71 72 void arch_timer_int_handler(void) 73 { 74 } 75 76 static int calib_cpu_handler(irq_hook_t * UNUSED(hook)) 77 { 78 u64_t tsc; 79 80 probe_ticks++; 81 read_tsc_64(&tsc); 82 83 84 if (probe_ticks == 1) { 85 tsc0 = tsc; 86 } 87 else if (probe_ticks == PROBE_TICKS) { 88 tsc1 = tsc; 89 } 90 91 /* just in case we are in an SMP single cpu fallback mode */ 92 BKL_UNLOCK(); 93 return 1; 94 } 95 96 static void estimate_cpu_freq(void) 97 { 98 u64_t tsc_delta; 99 u64_t cpu_freq; 100 101 irq_hook_t calib_cpu; 102 103 /* set the probe, we use the legacy timer, IRQ 0 */ 104 put_irq_handler(&calib_cpu, CLOCK_IRQ, calib_cpu_handler); 105 106 /* just in case we are in an SMP single cpu fallback mode */ 107 BKL_UNLOCK(); 108 /* set the PIC timer to get some time */ 109 intr_enable(); 110 111 /* loop for some time to get a sample */ 112 while(probe_ticks < PROBE_TICKS) { 113 intr_enable(); 114 } 115 116 intr_disable(); 117 /* just in case we are in an SMP single cpu fallback mode */ 118 BKL_LOCK(); 119 120 /* remove the probe */ 121 rm_irq_handler(&calib_cpu); 122 123 tsc_delta = tsc1 - tsc0; 124 125 cpu_freq = (tsc_delta / (PROBE_TICKS - 1)) * system_hz; 126 cpu_set_freq(cpuid, cpu_freq); 127 cpu_info[cpuid].freq = (unsigned long)(cpu_freq / 1000000); 128 BOOT_VERBOSE(cpu_print_freq(cpuid)); 129 } 130 131 int init_local_timer(unsigned freq) 132 { 133 #ifdef USE_APIC 134 /* if we know the address, lapic is enabled and we should use it */ 135 if (lapic_addr) { 136 unsigned cpu = cpuid; 137 tsc_per_ms[cpu] = (unsigned)(cpu_get_freq(cpu) / 1000); 138 tsc_per_tick[cpu] = (unsigned)(cpu_get_freq(cpu) / system_hz); 139 lapic_set_timer_one_shot(1000000 / system_hz); 140 } else { 141 DEBUGBASIC(("Initiating legacy i8253 timer\n")); 142 #else 143 { 144 #endif 145 init_8253A_timer(freq); 146 estimate_cpu_freq(); 147 /* always only 1 cpu in the system */ 148 tsc_per_ms[0] = (unsigned long)(cpu_get_freq(0) / 1000); 149 tsc_per_tick[0] = (unsigned)(cpu_get_freq(0) / system_hz); 150 } 151 152 return 0; 153 } 154 155 void stop_local_timer(void) 156 { 157 #ifdef USE_APIC 158 if (lapic_addr) { 159 lapic_stop_timer(); 160 apic_eoi(); 161 } else 162 #endif 163 { 164 stop_8253A_timer(); 165 } 166 } 167 168 void restart_local_timer(void) 169 { 170 #ifdef USE_APIC 171 if (lapic_addr) { 172 lapic_restart_timer(); 173 } 174 #endif 175 } 176 177 int register_local_timer_handler(const irq_handler_t handler) 178 { 179 #ifdef USE_APIC 180 if (lapic_addr) { 181 /* Using APIC, it is configured in apic_idt_init() */ 182 BOOT_VERBOSE(printf("Using LAPIC timer as tick source\n")); 183 } else 184 #endif 185 { 186 /* Using PIC, Initialize the CLOCK's interrupt hook. */ 187 pic_timer_hook.proc_nr_e = NONE; 188 pic_timer_hook.irq = CLOCK_IRQ; 189 190 put_irq_handler(&pic_timer_hook, CLOCK_IRQ, handler); 191 } 192 193 return 0; 194 } 195 196 void cycles_accounting_init(void) 197 { 198 #ifdef CONFIG_SMP 199 unsigned cpu = cpuid; 200 #endif 201 202 read_tsc_64(get_cpu_var_ptr(cpu, tsc_ctr_switch)); 203 204 get_cpu_var(cpu, cpu_last_tsc) = 0; 205 get_cpu_var(cpu, cpu_last_idle) = 0; 206 } 207 208 void context_stop(struct proc * p) 209 { 210 u64_t tsc, tsc_delta; 211 u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch); 212 unsigned int cpu, tpt, counter; 213 #ifdef CONFIG_SMP 214 int must_bkl_unlock = 0; 215 216 cpu = cpuid; 217 218 /* 219 * This function is called only if we switch from kernel to user or idle 220 * or back. Therefore this is a perfect location to place the big kernel 221 * lock which will hopefully disappear soon. 222 * 223 * If we stop accounting for KERNEL we must unlock the BKL. If account 224 * for IDLE we must not hold the lock 225 */ 226 if (p == proc_addr(KERNEL)) { 227 u64_t tmp; 228 229 read_tsc_64(&tsc); 230 tmp = tsc - *__tsc_ctr_switch; 231 kernel_ticks[cpu] = kernel_ticks[cpu] + tmp; 232 p->p_cycles = p->p_cycles + tmp; 233 must_bkl_unlock = 1; 234 } else { 235 u64_t bkl_tsc; 236 atomic_t succ; 237 238 read_tsc_64(&bkl_tsc); 239 /* this only gives a good estimate */ 240 succ = big_kernel_lock.val; 241 242 BKL_LOCK(); 243 244 read_tsc_64(&tsc); 245 246 bkl_ticks[cpu] = bkl_ticks[cpu] + tsc - bkl_tsc; 247 bkl_tries[cpu]++; 248 bkl_succ[cpu] += !(!(succ == 0)); 249 250 p->p_cycles = p->p_cycles + tsc - *__tsc_ctr_switch; 251 252 #ifdef CONFIG_SMP 253 /* 254 * Since at the time we got a scheduling IPI we might have been 255 * waiting for BKL already, we may miss it due to a similar IPI to 256 * the cpu which is already waiting for us to handle its. This 257 * results in a live-lock of these two cpus. 258 * 259 * Therefore we always check if there is one pending and if so, 260 * we handle it straight away so the other cpu can continue and 261 * we do not deadlock. 262 */ 263 smp_sched_handler(); 264 #endif 265 } 266 #else 267 read_tsc_64(&tsc); 268 p->p_cycles = p->p_cycles + tsc - *__tsc_ctr_switch; 269 cpu = 0; 270 #endif 271 272 tsc_delta = tsc - *__tsc_ctr_switch; 273 274 if (kbill_ipc) { 275 kbill_ipc->p_kipc_cycles += tsc_delta; 276 kbill_ipc = NULL; 277 } 278 279 if (kbill_kcall) { 280 kbill_kcall->p_kcall_cycles += tsc_delta; 281 kbill_kcall = NULL; 282 } 283 284 /* 285 * Perform CPU average accounting here, rather than in the generic 286 * clock handler. Doing it here offers two advantages: 1) we can 287 * account for time spent in the kernel, and 2) we properly account for 288 * CPU time spent by a process that has a lot of short-lasting activity 289 * such that it spends serious CPU time but never actually runs when a 290 * clock tick triggers. Note that clock speed inaccuracy requires that 291 * the code below is a loop, but the loop will in by far most cases not 292 * be executed more than once, and often be skipped at all. 293 */ 294 tpt = tsc_per_tick[cpu]; 295 296 p->p_tick_cycles += tsc_delta; 297 while (tpt > 0 && p->p_tick_cycles >= tpt) { 298 p->p_tick_cycles -= tpt; 299 300 /* 301 * The process has spent roughly a whole clock tick worth of 302 * CPU cycles. Update its per-process CPU utilization counter. 303 * Some of the cycles may actually have been spent in a 304 * previous second, but that is not a problem. 305 */ 306 cpuavg_increment(&p->p_cpuavg, kclockinfo.uptime, system_hz); 307 } 308 309 /* 310 * deduct the just consumed cpu cycles from the cpu time left for this 311 * process during its current quantum. Skip IDLE and other pseudo kernel 312 * tasks, except for global accounting purposes. 313 */ 314 if (p->p_endpoint >= 0) { 315 /* On MINIX3, the "system" counter covers system processes. */ 316 if (p->p_priv != priv_addr(USER_PRIV_ID)) 317 counter = CP_SYS; 318 else if (p->p_misc_flags & MF_NICED) 319 counter = CP_NICE; 320 else 321 counter = CP_USER; 322 323 #if DEBUG_RACE 324 p->p_cpu_time_left = 0; 325 #else 326 if (tsc_delta < p->p_cpu_time_left) { 327 p->p_cpu_time_left -= tsc_delta; 328 } else { 329 p->p_cpu_time_left = 0; 330 } 331 #endif 332 } else { 333 /* On MINIX3, the "interrupts" counter covers the kernel. */ 334 if (p->p_endpoint == IDLE) 335 counter = CP_IDLE; 336 else 337 counter = CP_INTR; 338 } 339 340 tsc_per_state[cpu][counter] += tsc_delta; 341 342 *__tsc_ctr_switch = tsc; 343 344 #ifdef CONFIG_SMP 345 if(must_bkl_unlock) { 346 BKL_UNLOCK(); 347 } 348 #endif 349 } 350 351 void context_stop_idle(void) 352 { 353 int is_idle; 354 #ifdef CONFIG_SMP 355 unsigned cpu = cpuid; 356 #endif 357 358 is_idle = get_cpu_var(cpu, cpu_is_idle); 359 get_cpu_var(cpu, cpu_is_idle) = 0; 360 361 context_stop(get_cpulocal_var_ptr(idle_proc)); 362 363 if (is_idle) 364 restart_local_timer(); 365 #if SPROFILE 366 if (sprofiling) 367 get_cpulocal_var(idle_interrupted) = 1; 368 #endif 369 } 370 371 u64_t ms_2_cpu_time(unsigned ms) 372 { 373 return (u64_t)tsc_per_ms[cpuid] * ms; 374 } 375 376 unsigned cpu_time_2_ms(u64_t cpu_time) 377 { 378 return (unsigned long)(cpu_time / tsc_per_ms[cpuid]); 379 } 380 381 short cpu_load(void) 382 { 383 u64_t current_tsc, *current_idle; 384 u64_t tsc_delta, idle_delta, busy; 385 struct proc *idle; 386 short load; 387 #ifdef CONFIG_SMP 388 unsigned cpu = cpuid; 389 #endif 390 391 u64_t *last_tsc, *last_idle; 392 393 last_tsc = get_cpu_var_ptr(cpu, cpu_last_tsc); 394 last_idle = get_cpu_var_ptr(cpu, cpu_last_idle); 395 396 idle = get_cpu_var_ptr(cpu, idle_proc);; 397 read_tsc_64(¤t_tsc); 398 current_idle = &idle->p_cycles; /* ptr to idle proc */ 399 400 /* calculate load since last cpu_load invocation */ 401 if (*last_tsc) { 402 tsc_delta = current_tsc - *last_tsc; 403 idle_delta = *current_idle - *last_idle; 404 405 busy = tsc_delta - idle_delta; 406 busy = busy * 100; 407 load = ex64lo(busy / tsc_delta); 408 409 if (load > 100) 410 load = 100; 411 } else 412 load = 0; 413 414 *last_tsc = current_tsc; 415 *last_idle = *current_idle; 416 return load; 417 } 418 419 void busy_delay_ms(int ms) 420 { 421 u64_t cycles = ms_2_cpu_time(ms), tsc0, tsc, tsc1; 422 read_tsc_64(&tsc0); 423 tsc1 = tsc0 + cycles; 424 do { read_tsc_64(&tsc); } while(tsc < tsc1); 425 return; 426 } 427 428 /* 429 * Return the number of clock ticks spent in each of a predefined number of 430 * CPU states. 431 */ 432 void 433 get_cpu_ticks(unsigned int cpu, uint64_t ticks[CPUSTATES]) 434 { 435 int i; 436 437 /* TODO: make this inter-CPU safe! */ 438 for (i = 0; i < CPUSTATES; i++) 439 ticks[i] = tsc_per_state[cpu][i] / tsc_per_tick[cpu]; 440 } 441