1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz and Don Ahn. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 37 */ 38 39#include <sys/cdefs.h> 40__FBSDID("$FreeBSD$"); 41 42/* #define DELAYDEBUG */ 43/* 44 * Routines to handle clock hardware. 45 */ 46 47#include "opt_ddb.h" 48#include "opt_clock.h" 49 50#include <sys/param.h> 51#include <sys/systm.h> 52#include <sys/bus.h> 53#include <sys/clock.h> 54#include <sys/lock.h> 55#include <sys/mutex.h> 56#include <sys/proc.h> 57#include <sys/time.h> 58#include <sys/timeet.h> 59#include <sys/timetc.h> 60#include <sys/kernel.h> 61#include <sys/limits.h> 62#include <sys/sysctl.h> 63#include <sys/cons.h> 64#include <sys/power.h> 65 66#include <machine/clock.h> 67#include <machine/cputypes.h> 68#include <machine/frame.h> 69#include <machine/intr_machdep.h> 70#include <machine/md_var.h> 71#include <machine/psl.h> 72#if defined(SMP) 73#include <machine/smp.h> 74#endif 75#include <machine/specialreg.h> 76#include <machine/timerreg.h> 77 78#include <x86/isa/icu.h> 79#include <x86/isa/isa.h> 80#include <isa/rtc.h> 81 82#include <vm/vm.h> 83#include <vm/pmap.h> 84#include <machine/pmap.h> 85#include <xen/hypervisor.h> 86#include <xen/xen-os.h> 87#include <machine/xen/xenfunc.h> 88#include <xen/interface/vcpu.h> 89#include <machine/cpu.h> 90#include <xen/xen_intr.h> 91 92/* 93 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we 94 * can use a simple formula for leap years. 95 */ 96#define LEAPYEAR(y) (!((y) % 4)) 97#define DAYSPERYEAR (28+30*4+31*7) 98 99#ifndef TIMER_FREQ 100#define TIMER_FREQ 1193182 101#endif 102 103#ifdef CYC2NS_SCALE_FACTOR 104#undef CYC2NS_SCALE_FACTOR 105#endif 106#define CYC2NS_SCALE_FACTOR 10 107 108/* Values for timerX_state: */ 109#define RELEASED 0 110#define RELEASE_PENDING 1 111#define ACQUIRED 2 112#define ACQUIRE_PENDING 3 113 114struct mtx clock_lock; 115#define RTC_LOCK_INIT \ 116 mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE) 117#define RTC_LOCK mtx_lock_spin(&clock_lock) 118#define RTC_UNLOCK mtx_unlock_spin(&clock_lock) 119#define NS_PER_TICK (1000000000ULL/hz) 120 121int adjkerntz; /* local offset from GMT in seconds */ 122int clkintr_pending; 123int pscnt = 1; 124int psdiv = 1; 125int wall_cmos_clock; 126u_int timer_freq = TIMER_FREQ; 127static u_long cyc2ns_scale; 128static uint64_t processed_system_time; /* stime (ns) at last processing. */ 129 130extern volatile uint64_t xen_timer_last_time; 131 132#define do_div(n,base) ({ \ 133 unsigned long __upper, __low, __high, __mod, __base; \ 134 __base = (base); \ 135 __asm("":"=a" (__low), "=d" (__high):"A" (n)); \ 136 __upper = __high; \ 137 if (__high) { \ 138 __upper = __high % (__base); \ 139 __high = __high / (__base); \ 140 } \ 141 __asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \ 142 __asm("":"=A" (n):"a" (__low),"d" (__high)); \ 143 __mod; \ 144}) 145 146 147/* convert from cycles(64bits) => nanoseconds (64bits) 148 * basic equation: 149 * ns = cycles / (freq / ns_per_sec) 150 * ns = cycles * (ns_per_sec / freq) 151 * ns = cycles * (10^9 / (cpu_mhz * 10^6)) 152 * ns = cycles * (10^3 / cpu_mhz) 153 * 154 * Then we use scaling math (suggested by george@mvista.com) to get: 155 * ns = cycles * (10^3 * SC / cpu_mhz) / SC 156 * ns = cycles * cyc2ns_scale / SC 157 * 158 * And since SC is a constant power of two, we can convert the div 159 * into a shift. 160 * -johnstul@us.ibm.com "math is hard, lets go shopping!" 161 */ 162static inline void set_cyc2ns_scale(unsigned long cpu_mhz) 163{ 164 cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz; 165} 166 167static inline unsigned long long cycles_2_ns(unsigned long long cyc) 168{ 169 return ((cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR); 170} 171 172static uint32_t 173getit(void) 174{ 175 return (xen_timer_last_time); 176} 177 178 179/* 180 * XXX: timer needs more SMP work. 181 */ 182void 183i8254_init(void) 184{ 185 186 RTC_LOCK_INIT; 187} 188 189/* 190 * Wait "n" microseconds. 191 * Relies on timer 1 counting down from (timer_freq / hz) 192 * Note: timer had better have been programmed before this is first used! 193 */ 194void 195DELAY(int n) 196{ 197 int delta, ticks_left; 198 uint32_t tick, prev_tick; 199#ifdef DELAYDEBUG 200 int getit_calls = 1; 201 int n1; 202 static int state = 0; 203 204 if (state == 0) { 205 state = 1; 206 for (n1 = 1; n1 <= 10000000; n1 *= 10) 207 DELAY(n1); 208 state = 2; 209 } 210 if (state == 1) 211 printf("DELAY(%d)...", n); 212#endif 213 /* 214 * Read the counter first, so that the rest of the setup overhead is 215 * counted. Guess the initial overhead is 20 usec (on most systems it 216 * takes about 1.5 usec for each of the i/o's in getit(). The loop 217 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 218 * multiplications and divisions to scale the count take a while). 219 * 220 * However, if ddb is active then use a fake counter since reading 221 * the i8254 counter involves acquiring a lock. ddb must not go 222 * locking for many reasons, but it calls here for at least atkbd 223 * input. 224 */ 225 prev_tick = getit(); 226 227 n -= 0; /* XXX actually guess no initial overhead */ 228 /* 229 * Calculate (n * (timer_freq / 1e6)) without using floating point 230 * and without any avoidable overflows. 231 */ 232 if (n <= 0) 233 ticks_left = 0; 234 else if (n < 256) 235 /* 236 * Use fixed point to avoid a slow division by 1000000. 237 * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest. 238 * 2^15 is the first power of 2 that gives exact results 239 * for n between 0 and 256. 240 */ 241 ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15; 242 else 243 /* 244 * Don't bother using fixed point, although gcc-2.7.2 245 * generates particularly poor code for the long long 246 * division, since even the slow way will complete long 247 * before the delay is up (unless we're interrupted). 248 */ 249 ticks_left = ((u_int)n * (long long)timer_freq + 999999) 250 / 1000000; 251 252 while (ticks_left > 0) { 253 tick = getit(); 254#ifdef DELAYDEBUG 255 ++getit_calls; 256#endif 257 delta = tick - prev_tick; 258 prev_tick = tick; 259 if (delta < 0) { 260 /* 261 * Guard against timer0_max_count being wrong. 262 * This shouldn't happen in normal operation, 263 * but it may happen if set_timer_freq() is 264 * traced. 265 */ 266 /* delta += timer0_max_count; ??? */ 267 if (delta < 0) 268 delta = 0; 269 } 270 ticks_left -= delta; 271 } 272#ifdef DELAYDEBUG 273 if (state == 1) 274 printf(" %d calls to getit() at %d usec each\n", 275 getit_calls, (n + 5) / getit_calls); 276#endif 277} 278 279void 280startrtclock() 281{ 282 uint64_t __cpu_khz; 283 uint32_t cpu_khz; 284 struct vcpu_time_info *info; 285 286 __cpu_khz = 1000000ULL << 32; 287 info = &HYPERVISOR_shared_info->vcpu_info[0].time; 288 289 (void)do_div(__cpu_khz, info->tsc_to_system_mul); 290 if ( info->tsc_shift < 0 ) 291 cpu_khz = __cpu_khz << -info->tsc_shift; 292 else 293 cpu_khz = __cpu_khz >> info->tsc_shift; 294 295 printf("Xen reported: %u.%03u MHz processor.\n", 296 cpu_khz / 1000, cpu_khz % 1000); 297 298 /* (10^6 * 2^32) / cpu_hz = (10^3 * 2^32) / cpu_khz = 299 (2^32 * 1 / (clocks/us)) */ 300 301 set_cyc2ns_scale(cpu_khz/1000); 302 tsc_freq = cpu_khz * 1000; 303} 304 305/* 306 * RTC support routines 307 */ 308 309 310static __inline int 311readrtc(int port) 312{ 313 return(bcd2bin(rtcin(port))); 314} 315 316 317#ifdef XEN_PRIVILEGED_GUEST 318 319/* 320 * Initialize the time of day register, based on the time base which is, e.g. 321 * from a filesystem. 322 */ 323static void 324domu_inittodr(time_t base) 325{ 326 unsigned long sec; 327 int s, y; 328 struct timespec ts; 329 330 update_wallclock(); 331 add_uptime_to_wallclock(); 332 333 RTC_LOCK; 334 335 if (base) { 336 ts.tv_sec = base; 337 ts.tv_nsec = 0; 338 tc_setclock(&ts); 339 } 340 341 sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 342 343 y = time_second - shadow_tv.tv_sec; 344 if (y <= -2 || y >= 2) { 345 /* badly off, adjust it */ 346 tc_setclock(&shadow_tv); 347 } 348 RTC_UNLOCK; 349} 350 351/* 352 * Write system time back to RTC. 353 */ 354static void 355domu_resettodr(void) 356{ 357 unsigned long tm; 358 int s; 359 dom0_op_t op; 360 struct shadow_time_info *shadow; 361 struct pcpu *pc; 362 363 pc = pcpu_find(smp_processor_id()); 364 shadow = &pc->pc_shadow_time; 365 if (xen_disable_rtc_set) 366 return; 367 368 s = splclock(); 369 tm = time_second; 370 splx(s); 371 372 tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 373 374 if ((xen_start_info->flags & SIF_INITDOMAIN) && 375 !independent_wallclock) 376 { 377 op.cmd = DOM0_SETTIME; 378 op.u.settime.secs = tm; 379 op.u.settime.nsecs = 0; 380 op.u.settime.system_time = shadow->system_timestamp; 381 HYPERVISOR_dom0_op(&op); 382 update_wallclock(); 383 add_uptime_to_wallclock(); 384 } else if (independent_wallclock) { 385 /* notyet */ 386 ; 387 } 388} 389 390/* 391 * Initialize the time of day register, based on the time base which is, e.g. 392 * from a filesystem. 393 */ 394void 395inittodr(time_t base) 396{ 397 unsigned long sec, days; 398 int year, month; 399 int y, m, s; 400 struct timespec ts; 401 402 if (!(xen_start_info->flags & SIF_INITDOMAIN)) { 403 domu_inittodr(base); 404 return; 405 } 406 407 if (base) { 408 s = splclock(); 409 ts.tv_sec = base; 410 ts.tv_nsec = 0; 411 tc_setclock(&ts); 412 splx(s); 413 } 414 415 /* Look if we have a RTC present and the time is valid */ 416 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 417 goto wrong_time; 418 419 /* wait for time update to complete */ 420 /* If RTCSA_TUP is zero, we have at least 244us before next update */ 421 s = splhigh(); 422 while (rtcin(RTC_STATUSA) & RTCSA_TUP) { 423 splx(s); 424 s = splhigh(); 425 } 426 427 days = 0; 428#ifdef USE_RTC_CENTURY 429 year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100; 430#else 431 year = readrtc(RTC_YEAR) + 1900; 432 if (year < 1970) 433 year += 100; 434#endif 435 if (year < 1970) { 436 splx(s); 437 goto wrong_time; 438 } 439 month = readrtc(RTC_MONTH); 440 for (m = 1; m < month; m++) 441 days += daysinmonth[m-1]; 442 if ((month > 2) && LEAPYEAR(year)) 443 days ++; 444 days += readrtc(RTC_DAY) - 1; 445 for (y = 1970; y < year; y++) 446 days += DAYSPERYEAR + LEAPYEAR(y); 447 sec = ((( days * 24 + 448 readrtc(RTC_HRS)) * 60 + 449 readrtc(RTC_MIN)) * 60 + 450 readrtc(RTC_SEC)); 451 /* sec now contains the number of seconds, since Jan 1 1970, 452 in the local time zone */ 453 454 sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 455 456 y = time_second - sec; 457 if (y <= -2 || y >= 2) { 458 /* badly off, adjust it */ 459 ts.tv_sec = sec; 460 ts.tv_nsec = 0; 461 tc_setclock(&ts); 462 } 463 splx(s); 464 return; 465 466 wrong_time: 467 printf("Invalid time in real time clock.\n"); 468 printf("Check and reset the date immediately!\n"); 469} 470 471 472/* 473 * Write system time back to RTC 474 */ 475void 476resettodr() 477{ 478 unsigned long tm; 479 int y, m, s; 480 481 if (!(xen_start_info->flags & SIF_INITDOMAIN)) { 482 domu_resettodr(); 483 return; 484 } 485 486 if (xen_disable_rtc_set) 487 return; 488 489 s = splclock(); 490 tm = time_second; 491 splx(s); 492 493 /* Disable RTC updates and interrupts. */ 494 writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); 495 496 /* Calculate local time to put in RTC */ 497 498 tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 499 500 writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */ 501 writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */ 502 writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */ 503 504 /* We have now the days since 01-01-1970 in tm */ 505 writertc(RTC_WDAY, (tm + 4) % 7 + 1); /* Write back Weekday */ 506 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); 507 tm >= m; 508 y++, m = DAYSPERYEAR + LEAPYEAR(y)) 509 tm -= m; 510 511 /* Now we have the years in y and the day-of-the-year in tm */ 512 writertc(RTC_YEAR, bin2bcd(y%100)); /* Write back Year */ 513#ifdef USE_RTC_CENTURY 514 writertc(RTC_CENTURY, bin2bcd(y/100)); /* ... and Century */ 515#endif 516 for (m = 0; ; m++) { 517 int ml; 518 519 ml = daysinmonth[m]; 520 if (m == 1 && LEAPYEAR(y)) 521 ml++; 522 if (tm < ml) 523 break; 524 tm -= ml; 525 } 526 527 writertc(RTC_MONTH, bin2bcd(m + 1)); /* Write back Month */ 528 writertc(RTC_DAY, bin2bcd(tm + 1)); /* Write back Month Day */ 529 530 /* Reenable RTC updates and interrupts. */ 531 writertc(RTC_STATUSB, RTCSB_24HR); 532 rtcin(RTC_INTR); 533} 534#endif 535 536/* 537 * Start clocks running. 538 */ 539void 540cpu_initclocks(void) 541{ 542 cpu_initclocks_bsp(); 543} 544 545/* Return system time offset by ticks */ 546uint64_t 547get_system_time(int ticks) 548{ 549 return (processed_system_time + (ticks * NS_PER_TICK)); 550} 551 552int 553timer_spkr_acquire(void) 554{ 555 556 return (0); 557} 558 559int 560timer_spkr_release(void) 561{ 562 563 return (0); 564} 565 566void 567timer_spkr_setfreq(int freq) 568{ 569 570} 571 572