/*
 * interrupt.c
 *
 * Copyright 2002, Minoru Murashima. All rights reserved.
 * Distributed under the terms of the BSD License.
 */


#include<lib.h>
#include<proc.h>
#include<segment.h>
#include<mp.h>
#include<fs.h>
#include<time.h>
#include<mm.h>
#include<device.h>
#include<signal.h>
#include<reboot.h>
#include<net/net.h>
#include<setup.h>
#include<console.h>
#include<test.h>
#include<interrupt.h>


enum{IDT_ENTRY=256};		/* Interrupt descriptorエントリー数 */


DESCRIPTOR idt[IDT_ENTRY];		/* IDT */
DTR idtr={IDT_ENTRY*8-1,idt};	/* IDT Reg */

/* System calls entry table. */
SYSCALL syscall_table[SYS_ENTRYS];


static int temp()
{
	return 0;
}


/*
 * 割り込みハンドラテーブル
 * returns : task switch on 1,off 0
 */
int (*irq_entry[IRQ_ENTRY])()={
	temp,temp,temp,temp,temp,temp,temp,temp,temp,temp,temp,temp,temp,temp,temp,temp,temp
};

/*
 * ハード割り込み用ＥＯＩ関数
 * parameters : IRQ number
 */
void (*irq_eoi)(uchar);

/*
 * Release hard interrupt mask
 * parameters : IRQ number
 */
void (*release_irq_mask)(uchar);

/*
 * Set hard interrupt mask
 * parameters : IRQ number
 */
void (*set_irq_mask)(uchar);


/*
 * IDTを設定する
 * parameters : IDT number,Hnadler address,Gate flag(IDT_INTR or IDT_TRAP)
 */
void set_idt(int num,void *func,int flag)
{
	idt[num].low=((uint)func&0xffff)|(KERNEL_CODE_DES<<16);
	idt[num].high=0x8000|((uint)func&0xffff0000)|flag;
}


/*
 * Set call gate discriptor
 * parameters : Value of discritor,Offset,Parameter count
 */
void set_gate(int des,void *addr,uchar para_num)
{
	gdt[des/8].low=((uint)addr&0xffff)|(KERNEL_CODE_DES<<16);
	gdt[des/8].high=((uint)addr&0xffff0000)|0xec00|para_num;
}


/*
 * Init system call
 */
