
#ifndef _FL_KER_INCLUDED /* { */
#define _FL_KER_INCLUDED 1

/* FactoryLink Kernel Version Macro */
#ifdef FLKVERSION
#undef FLKVERSION
#endif
#define FLKVERSION (0x0700)

/* Bit masks for TYPE.t_stat field */

                                        /* storage type: */
#define T_STAT_FIXED            0x0000  /*  fixed, even size */
#define T_STAT_DIGITAL          0x0001  /*  t_ksiz = 0, t_usiz = 2 */
#define T_STAT_MESSAGE          0x0002  /*  variable size */
                                        /* access type: */
#define	T_STAT_MAILBOX		0x0003	/* mailbox */
#define T_STAT_RANDOM           0x0000  /*  random */
#define T_STAT_QUEUE            0x0010  /*  FIFO (implemented) */
#define T_STAT_STACK            0x0020  /*  LIFO (not implemented) */

/* Bit masks for KPROC.p_type field */

#define P_TYPE_PRIVILEGED       0x0001  /* privileged process */
#define P_TYPE_FOREGROUND       0x0002  /* capable of FG operation */
#define P_TYPE_SESSION          0x0004  /* started in new session */
#define P_TYPE_NOHIBER          0x0008  /* never hibernates */
#define P_TYPE_NONEWCONFIG      0x0010  /* never notified for online config */
#define P_TYPE_SYSCT            0x0020  /* initialized from sys CT. */

/* Bit masks for KPROC.p_stat field */

#define P_STAT_USED             0x0001  /* entry has been used before */
#define P_STAT_ACTIVE           0x0002  /* process is currently active */
#define	P_STAT_TERM_FLAG        0x0004  /* term flag is set */
#define P_STAT_LOCK_EXPIRED     0x0008  /* lock has expired due to timeout */
#define P_STAT_OS_ERROR         0x0010  /* process generated an OS error */
#define P_STAT_STARTING         0x0020  /* RUNMGR is starting process */
                                        /* (or attempting to do so) */
/* Value ranges for KPROC.p_order field */
#define P_ORDER_MIN             0
#define P_ORDER_MAX             33

/* Values for KPROC.p_req field */

#define P_REQ_NONE              0       /* awake (not sleeping) */
#define P_REQ_LOCK              1       /* attempting to lock database */
#define P_REQ_WAIT_READ         2       /* waiting to read database */
#define P_REQ_WAIT_WRITE        3       /* waiting to write database */
#define P_REQ_WAIT_ACCESS       4       /* waiting to read or write */

/* Indices into KPROC.p_acct field */

#define P_ACCT_TTFS             0       /* # of test term flag calls */
#define P_ACCT_READS            1       /* # of read calls */
#define P_ACCT_NREAD            2       /* # of elements read */
#define P_ACCT_WRITES           3       /* # of write calls */
#define P_ACCT_NWRITE           4       /* # of elements written */
#define P_ACCT_LOCKS            5       /* # of lock calls (effective) */
#define P_ACCT_TLOCK            6       /* ticks with database locked */
#define P_ACCT_WAITS            7       /* # of wait calls (effective) */
#define P_ACCT_SLEEPS           8       /* # of times put to sleep */
#define P_ACCT_TSLEEP           9       /* ticks sleeping for any reason */
#define P_ACCT_MAX              10      /* # of pieces of accounting info */
                                        /* (dimension of p_acct[] array) */

/* Indices into KINST.i_stat field */
#define I_STAT_USED     1   /* Instance is in use */

/* Flags for function fl_set_kinst() */
#define I_SET_CYCLEMASK         0x0001
#define I_SET_SIGNALMASK        0x0002

#define	MAX_MEM_SEG_SIZE	65536L
#define MAX_MEM_MAPS            1000    /* max number of memory maps */
	                                /* per KMEM (# KMEMMAP's) */
	                                /* (must be a multiple of 8) */
#define SEQ_MEM_MAPS            1024    /* map sequence (must be smallest
					/* power of 2 > MAX_MEM_MAPS) */
