#ifndef __DTYPE_H__
#define __DTYPE_H__

#define	ACTIVATED	1<<0
#define	PERIODIC	1<<1

#define	OK	0
#define ERROR	-1
#define	TRUE	(1==1)
#define	FALSE	(0==1)
#define	N		0
#define BLOCKHEAD_SIGNATURE 0x0000F00D
#define NAME_MAXLEN	20
#define	NULL	0
#define	MAX_PRIO	32
#define MAX_TASK_NUM	256
#define	TASK_STACK_SIZE	0x1000


/*general device commands*/
#define	DEVICE_SET_RESUME		0x01	//resume device
#define	DEVICE_SET_SUSPEND		0x02	//suspend device

//flags[0:3]: device mode
//device mode
#define	DEVICE_RDONLY				1<<0
#define	DEVICE_WRONLY				1<<1
#define DEVICE_RDWR					DEVICE_RDONLY	|	DEVICE_WRONLY
#define	DEVICE_STANDALONERDLONLY	1<<2

//flags[4:7]:active or suspend
//active or suspend
#define	DEVICE_ACTIVATED			1<<4
#define	DEVICE_SUSPENDED			1<<5


//flags[8:11]:Tx and Rx flag
//TX_RX mode
#define	DEVICE_RX_INT_MODE			1<<8	//INT mode on Rx
#define	DEVICE_RX_DMA_MODE			1<<9	//DMA mode on Rx
#define	DEVICE_TX_INT_MODE			1<<10	//INT mode on Tx
#define	DEVICE_TX_DMA_MODE			1<<11	//DMA mode on Tx

//flags[12:15]:device Open flag
//OPEN flag
#define	DEVICE_OFLAG_RDONLY			1<<12
#define DEVICE_OFLAG_WRONLY			1<<13
#define DEVICE_OFLAG_RDWR			DEVICE_OFLAG_RDONLY | DEVICE_OFLAG_WRONLY
#define DEVICE_OFLAG_CLOSE			1<<14
#define DEVICE_OFLAG_OPEN			1<<15


typedef unsigned int   u32int;
typedef          int   s32int;
typedef unsigned short u16int;
typedef          short s16int;
typedef unsigned char  u8int;
typedef          char  s8int;
//typedef	void		device_t;




/**********************************************************
for	node&list structures
***********************************************************/
struct	node{
	struct	node		*next;
	struct	node		*prev;
};
typedef	struct	node	node_t;

struct	list{
	node_t	head;
	node_t	tail;
};
typedef	struct	list	list_t;



//I/O device structure
typedef	enum {
	Char_Device = 0,	//character device
	Block_Device,		//block	device
	NetIf_Device,		//net interface
	Sound_Device,		//Sound device
	Unknown_Device		//unkenown device
} device_type;


/*********************************************************
for device
*********************************************************/
struct	device{
	node_t			node;				//the node of timer list
	char			name[NAME_MAXLEN];
	device_type		type;
	
	//4bits: oflag, 4bits:TX_RX_flag, 4bits: active or suspend, 4bits: mode
	u16int			flags;
	
	
	
	
	
	//device interface
	s8int	(*init)(device_t* dev);
	s8int   (*close)(device_t* dev);
	s8int	(*open)		(device_t*	dev,	u16int	oflag);
	u32int	(*read)		(device_t*	dev,	u32int	pos,	u32int	size,	void*	buffer);
	u32int	(*write)	(device_t*	dev,	u32int	pos,	u32int	size,	const	void*	buffer);
	s8int	(*ctrl)		(device_t*	dev,	u8int	cmd,	void	*args);
	
	//device callback
	s8int	(*rx)(device_t*	dev,	u32int	size);
	s8int	(*tx)(device_t*	dev,	void*	buffer);	
	
};
typedef	struct	device	device_t;




/**********************************************************
	task definition
**********************************************************/
/*state of task*/
typedef	enum{
	READY=0,
	RUNNING,
	BLOCK,
	CLOSE
}	TASK_STATE;

/**********************************************************
for	Timer	Structure
***********************************************************/
struct	timer{
	node_t	node;
	char	name[NAME_MAXLEN];
	u8int	flag;	/* 0 bit:actived, 1 bit:type*/
	void	(*timeout_func)(void*	parameter);
	void	*parameter;
	u32int	init_tick;	/*timer timeout	tick.*/
	u32int	timeout_tick;	/*timeout	tick.*/
};
typedef	struct	timer	timer_t;