int init_syscall()
{
	syscall_table[SYS_OPEN]			= sys_open;
	syscall_table[SYS_READ]			= sys_read;
	syscall_table[SYS_WRITE]		= sys_write;
	syscall_table[SYS_CLOSE]		= sys_close;
	syscall_table[SYS_LSEEK]		= sys_lseek;
	syscall_table[SYS_MKDIR]		= sys_mkdir;
	syscall_table[SYS_CREAT]		= sys_creat;
	syscall_table[SYS_RENAME]		= sys_rename;
	syscall_table[SYS_UNLINK]		= sys_unlink;
	syscall_table[SYS_RMDIR]		= sys_rmdir;
	syscall_table[SYS_OPENDIR]		= sys_opendir;
	syscall_table[SYS_READDIR]		= sys_readdir;
	syscall_table[SYS_REWINDDIR]	= sys_rewinddir;
	syscall_table[SYS_CHDIR]		= sys_chdir;
	syscall_table[SYS_FCHDIR]		= sys_fchdir;
	syscall_table[SYS_GETCWD]		= sys_getcwd;
	syscall_table[SYS_STAT]			= sys_stat;
	syscall_table[SYS_LOCK]			= sys_lock;
	syscall_table[SYS_MOUNT]		= sys_mount;
	syscall_table[SYS_UMOUNT]		= sys_umount;
	syscall_table[SYS_FORK]			= sys_fork;
	syscall_table[SYS_EXEC]			= sys_exec;
	syscall_table[SYS_EXIT]			= sys_exit;
	syscall_table[SYS_SLEEP]		= sys_sleep;
	syscall_table[SYS_ALARM]		= sys_alarm;
	syscall_table[SYS_TIME]			= sys_time;
	syscall_table[SYS_GETTIMEOFDAY]	= sys_gettimeofday;
	syscall_table[SYS_SYNC]			= sys_sync;
	syscall_table[SYS_WAIT]			= sys_wait;
	syscall_table[SYS_GETPID]		= sys_getpid;
	syscall_table[SYS_GETGID]		= sys_getgid;
	syscall_table[SYS_GETPGID]		= sys_getpgid;
	syscall_table[SYS_GETPPID]		= sys_getppid;
	syscall_table[SYS_GETUID]		= sys_getuid;
	syscall_table[SYS_GETSID]		= sys_getsid;
	syscall_table[SYS_SETGID]		= sys_setgid;
	syscall_table[SYS_SETPGID]		= sys_setpgid;
	syscall_table[SYS_SETUID]		= sys_setuid;
	syscall_table[SYS_SETSID]		= sys_setsid;
	syscall_table[SYS_TIMES]		= sys_times;
	syscall_table[SYS_SIGACTION]	= sys_sigaction;
	syscall_table[SYS_SIGPROCMASK]	= sys_sigprocmask;
	syscall_table[SYS_KILL]			= sys_kill;
	syscall_table[SYS_SIGPENDING]	= sys_sigpending;
	syscall_table[SYS_SIGSUSPEND]	= sys_sigsuspend;
	syscall_table[SYS_BRK]			= sys_brk;
	syscall_table[SYS_REBOOT]		= sys_reboot;
	syscall_table[SYS_FCNTL]		= sys_fcntl;
	syscall_table[SYS_CHATTR]		= sys_chattr;
	syscall_table[SYS_FCHATTR]		= sys_fchattr;
	syscall_table[SYS_IOCTL]		= sys_ioctl;
	syscall_table[SYS_LINK]			= sys_link;
	syscall_table[SYS_SYMLINK]		= sys_symlink;
	syscall_table[SYS_READLINK]		= sys_readlink;
	syscall_table[SYS_SELECT]		= sys_select;
	syscall_table[SYS_POLL]			= sys_poll;
	syscall_table[SYS_GETFSSTAT]	= sys_getstatfs;
	syscall_table[SYS_STATFS]		= sys_statfs;
	syscall_table[SYS_UNAME]		= sys_uname;
	syscall_table[SYS_TTYNAME]		= sys_ttyname;
	syscall_table[SYS_SETTIME]		= sys_settime;
	syscall_table[SYS_SOCKET]		= sys_socket;
	syscall_table[SYS_SEND]			= sys_send;
	syscall_table[SYS_RECV]			= sys_recv;
	syscall_table[SYS_CONNECT]		= sys_connect;
	syscall_table[SYS_SHUTDOWN]		= sys_shutdown;
	syscall_table[SYS_BIND]			= sys_bind;
	syscall_table[SYS_LISTEN]		= sys_listen;
	syscall_table[SYS_ACCEPT]		= sys_accept;
	syscall_table[SYS_GETSOCKNAME]	= sys_getsockname;
	syscall_table[SYS_GETPEERNAME]	= sys_getpeername;
	syscall_table[SYS_GETSOCKOPT]	= sys_getsockopt;
	syscall_table[SYS_SETSOCKOPT]	= sys_setsockopt;
	syscall_table[SYS_SENDMSG]		= sys_sendmsg;
	syscall_table[SYS_RECVMSG]		= sys_recvmsg;
	syscall_table[SYS_GETITIMER]	= sys_getitimer;
	syscall_table[SYS_SETITIMER]	= sys_setitimer;
/*************************************************/
	syscall_table[SYS_TEST]			= test_fs;
/*************************************************/

	set_gate(SYSCALL0_SEG,syscall0,1);
	set_gate(SYSCALL1_SEG,syscall1,2);
	set_gate(SYSCALL2_SEG,syscall2,3);
	set_gate(SYSCALL3_SEG,syscall3,4);
	set_gate(SYSCALL4_SEG,syscall4,5);
	set_gate(SYSCALL5_SEG,syscall5,6);
	set_gate(SYSCALL6_SEG,syscall6,7);

	return 0;
}