#define MAX_MEM_SIZE            (MAX_MEM_SEG_SIZE - MAX_MEM_MAPS*sizeof(KMEMMAP) \
	                        - sizeof(KMEM))
	                                /* max managed memory segment */
	                                /* size per KMEM (one chunk) */

/* Bit masks for KSEG.s_flags field */
#define S_FLAGS_DBRT  0x0001            /* Memory segment for the DBRT */

/* Kernel data structures */

typedef	struct _KUSR			/* User (domain) */
{
	char	u_name[MAX_USR_NAME];	/* name */
	char	u_parent[MAX_USR_NAME];	/* parent */
	uint	u_instance;		/* maximum instance */
} KUSR;

typedef struct _KSEG                    /* Kernel segment */
{
	char FAR *s_seg;                /* base address of segment */
	u32     s_siz;                  /* size of segment, in bytes */
	u32     s_used;                 /* number of used bytes */
	u32     s_free;                 /* number of free bytes */
	i32	s_id;			/* segment id (shared memory id) */
	i16     s_flags;                /* flags for segment */
} KSEG;

#ifdef AIX
typedef struct ker_shmseg
{
	u32 ks_sid;		/* internal shmid */
	u32 ks_usid;	/* actual unix shared memory id */
	u32 ks_inuse;	/* 1 if in use 0 if free */
	u32 ks_offs;	/* offset from beginning of block */
	char *ks_ptr;	/* global pointer */
	u32 ks_size;	/* length */
}KSG;
#endif

typedef struct _KTYPE                   /* Kernel data type */
{
	u16     t_stat;                 /* storage type/access type bits */
	u16     t_max;                  /* max number of elements */
	u16     t_usiz;                 /* user size per element */
	u16     t_ksiz;                 /* Kernel size per element */
	i16     t_id;                   /* data type identifier */
	                                /* (FL_DIGITAL, etc.) */
	u16	t_private;		/* Private (non-shared) data */
	u32	t_dsiz;			/* size of KDATA array */
	u32	t_vsiz;			/* size of values array */
	char FAR *t_seg;		/* address of data storage if shared  */
	char	t_user[MAX_USR_NAME];	/* name of owning domain */
} KTYPE;

typedef struct _KDATA                   /* Kernel data entry */
{
	mask_t  d_chng;                 /* change (in value) bits */
	mask_t  d_wait;                 /* wait (to read and/or write) bits */
} KDATA;

typedef	struct	_KVAL
{
	ATTR	d_attr;                 /* attribute bits */
} KVAL;					/* variable length data follows */

/* Memory management structures */


typedef u16 KMEMMAP;                    /* Kernel memory map */
	                                /* (holds offsets to blocks) */

typedef struct _KMEMBLK                 /* Kernel memory block */
{
	u16     mb_map;                 /* memory map index and sequence */
	u16     mb_siz;                 /* size of block, in units */
	u16     mb_rsvd[6];             /* reserved --- we require */
	                                /* sizeof(KMEMBLK) = 1 unit = 16 */
} KMEMBLK;

typedef struct _KMEM                    /* Kernel memory (v-to-p) */
{
	KMEMMAP FAR *m_mapp;            /* ptr to memory map array */
	KMEMBLK FAR *m_bblkp;           /* ptr to beginning of blocks */
	KMEMBLK FAR *m_fblkp;           /* ptr to first free block */
	KMEMBLK FAR *m_eblkp;           /* ptr to end of blocks */
	u16     m_unit;                 /* size of a unit, in bytes */
	u16     m_maps;                 /* total number of memory maps */
	u16     m_mapndx;               /* next spare map index */
	u16     m_mapseq;               /* next spare map sequence */
	u16     m_ublks;                /* number of used blocks */
	u16     m_fblks;                /* number of free blocks */
	u16     m_used;                 /* number of used units */
	u16     m_free;                 /* number of free units */
} KMEM;

typedef	int	(*ATTRFN)(void /* struct _KPROC */ *pp,
		KDATA FAR *kdp, KVAL FAR *kvp, 
		void FAR *current, void FAR *request, int rw);

