1/* 2 * linux/arch/i386/kernel/time.c 3 * 4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 5 * 6 * This file contains the PC-specific time handling details: 7 * reading the RTC at bootup, etc.. 8 * 1994-07-02 Alan Modra 9 * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime 10 * 1995-03-26 Markus Kuhn 11 * fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887 12 * precision CMOS clock update 13 * 1996-05-03 Ingo Molnar 14 * fixed time warps in do_[slow|fast]_gettimeoffset() 15 * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 16 * "A Kernel Model for Precision Timekeeping" by Dave Mills 17 * 1998-09-05 (Various) 18 * More robust do_fast_gettimeoffset() algorithm implemented 19 * (works with APM, Cyrix 6x86MX and Centaur C6), 20 * monotonic gettimeofday() with fast_get_timeoffset(), 21 * drift-proof precision TSC calibration on boot 22 * (C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D. 23 * Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>; 24 * ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>). 25 * 1998-12-16 Andrea Arcangeli 26 * Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy 27 * because was not accounting lost_ticks. 28 * 1998-12-24 Copyright (C) 1998 Andrea Arcangeli 29 * Fixed a xtime SMP race (we need the xtime_lock rw spinlock to 30 * serialize accesses to xtime/lost_ticks). 31 */ 32 33#include <linux/errno.h> 34#include <linux/sched.h> 35#include <linux/kernel.h> 36#include <linux/param.h> 37#include <linux/string.h> 38#include <linux/mm.h> 39#include <linux/interrupt.h> 40#include <linux/time.h> 41#include <linux/delay.h> 42#include <linux/init.h> 43#include <linux/smp.h> 44#include <linux/module.h> 45#include <linux/sysdev.h> 46#include <linux/bcd.h> 47#include <linux/efi.h> 48#include <linux/mca.h> 49 50#include <asm/io.h> 51#include <asm/smp.h> 52#include <asm/irq.h> 53#include <asm/msr.h> 54#include <asm/delay.h> 55#include <asm/mpspec.h> 56#include <asm/uaccess.h> 57#include <asm/processor.h> 58#include <asm/timer.h> 59#include <asm/time.h> 60 61#include "mach_time.h" 62 63#include <linux/timex.h> 64 65#include <asm/hpet.h> 66 67#include <asm/arch_hooks.h> 68 69#include "io_ports.h" 70 71#include <asm/i8259.h> 72 73#include "do_timer.h" 74 75unsigned int cpu_khz; /* Detected as we calibrate the TSC */ 76EXPORT_SYMBOL(cpu_khz); 77 78DEFINE_SPINLOCK(rtc_lock); 79EXPORT_SYMBOL(rtc_lock); 80 81/* 82 * This is a special lock that is owned by the CPU and holds the index 83 * register we are working with. It is required for NMI access to the 84 * CMOS/RTC registers. See include/asm-i386/mc146818rtc.h for details. 85 */ 86volatile unsigned long cmos_lock = 0; 87EXPORT_SYMBOL(cmos_lock); 88 89/* Routines for accessing the CMOS RAM/RTC. */ 90unsigned char rtc_cmos_read(unsigned char addr) 91{ 92 unsigned char val; 93 lock_cmos_prefix(addr); 94 outb_p(addr, RTC_PORT(0)); 95 val = inb_p(RTC_PORT(1)); 96 lock_cmos_suffix(addr); 97 return val; 98} 99EXPORT_SYMBOL(rtc_cmos_read); 100 101void rtc_cmos_write(unsigned char val, unsigned char addr) 102{ 103 lock_cmos_prefix(addr); 104 outb_p(addr, RTC_PORT(0)); 105 outb_p(val, RTC_PORT(1)); 106 lock_cmos_suffix(addr); 107} 108EXPORT_SYMBOL(rtc_cmos_write); 109 110static int set_rtc_mmss(unsigned long nowtime) 111{ 112 int retval; 113 unsigned long flags; 114 115 /* gets recalled with irq locally disabled */ 116 spin_lock_irqsave(&rtc_lock, flags); 117 retval = set_wallclock(nowtime); 118 spin_unlock_irqrestore(&rtc_lock, flags); 119 120 return retval; 121} 122 123 124int timer_ack; 125 126unsigned long profile_pc(struct pt_regs *regs) 127{ 128 unsigned long pc = instruction_pointer(regs); 129 130#ifdef CONFIG_SMP 131 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) && 132 in_lock_functions(pc)) { 133#ifdef CONFIG_FRAME_POINTER 134 return *(unsigned long *)(regs->ebp + 4); 135#else 136 unsigned long *sp = (unsigned long *)®s->esp; 137 138 /* Return address is either directly at stack pointer 139 or above a saved eflags. Eflags has bits 22-31 zero, 140 kernel addresses don't. */ 141 if (sp[0] >> 22) 142 return sp[0]; 143 if (sp[1] >> 22) 144 return sp[1]; 145#endif 146 } 147#endif 148 return pc; 149} 150EXPORT_SYMBOL(profile_pc); 151 152/* 153 * This is the same as the above, except we _also_ save the current 154 * Time Stamp Counter value at the time of the timer interrupt, so that 155 * we later on can estimate the time of day more exactly. 156 */ 157irqreturn_t timer_interrupt(int irq, void *dev_id) 158{ 159#ifdef CONFIG_X86_IO_APIC 160 if (timer_ack) { 161 /* 162 * Subtle, when I/O APICs are used we have to ack timer IRQ 163 * manually to reset the IRR bit for do_slow_gettimeoffset(). 164 * This will also deassert NMI lines for the watchdog if run 165 * on an 82489DX-based system. 166 */ 167 spin_lock(&i8259A_lock); 168 outb(0x0c, PIC_MASTER_OCW3); 169 /* Ack the IRQ; AEOI will end it automatically. */ 170 inb(PIC_MASTER_POLL); 171 spin_unlock(&i8259A_lock); 172 } 173#endif 174 175 do_timer_interrupt_hook(); 176 177 if (MCA_bus) { 178 /* The PS/2 uses level-triggered interrupts. You can't 179 turn them off, nor would you want to (any attempt to 180 enable edge-triggered interrupts usually gets intercepted by a 181 special hardware circuit). Hence we have to acknowledge 182 the timer interrupt. Through some incredibly stupid 183 design idea, the reset for IRQ 0 is done by setting the 184 high bit of the PPI port B (0x61). Note that some PS/2s, 185 notably the 55SX, work fine if this is removed. */ 186 187 u8 irq_v = inb_p( 0x61 ); /* read the current state */ 188 outb_p( irq_v|0x80, 0x61 ); /* reset the IRQ */ 189 } 190 191 return IRQ_HANDLED; 192} 193 194/* not static: needed by APM */ 195unsigned long read_persistent_clock(void) 196{ 197 unsigned long retval; 198 unsigned long flags; 199 200 spin_lock_irqsave(&rtc_lock, flags); 201 202 retval = get_wallclock(); 203 204 spin_unlock_irqrestore(&rtc_lock, flags); 205 206 return retval; 207} 208 209static void sync_cmos_clock(unsigned long dummy); 210 211static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0); 212int no_sync_cmos_clock; 213 214static void sync_cmos_clock(unsigned long dummy) 215{ 216 struct timeval now, next; 217 int fail = 1; 218 219 /* 220 * If we have an externally synchronized Linux clock, then update 221 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be 222 * called as close as possible to 500 ms before the new second starts. 223 * This code is run on a timer. If the clock is set, that timer 224 * may not expire at the correct time. Thus, we adjust... 225 */ 226 if (!ntp_synced()) 227 /* 228 * Not synced, exit, do not restart a timer (if one is 229 * running, let it run out). 230 */ 231 return; 232 233 do_gettimeofday(&now); 234 if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 && 235 now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2) 236 fail = set_rtc_mmss(now.tv_sec); 237 238 next.tv_usec = USEC_AFTER - now.tv_usec; 239 if (next.tv_usec <= 0) 240 next.tv_usec += USEC_PER_SEC; 241 242 if (!fail) 243 next.tv_sec = 659; 244 else 245 next.tv_sec = 0; 246 247 if (next.tv_usec >= USEC_PER_SEC) { 248 next.tv_sec++; 249 next.tv_usec -= USEC_PER_SEC; 250 } 251 mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next)); 252} 253 254void notify_arch_cmos_timer(void) 255{ 256 if (!no_sync_cmos_clock) 257 mod_timer(&sync_cmos_timer, jiffies + 1); 258} 259 260extern void (*late_time_init)(void); 261/* Duplicate of time_init() below, with hpet_enable part added */ 262void __init hpet_time_init(void) 263{ 264 if (!hpet_enable()) 265 setup_pit_timer(); 266 time_init_hook(); 267} 268 269/* 270 * This is called directly from init code; we must delay timer setup in the 271 * HPET case as we can't make the decision to turn on HPET this early in the 272 * boot process. 273 * 274 * The chosen time_init function will usually be hpet_time_init, above, but 275 * in the case of virtual hardware, an alternative function may be substituted. 276 */ 277void __init time_init(void) 278{ 279 tsc_init(); 280 late_time_init = choose_time_init(); 281} 282