/*structure of task*/
struct	task	{
	node_t		node;
	
	/*stack point and entry*/
	void*		sp;
	void*		entry;
	void*		parameter;
	void*		stack_addr;
	u16int		stack_size;
	
	u8int		priority;
	
	u32int		init_tick;
	u32int		remaining_tick;
	
	u32int		task_id;
	TASK_STATE	state;
	char		name[NAME_MAXLEN];
	
	timer_t*	timer;
};
typedef	struct	task	task_t;

typedef	enum{
	WAITING_NO = 0,
	WAITING,
	WAITING_FOREVER
} SEM_WAITING_TYPE;

typedef	enum{
	FIFO = 0,
	PRIO
} SEM_FLAG_TYPE;

/**********************************************************
for mailbox 
***********************************************************/
struct	mailbox	{
	char	name[NAME_MAXLEN];
	u32int	*msg_pool;
	SEM_FLAG_TYPE	flag;
	u16int	size;
	u16int	entry;
	u16int	input_offset;
	u16int	output_offset;
	list_t	waiting_list;
};
typedef	struct	mailbox	mailbox_t;

/*********************************************************
for semaphore 
**********************************************************/
/*
 * semaphore
 *
 */
struct	semaphore{
	char	name[NAME_MAXLEN];
	u16int	value;
	SEM_FLAG_TYPE	flag;
	list_t	waiting_list;
};
typedef	struct	semaphore sem_t;


/**********************************************************
for schedule 
***********************************************************/
typedef enum{
	SCHED_TIME_EXPIRE=0,
	SCHED_TASK_REQUEST
} SCHED_TYPE;



typedef	enum{
	SET_TIME=0,
	GET_TIME,
	SET_ONESHOT,
	SET_PERIODIC
}	TIMER_CMD_TYPE;






/**********************************************************
for Memory Block Structure
***********************************************************/
typedef struct blockHead{
	u32int	signature;
	u8int	allocated;
	u32int	size;
	struct	blockHead *next;
	struct	blockHead *prev;
}blockHead_t;





		
/**********************************************************
for descript table
***********************************************************/		
// This structure contains the value of one GDT entry.
// We use the attribute 'packed' to tell GCC not to change
// any of the alignment in the structure.
struct gdt_entry_struct
{
    u16int limit_low;           // The lower 16 bits of the limit.
    u16int base_low;            // The lower 16 bits of the base.
    u8int  base_middle;         // The next 8 bits of the base.
    u8int  access;              // Access flags, determine what ring this segment can be used in.
    u8int  granularity;
    u8int  base_high;           // The last 8 bits of the base.
} __attribute__((packed));

typedef struct gdt_entry_struct gdt_entry_t;

// This struct describes a GDT pointer. It points to the start of
// our array of GDT entries, and is in the format required by the
// lgdt instruction.
struct gdt_ptr_struct
{
    u16int limit;               // The upper 16 bits of all selector limits.
    u32int base;                // The address of the first gdt_entry_t struct.
} __attribute__((packed));

typedef struct gdt_ptr_struct gdt_ptr_t;

// A struct describing an interrupt gate.
struct idt_entry_struct
{
    u16int base_lo;             // The lower 16 bits of the address to jump to when this interrupt fires.
    u16int sel;                 // Kernel segment selector.
    u8int  always0;             // This must always be zero.
    u8int  flags;               // More flags. See documentation.
    u16int base_hi;             // The upper 16 bits of the address to jump to.
} __attribute__((packed));

typedef struct idt_entry_struct idt_entry_t;

// A struct describing a pointer to an array of interrupt handlers.
// This is in a format suitable for giving to 'lidt'.
struct idt_ptr_struct
{
    u16int limit;
    u32int base;                // The address of the first element in our idt_entry_t array.
} __attribute__((packed));

typedef struct idt_ptr_struct idt_ptr_t;

		
/************************************************************************************/
/************************************************************************
for regs
************************************************************************/
/* This defines what the stack looks like after an ISR was running */
struct regs
{
    unsigned int gs, fs, es, ds;
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
    unsigned int int_no, err_code;
    unsigned int eip, cs, eflags, useresp, ss;    
};

//;typedef struct registers
//;{
//;   unsigned int ds;                  // Data segment selector
//;   unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
//;   unsigned int int_no, err_code;    // Interrupt number and error code (if applicable)
//;   unsigned int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
//;} __attribute__ ((packed)) registers_t;

typedef struct regs registers_t;

/************************************************************************************/



#endif 