typedef struct _KPROC                   /* client process */
{
	struct _KPROC *p_link;     	/* link to next request */
	char    p_name[MAX_PROC_NAME];  /* process name */
	char    p_desc[MAX_PROC_DESC];  /* process description */
	char    p_cmd[MAX_CMD_LINE];    /* command line */
	char    p_cmd_init[MAX_CMD_LINE]; /* command line @ fl_proc_init()*/
	char    p_path[MAX_FILE_NAME];    /* relative path name */
	char    p_path_init[MAX_CMD_LINE];/* path @ fl_proc_init()*/
	u16     p_type;                 /* process type bit field */
	u16     p_stat;                 /* process status bit field */
	u16     p_segs;                 /* segments gotten */
	u16     p_prty;                 /* priority (class & level) */
	u16     p_order;                /* start order (0-31) */
	u16     p_lock;                 /* lock count (for nesting) */
	u16     p_user;                 /* index into user names table */
	i16     p_req;                  /* current request type */
	i16     p_errno;                /* error number last reported */
	u32     p_pid;                  /* process id */
	u32     p_tick;                 /* clock tick at last request */
	u32     p_acct[P_ACCT_MAX];     /* accounting information */
	u32     p_sig_act;              /* mask of signals now active */
	u32     p_sig_del;              /* mask of signals deliverable */
	u32     p_mask;                 /* this task's mask bit */
	VPTR    p_tag_ptr;              /* v-ptr to registered tag list */
	u16     p_tag_num;              /* number of tags in tag list */ 
	u16     p_taskid;               /* reference - task id */
	TAG     e_ctrl;                 /* control: start/stop (DIG or ANA) */
	TAG     e_stat;                 /* self-reported status (ANA) */
	TAG     e_msg;                  /* self-reported message (MSG) */
	ATTR    p_read_mask;            /* mask of attributes for read */
	ATTR    p_write_mask;           /* mask of attributes for write */
	ATTR    p_change_mask;          /* mask of attributes for change */
	ATTRFN	p_attr_fn[MAX_ATTR_BIT];
} KPROC;

typedef struct _KGLOBALS                /* Kernel globals */
{
	id_t	g_lock_id;		/* ID of database lock */
	id_t	g_link_id;		/* ID of next task in queue */
	mask_t  g_active_mask;          /* active processes mask */
	mask_t  g_sleep_mask;           /* sleeping processes mask */
	mask_t  g_lock_mask;            /* lock request pending mask */
	mask_t  g_wait_read_mask;       /* waiting to read mask */
	mask_t  g_wait_write_mask;      /* waiting to write mask */
	mask_t  g_wait_access_mask;     /* waiting to access mask */
	u32	g_lock_tick;            /* clock tick at last lock */
} KGLOBALS;

/* Instance management structures */

typedef struct _KDPTR           /* KDATA Pointer */
{
	struct _KDATA FAR *t_seg;   /* base address of KDATA array */
	char FAR *t_val;        /* base address of value array */
					/* This points to a KVAL, but we */
					/* need a char to properly calculate */
					/* the offset */
} KDPTR;

typedef struct _KINST                   /* Application instance */
{
	mask_t  i_active_mask;          /* active processes mask */
	mask_t  i_sleep_mask;           /* sleeping processes mask */
	mask_t  i_lock_mask;            /* lock request pending mask */
	mask_t  i_wait_read_mask;       /* waiting to read mask */
	mask_t  i_wait_write_mask;      /* waiting to write mask */
	mask_t  i_wait_access_mask;     /* waiting to access mask */
	mask_t  i_wake_mask;            /* work area for wakeup mask */
	mask_t  i_cycle_mask;           /* online config - cycle mask */
	mask_t  i_signal_mask;          /* online config - signal mask */
	uint    i_stat;         /* status (I_STAT_USED) */
	uint    i_user;         /* index into Kgdp.kuser */
	char    i_uname[MAX_USR_NAME];  /* user instance name */
	KPROC   i_proc[MAX_PROCS];  /* proc table for this app */
	KDPTR NEAR *i_kdptr;        /* pointers to change bits and data */
} KINST;


