#include <mach/mach_types.h>
#include <kern/clock.h>
#include <kern/thread.h>
#include <kern/processor.h>
#include <kern/macro_help.h>
#include <kern/spl.h>
#include <kern/etimer.h>
#include <kern/pms.h>
#include <machine/commpage.h>
#include <machine/machine_routines.h>
#include <sys/kdebug.h>
#ifdef __ppc__
#include <ppc/exception.h>
#else
#include <i386/cpu_data.h>
#endif
#include <sys/kdebug.h>
uint32_t rtclock_tick_interval;
clock_timer_func_t rtclock_timer_expire;
#ifdef __ppc__
# define PER_PROC_INFO struct per_proc_info
# define GET_PER_PROC_INFO() getPerProc()
#else
# define PER_PROC_INFO cpu_data_t
# define GET_PER_PROC_INFO() current_cpu_datap()
#endif
void etimer_intr(int inuser, uint64_t iaddr) {
uint64_t abstime;
rtclock_timer_t *mytimer;
PER_PROC_INFO *pp;
pp = GET_PER_PROC_INFO();
mytimer = &pp->rtclock_timer;
abstime = mach_absolute_time();
if (pp->pms.pmsPop <= abstime) {
KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 3) | DBG_FUNC_START, 0, 0, 0, 0, 0);
pmsStep(1);
KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 3) | DBG_FUNC_END, 0, 0, 0, 0, 0);
abstime = mach_absolute_time();
}
if (pp->rtclock_intr_deadline <= abstime) {
KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 4) | DBG_FUNC_START, (int)rtclock_tick_interval, 0, 0, 0, 0);
clock_deadline_for_periodic_event(rtclock_tick_interval,
abstime,
&pp->rtclock_intr_deadline);
KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 4) | DBG_FUNC_END, 0, 0, 0, 0, 0);
#if STAT_TIME
hertz_tick(NSEC_PER_HZ, inuser, iaddr);
#else
hertz_tick(inuser, iaddr);
#endif
abstime = mach_absolute_time();
}
if (mytimer->deadline <= abstime) {
mytimer->has_expired = TRUE;
mytimer->deadline = EndOfAllTime;
(*rtclock_timer_expire)(abstime);
mytimer->has_expired = FALSE;
}
pp->rtcPop = EndOfAllTime;
etimer_resync_deadlines();
}
void etimer_set_deadline(uint64_t deadline)
{
rtclock_timer_t *mytimer;
spl_t s;
PER_PROC_INFO *pp;
s = splclock();
pp = GET_PER_PROC_INFO();
mytimer = &pp->rtclock_timer;
mytimer->deadline = deadline;
etimer_resync_deadlines();
splx(s);
}
void
etimer_resync_deadlines(void)
{
uint64_t deadline;
rtclock_timer_t *mytimer;
spl_t s = splclock();
PER_PROC_INFO *pp;
pp = GET_PER_PROC_INFO();
deadline = 0;
if (pp->rtclock_intr_deadline > 0)
deadline = pp->rtclock_intr_deadline;
mytimer = &pp->rtclock_timer;
if ((!mytimer->has_expired) && (mytimer->deadline > 0) && (mytimer->deadline < deadline))
deadline = mytimer->deadline;
if ((pp->pms.pmsPop > 0) && (pp->pms.pmsPop < deadline))
deadline = pp->pms.pmsPop;
#ifdef __ppc__
#endif
if ((deadline > 0) && (deadline < pp->rtcPop)) {
int decr;
pp->rtcPop = deadline;
decr = setPop(deadline);
KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 1) | DBG_FUNC_NONE, decr, 2, 0, 0, 0);
}
splx(s);
}