| Current File : //usr/share/src/uts/i86pc/sys/clock.h |
/*
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _SYS_CLOCK_H
#define _SYS_CLOCK_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _KERNEL
#ifndef _ASM
#include <sys/psw.h>
#include <sys/time.h>
#include <sys/processor.h>
#if defined(__GNUC__) && defined(_ASM_INLINES)
#include <asm/clock.h>
#endif
#include <sys/machclock.h>
extern time_t ggmtl(void);
extern void sgmtl(time_t);
extern void rtcsync(void);
extern void hres_tick(void);
extern void (*hrtime_tick)(void);
#ifndef __xpv
extern void tsc_hrtimeinit(uint64_t cpu_freq_hz);
extern void tsc_sync_master(processorid_t);
extern void tsc_sync_slave(void);
#endif
/*
* Careful: this can always return zero on some systems. Use the system hrtime
* routines if you want a meaningful time.
*/
extern hrtime_t tsc_read(void);
extern hrtime_t __rdtsc_insn(void);
extern int tsc_gethrtime_enable;
extern int tscp_enable;
#define ADJ_SHIFT 4 /* used in get_hrestime */
#define NSEC_SHIFT 5
/* Hack value just to allow clock to be kicked */
#define NSEC_PER_CLOCK_TICK NANOSEC / 100
#define YRBASE 00 /* 1900 - what year 0 in chip represents */
#endif /* !_ASM */
#define CBE_HIGH_PIL 14
#define CBE_LOCK_PIL LOCK_LEVEL
#define CBE_LOW_PIL 2
/*
* CLOCK_LOCK() sets the bottom 32 bit of the hrt->hres_lock. The other 32
* bits are used as the counter.
*
* NOTE: It is assumed that lock_set_spl() only uses the bottom 32 bits the
* lock.
*
* This lock is acquired around hrt members including hrestime and
* timedelta.
*
* CLOCK_UNLOCK() increments the counter (top 32bits of hres_lock) and
* clears the lock. This way gethrtime() can figure out if the value in the
* lock got changed or not.
*/
#define HRES_LOCK_OFFSET 0 /* byte 0 has the lock bit(bit 0 in the byte) */
#define CLOCK_LOCK(oldsplp) \
lock_set_spl((lock_t *)&hrt->hres_lock + HRES_LOCK_OFFSET, \
ipltospl(XC_HI_PIL), oldsplp)
#define CLOCK_UNLOCK(spl) \
{ \
uint64_t val = ((hrt->hres_lock >> 32) + 1) << 32; \
val = atomic_swap_64(&hrt->hres_lock, val); \
if (LOCK_HAS_WAITERS(val)) \
pv_cpu_release(); \
splx(spl); \
LOCKSTAT_RECORD0(LS_CLOCK_UNLOCK_RELEASE, \
(lock_t *)&hrt->hres_lock + HRES_LOCK_OFFSET); \
}
/*
* You want CLOCK_LOCK and CLOCK_UNLOCK above.
* These versions of the above macros are for use only by the clock interrupt
* which is already at CY_LOCK_LEVEL.
*/
#define CLOCK_SPIN_LOCK() hres_spin_lock()
#define CLOCK_SPIN_UNLOCK() hres_spin_unlock()
#endif /* KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_CLOCK_H */