/* Convert FactoryLink ID to instance and task parts */
#define ID2INST(id)          ((id) >> 8)
#define INST2WID(id)         ((id_t)((id) << 8))
#define ID2INSTID(id)        ((id_t)((id) & 0xFF00))
#define ID2TASK(id)          ((id) & 0xFF)
#define MAKE_ID(inst, task)  ((id_t)(((inst) << 8) + ((task) & 0xFF)))

#ifdef __cplusplus
extern "C" {
#endif
int	FLENTRY fl_get_name(char* flname, int maxlen);
int	FLENTRY fl_get_globals(KGLOBALS FAR *ugp);	/* obsolete */
int	FLENTRY fl_get_app_globals(id_t id, KGLOBALS FAR *ugp);
int     FLENTRY fl_get_nkusrs(void);
int     FLENTRY fl_num_kusrs(uint n);
int     FLENTRY fl_nth_kusr(uint n, KUSR *kusr);
int     FLENTRY fl_get_kusr(char *dom, KUSR *kusr);
uint	FLENTRY fl_get_nsegs(void);
int	FLENTRY fl_get_seg(uint seg, KSEG FAR *usp);
uint	FLENTRY fl_get_nmems(void);
int	FLENTRY fl_get_mem(uint mem, KMEM FAR *ump);
uint	FLENTRY fl_get_ntypes(void);
int	FLENTRY fl_get_type(uint type, KTYPE FAR *utp);
int	FLENTRY fl_get_nprocs(void);
int	FLENTRY fl_get_proc(id_t id, KPROC FAR *upp);
int	FLENTRY fl_get_env(id_t id, KENV FAR *uep);
int     FLENTRY fl_get_kinst(char* dom, char* user, KINST *pki); 
int     FLENTRY fl_get_nkinsts(void); 
int	FLENTRY fl_nth_kinst(uint ndx, KINST *pkinst);
int	FLENTRY fl_set_kinst(uint ndx, uint setflags, KINST *pkinst);
int	FLENTRY fl_set_type(uint type, KTYPE FAR *utp);
int	FLENTRY fl_set_proc(id_t id, KPROC FAR *upp);
int	FLENTRY fl_set_env(id_t id, KENV FAR *uep);
int	FLENTRY fl_dump_segs(char FAR *bp);
int	FLENTRY fl_dump_mems(char FAR *bp);
int	FLENTRY fl_dump_types(char FAR *bp);
int	FLENTRY fl_dump_procs(char FAR *bp);
int	FLENTRY fl_init(char FAR *bp);		/* Obsolete! */
int	FLENTRY fl_last_newconfig(int dir, KDT* kdt);

int	FLENTRY fl_create_rtdb(char FAR *pgm_dir, char FAR *app_dir,
		char FAR *name, 
		KUSR FAR *user, int ucnt, 
		KTYPE FAR *utype, int tcnt,
		int max_segs, int max_mems, u16 kflags);
int     FLENTRY fl_dbrt_adjust(id_t id, KTYPE* utype, int tcnt);
int	FLENTRY fl_delete_rtdb(int rtid);
id_t	FLENTRY fl_init_app(char FAR *name, char FAR *domain, 
			    char FAR *user, KPROC FAR *pp);
int	FLENTRY fl_exit_app(id_t id);
int	FLENTRY fl_reset_app_mem(id_t id);

int	FLENTRY fl_map_firstkgd(int* appid);
int	FLENTRY fl_map_nextkgd(int* appid);
int	FLENTRY fl_unmap_kgd(void);

/* Key Access Services: Platform-Dependent */

int	FLENTRY fl_get_options(void FAR *buf);
int	FLENTRY fl_proc_options(char FAR *uname, short FAR *options);
int	FLENTRY fl_check_key(void);
int	FLENTRY fl_check_bit(short bit_num);

int	FLENTRY	fl_set_read_mask(id_t id, uint n, ATTR FAR *ap, ATTRFN *fn);
int	FLENTRY	fl_set_write_mask(id_t id, uint n, ATTR FAR *ap, ATTRFN *fn);
int	FLENTRY fl_move(id_t id, TAG FAR *src_tagp, TAG FAR *dst_tagp);


#ifdef __cplusplus
}
#endif
#endif /* _FL_KER_INCLUDED } */
