/* * Initialize the TOD clock and the CPU timer of * the boot cpu. */ void __init time_init(void) { struct timespec ts; unsigned long flags; cycle_t now; /* Reset time synchronization interfaces. */ etr_reset(); stp_reset(); /* request the clock comparator external interrupt */ if (register_early_external_interrupt(0x1004, clock_comparator_interrupt, &ext_int_info_cc) != 0) panic("Couldn't request external interrupt 0x1004"); /* request the timing alert external interrupt */ if (register_early_external_interrupt(0x1406, timing_alert_interrupt, &ext_int_etr_cc) != 0) panic("Couldn't request external interrupt 0x1406"); if (clocksource_register(&clocksource_tod) != 0) panic("Could not register TOD clock source"); /* * The TOD clock is an accurate clock. The xtime should be * initialized in a way that the difference between TOD and * xtime is reasonably small. Too bad that timekeeping_init * sets xtime.tv_nsec to zero. In addition the clock source * change from the jiffies clock source to the TOD clock * source add another error of up to 1/HZ second. The same * function sets wall_to_monotonic to a value that is too * small for /proc/uptime to be accurate. * Reset xtime and wall_to_monotonic to sane values. */ write_seqlock_irqsave(&xtime_lock, flags); now = get_clock(); tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime); clocksource_tod.cycle_last = now; clocksource_tod.raw_time = xtime; tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts); set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec); write_sequnlock_irqrestore(&xtime_lock, flags); /* Enable TOD clock interrupts on the boot cpu. */ init_cpu_timer(); /* Enable cpu timer interrupts on the boot cpu. */ vtime_init(); }
unsigned long read_persistent_clock(void) { struct timespec ts; tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, &ts); return ts.tv_sec; }
int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, int area, debug_entry_t * entry, char *out_buf) { struct timespec time_spec; unsigned long long time; char *except_str; unsigned long caller; int rc = 0; unsigned int level; level = entry->id.fields.level; time = entry->id.stck; /* adjust todclock to 1970 */ time -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); tod_to_timeval(time, &time_spec); if (entry->id.fields.exception) except_str = "*"; else except_str = "-"; caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN; rc += sprintf(out_buf, "%02i %011lu:%06lu %1u %1s %02i %p ", area, time_spec.tv_sec, time_spec.tv_nsec / 1000, level, except_str, entry->id.fields.cpuid, (void *) caller); return rc; }
/* * Initialize the TOD clock and the CPU timer of * the boot cpu. */ void __init time_init(void) { u64 init_timer_cc; init_timer_cc = reset_tod_clock(); jiffies_timer_cc = init_timer_cc - jiffies_64 * CLK_TICKS_PER_JIFFY; /* set xtime */ tod_to_timeval(init_timer_cc - TOD_UNIX_EPOCH, &xtime); set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); /* request the clock comparator external interrupt */ if (register_early_external_interrupt(0x1004, clock_comparator_interrupt, &ext_int_info_cc) != 0) panic("Couldn't request external interrupt 0x1004"); if (clocksource_register(&clocksource_tod) != 0) panic("Could not register TOD clock source"); /* request the timing alert external interrupt */ if (register_early_external_interrupt(0x1406, timing_alert_interrupt, &ext_int_etr_cc) != 0) panic("Couldn't request external interrupt 0x1406"); /* Enable TOD clock interrupts on the boot cpu. */ init_cpu_timer(); #ifdef CONFIG_VIRT_TIMER vtime_init(); #endif }
/* * Initialize the TOD clock and the CPU timer of * the boot cpu. */ void __init time_init(void) { sched_clock_base_cc = reset_tod_clock(); /* set xtime */ tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &xtime); set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); /* request the clock comparator external interrupt */ if (register_early_external_interrupt(0x1004, clock_comparator_interrupt, &ext_int_info_cc) != 0) panic("Couldn't request external interrupt 0x1004"); if (clocksource_register(&clocksource_tod) != 0) panic("Could not register TOD clock source"); /* request the timing alert external interrupt */ if (register_early_external_interrupt(0x1406, timing_alert_interrupt, &ext_int_etr_cc) != 0) panic("Couldn't request external interrupt 0x1406"); /* Enable TOD clock interrupts on the boot cpu. */ init_cpu_timer(); /* Enable cpu timer interrupts on the boot cpu. */ vtime_init(); }
void read_boot_clock64(struct timespec64 *ts) { __u64 clock; clock = sched_clock_base_cc - initial_leap_seconds; tod_to_timeval(clock - TOD_UNIX_EPOCH, ts); }
void read_persistent_clock64(struct timespec64 *ts) { __u64 clock; clock = get_tod_clock() - initial_leap_seconds; tod_to_timeval(clock - TOD_UNIX_EPOCH, ts); }
void read_boot_clock(struct timespec *ts) { tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, ts); }
void read_persistent_clock(struct timespec *ts) { tod_to_timeval(get_tod_clock() - TOD_UNIX_EPOCH, ts); }