static char rcsid[] = "$Header: clock.c,v 820.1 86/12/04 19:52:47 root Exp $";
static char sccsid[]="%W% %Y% %Q% %G%";

/************************************************************************
*									*
*				Copyright 1984				*
*			VALID LOGIC SYSTEMS INCORPORATED		*
*									*
*	This listing contains confidential proprietary information	*
*	which is not to be disclosed to unauthorized persons without	*
*	written consent of an officer of Valid Logic Systems 		*
*	Incorporated.							*
*									*
*	The copyright notice appearing above is included to provide	*
*	statutory protection in the event of unauthorized or 		*
*	unintentional public disclosure.				*
*									*
************************************************************************/

/*	clock.c	4.1	83/02/10	*/

#include "../h/param.h"
#include "../h/time.h"
#include "../h/kernel.h"
#include "../s32/vectors.h"
#include "../s32/cpu.h"
#ifdef WHITE
#include "../white/config.h"
#include "../white/via.h"
#else WHITE
#include "../s32/clock.h"
#endif WHITE

/*
 * Machine-dependent clock routines.
 *
 * Startrtclock restarts the real-time clock, which provides
 * hardclock interrupts to kern_clock.c.
 *
 * Inittodr initializes the time of day hardware which provides
 * date functions.  Its primary function is to use some file
 * system information in case the hardare clock lost state.
 *
 * Resettodr restores the time of day hardware after a time change.
 */

/*
 * Start the real-time clock.
 */
startrtclock()
{
	int s = spl7();
	extern int clkint();

	IRQ6vector = clkint;
#ifdef WHITE
	VIAADDR->v_acr = ACR_T1FR|ACR_T2OS;
	VIAADDR->v_ier = I_CLR|I_T2|I_CB1|I_CB2|I_SR|I_CA1|I_CA2;
	VIAADDR->v_t1ll = CLKCOUNT;
	VIAADDR->v_t1lh = CLKCOUNT >> 8;
	VIAADDR->v_t1ch = CLKCOUNT >> 8;
	VIAADDR->v_ier = I_SET|I_T1;
#else WHITE
	/*
	 * NOTE!  In the words of the prophet INTEL,
	 * "The 8253 MUST be COMPLETELY initialized!"
	 *
	 * To fail to do so will result
	 * in "undefined outputs"...perhaps a multitude
	 * of spurious interrupts, for starters,
	 * pun unintended.
	 */
	clkparam = C_RATE / hz - 30;	/* for locore.s */

	/*
	 * PIT<0>:
	 * This timer drives the HZ timer
	 * for the kernel's scheduler.
	 */
	CLKADDR->c_mode = C_MODE0	/* Interrupt on terminal count     */
			| C_SEL0	/* Counter #0			   */
			| C_WORD;	/* Read/write both bytes (0 first) */
#ifdef M68020
	/*
	 * Can't access the clock chip at any less than 1 micro second
	 * interval.  This is violated with the cache on.
	 */
	flushWriteQueue();
#endif M68020
	CLKADDR->c_c0 = clkparam;	/* Starting value for downcounter  */
#ifdef M68020
	/*
	 * Can't access the clock chip at any less than 1 micro second
	 * interval.  This is violated with the cache on.
	 */
	flushWriteQueue();
#endif M68020
	CLKADDR->c_c0 = clkparam >> NBBY;/* ...also starts ctr counting	   */

	/*
	 * PIT<1>:
	 */
#ifdef M68020
	/*
	 * Can't access the clock chip at any less than 1 micro second
	 * interval.  This is violated with the cache on.
	 */
	flushWriteQueue();
#endif M68020
	CLKADDR->c_mode = C_MODE0	/* Interrupt on terminal count     */
			| C_SEL1	/* Counter #1			   */
			| C_WORD;	/* Read/write both bytes (0 first) */
#ifdef	DontDoThis
	CLKADDR->c_c0 = clkparam;	/* Starting value for downcounter  */
	CLKADDR->c_c1 = clkparam >> NBBY;/* ...also starts ctr counting	   */
#endif	DontDoThis

#ifndef	M68020
	/*
	 * PIT<2>:
	 */
#ifdef M68020
	/*
	 * Can't access the clock chip at any less than 1 micro second
	 * interval.  This is violated with the cache on.
	 */
	flushWriteQueue();
#endif M68020
	CLKADDR->c_mode = C_MODE0	/* Interrupt on terminal count     */
			| C_SEL2	/* Counter #2			   */
			| C_WORD;	/* Read/write both bytes (0 first) */
#ifdef	DontDoThis
	CLKADDR->c_c0 = clkparam;	/* Starting value for downcounter  */
	CLKADDR->c_c2 = clkparam >> NBBY;/* ...also starts ctr counting	   */
#endif	DontDoThis
#endif	M68020

#ifndef s32	/* KGCLOCK */
#ifndef	M68020
	V_STATUS |= V_ENINT;		/* enable interrupts */
#else	M68020
	orStatusReg(V_ENINT);		/* Enable interrupts, including clock */
#endif	M68020
#endif
#endif WHITE
	splx(s);
}

/*
 * Initialze the time of day register, based on the time base which is, e.g.
 * from a filesystem.  Base provides the time to within six months,
 * and the time of year clock provides the rest.
 */
inittodr(base)
	time_t base;
{
	time.tv_sec = base;
}

/*
 * Reset the TODR based on the time value; used when the TODR
 * has a preposterous value and also when the time is reset
 * by the stime system call.  Also called when the TODR goes past
 * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
 * to wrap the TODR around.
 */
resettodr()
{
}
