/*
 * time.h
 *
 * Copyright 2002, Minoru Murashima. All rights reserved.
 * Distributed under the terms of the BSD License.
 *
 * time.c用ヘッダーファイル
 */


#ifndef time_h
#define time_h


#include<lib.h>
#include<sys/time.h>


#ifndef ASM_FILE


enum{
	TIMER_MAX = 2,		/* タイマー最大数 */
	ITIMER_MAX = 2,		/* itimer最大数 */

	PIT_HZ=1193181,		/* 8254インターバルタイマーのヘルツ数 */

	/* 8254 interval timer IO register */
	PIT_CNR0=0x40,		/* counter0 register */
	PIT_CTR= 0x43,		/* control register */

	/* MC146818 CMOS RAM and real-time clock IO register */
	CMOS_ADR= 0x70,		/* address register */
	CMOS_DTR= 0x71,		/* data register */
	CMOS_SCD= 0x0,		/* second */
	CMOS_MNT= 0x2,		/* minute */
	CMOS_HOR= 0x4,		/* hour */
	CMOS_DAY= 0x7,		/* day */
	CMOS_MTH= 0x8,		/* month */
	CMOS_YER= 0x9,		/* year */
	CMOS_STRA=0xa,		/* status register A */
	CMOS_STRB=0xb,		/* status register B */
	CMOS_STRC=0xc,		/* status register C */

	NMI_ENABLE=0x80,	/* NMI interrupt enable,CMOS address registerに書き込むとき一緒に設定する。 */
};


typedef struct TIMER{
	struct TIMER *next;
	struct TIMER *prev;
	uint init;						/* 初期タイマー値 */
	uint count;						/* 残り時間 */
	int flag;
	struct TIMER *link;				/* 接続元リンク */
	void *proc;						/* プロセス */
	void (*handle)(struct TIMER*);	/* タイマーハンドラー */
}TIMER;

typedef struct{
	int64 init;			/* 初期タイマー値（rdtsc値） */
	int64 cur;			/* 残り時間（rdtsc値） */
}ITIMER;

enum{
	/* itimer区分 */
	ITIME_SYS = 0,		/* itimer配列システム時間 */
	ITIME_PRC = 1,		/* itimer配列ユーザー時間 */
};

extern int clock_1micro;
extern int clock_1m;
extern int timer_num;


/*
 * CMOS read and write
 */
extern inline uchar read_cmos(int addr)
{
	outb(CMOS_ADR,addr|NMI_ENABLE);
	return inb(CMOS_DTR);
}

extern inline void write_cmos(int addr,uchar value)
{
	outb(CMOS_ADR,addr|NMI_ENABLE);
	outb(CMOS_DTR,value);
}

extern int count_cpu_clock();
extern int setWake(uint);
extern void delWakeTimer(TIMER*);
extern void initTimer(TIMER*, ITIMER*);
extern void releaseTimer(TIMER*);
extern void init_time();
extern void calcUserTime();
extern void calcSysTime();
extern void doItimer(ITIMER*,uint64,int);
extern void gettimeofday(struct timeval*);
extern int sys_time();
extern int sys_sleep();
extern void sys_wake(void*);
extern int sys_alarm();
extern int sys_settime(uint);
extern int sys_gettimeofday();
extern int sys_getitimer(int which, struct itimerval *value);
extern int sys_setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);


#endif


#endif
