/*
 * |-----------------------------------------------------------|
 * | Copyright (c) 1991, 1990 MIPS Computer Systems, Inc.      |
 * | All Rights Reserved                                       |
 * |-----------------------------------------------------------|
 * |          Restricted Rights Legend                         |
 * | Use, duplication, or disclosure by the Government is      |
 * | subject to restrictions as set forth in                   |
 * | subparagraph (c)(1)(ii) of the Rights in Technical        |
 * | Data and Computer Software Clause of DFARS 252.227-7013.  |
 * |         MIPS Computer Systems, Inc.                       |
 * |         950 DeGuigne Avenue                               |
 * |         Sunnyvale, California 94088-3650, USA             |
 * |-----------------------------------------------------------|
 */
/* $Header: lboot.h,v 1.15.2.1 92/06/24 13:36:06 marker Exp $ */
/* |-----------------------------------------------------------|
 * | Copyright (c) 1990 MIPS Computer Systems, Inc.            |
 * | All Rights Reserved                                       |
 * |-----------------------------------------------------------|
 * |          Restricted Rights Legend                         |
 * | Use, duplication, or disclosure by the Government is      |
 * | subject to restrictions as set forth in                   |
 * | subparagraph (c)(1)(ii) of the Rights in Technical        |
 * | Data and Computer Software Clause of DFARS 52.227-7013.   |
 * |         MIPS Computer Systems, Inc.                       |
 * |         950 DeGuigne Drive                                |
 * |         Sunnyvale, CA 94086                               |
 * |-----------------------------------------------------------|
 */

#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <setjmp.h>
#ifdef SYS4.2
#define DIRSIZ	14
#define dirent direct
#else
#include <sys/dir.h>
#endif

#ifndef	_STYPES
#define	dev_t	__exp_dev_t	/* RISC/os: use expanded device types */
#endif

/*
 * Kernel structure
 *
 * The kernel requiring configuration may contain an optional header built by
 * mkboot(1M).  If so, this optional header is saved with this structure.  This
 * structure is linked to the driver linked-list so that all optional headers
 * may be easily accessed.  In some cases, only the driver optional headers are
 * required -- "driver" is the head of this linked-list.  In other cases, all
 * optional headers must be accessed -- "kernel" is the head of this linked-
 * list.
 *
 * This structure must exactly match struct driver up to the point marked
 * in struct driver.  This is done to allow routines such as eval() and
 * initdata() to be passed a "struct kernel" pointer in place of a "struct
 * driver" pointer.
 */
struct	kernel
	{
	struct driver  *next;
	struct master  *opthdr;		/* mkboot() header */
	char           *mname;		/* master name */
	char           *dname;		/* kernel object */
	unsigned char	flag;		/* empty flags field */
	unsigned char	nctl;		/* zero */
	unsigned char	int_major;	/* zero */
	};

extern struct kernel *kernel;
extern struct driver *driver;

/*
 * The kernel and driver linked list is illustrated below.
 *
 *         kernel                    driver
 *        +-------+                 +-------+
 *        |   X   |                 |   X   |
 *        +-- | --+                 +-- | --+
 *            |                         |
 *            V                         V
 *        +-------------+           +-------------+              +-------------+
 *        |struct kernel|           |struct driver|              |struct driver|
 *        |             |           |             |              |             |
 *        |      X----------------> |      X-------------------> |     NULL    |
 *        |             |           |             |              |             |
 *    +----------X      |       +----------X      |          +----------X      |
 *    |   +-------------+       |   |             |          |   |             |
 *    |                         |   |             |          |   |             |
 *    |                         |   +-------------+          |   +-------------+
 *    |                         |                            |
 *    |   +-------------+       |   +-------------+          |   +-------------+
 *    |   |             |       |   |             |          |   |             |
 *    +-> |struct master|       +-> |struct master|          +-> |struct master|
 *        |             |           |             |              |             |
 *        |             |           |             |              +-------------+
 *        +-------------+           |             |
 *                                  +-------------+
 */

/*
 * Driver structure
 *
 * Each driver (or module) existing in /boot is represented by an instance of
 * this structure.  It is built at initialization.  All object files found are
 * referred to as drivers throughout this file -- even though modules (NOTADRV)
 * are sometimes treated specially.
 */
struct	driver {
	struct driver  *next;
	struct master  *opthdr;		/* mkboot() header */
	char           *mname;		/* master name */
	char           *dname;		/* driver object */
	unsigned char	flag;		/* flags */
	unsigned char	nctl;		/* number of controllers
					 *	- actually found in EDT if a real device driver
					 *	- number of INCLUDEs if a software driver
					 *	- constant 1 if a REQuired driver
					 */
	unsigned char	int_major;	/* The internal major number generated by self-config */

	/******* end of common elements between struct driver and struct kernel *********/

	struct edt     *edtp;		/* pointer to edt structure */
#ifdef MULTIPLE_MAJOR
#define MAX_MAJOR	16		/* maximum number of majors per dev */
	unsigned char	mint_major[MAX_MAJOR];	/* multiple internal majors */
#endif MULTIPLE_MAJOR
};

#define	MAXCNTL		16	/* maximum controllers allowed per device */

/*
 * Flags
 */
#define	LOAD	0x80		/* load this driver */
#define	INEDT	0x40		/* this driver matched in EDT */
#define	INCLUDE	0x10		/* /etc/system: include this driver */
#define	EXCLUDE	0x08		/* /etc/system: exclude this driver */


struct vme_intrs {
	struct vme_intrs *v_next;
		char	*v_vname;	/* Name of int routine tied to this
					   interrupt */
	unsigned char	v_vec;	/* The vme vector tied to this interrupt */
	unsigned char	v_brl;	/* The interrupt priority level associated 
				   with this interrupt */
	unsigned char	v_unit;	/* The software identifier associated with
				   v_vec */
};

#ifdef ATBUS
struct atbus_intrs {
	int	*dummy;			/* For the dumb coding style in lboot */
	struct atbus_intrs *a_next;
	char	*a_aname;		/* Name of int routine tied to this
					   interrupt */
	unsigned char	a_irq;	/* The ATBUS IRQ tied to this interrupt */
	unsigned char	a_unit;	/* The software identifier associated with
				   a_vec */

};
#endif

struct edt {
	struct	vme_intrs *v_next;
#ifdef ATBUS
	struct	atbus_intrs *a_next;
#endif
	paddr_t	e_base;
	struct edt *e_next;
#ifdef	EDTINIT
	char *e_init;
#endif	EDTINIT
};


/*
 * MACROS
 */
#ifndef max
# define	min(x,y)	(((x)<=(y))? (x) : (y))
# define	max(x,y)	(((x)>=(y))? (x) : (y))
# define	umin(x,y)	(((unsigned)(x)<=(unsigned)(y))? (x) : (y))
# define	umax(x,y)	(((unsigned)(x)>=(unsigned)(y))? (x) : (y))
#endif max

/*
 * Boolean data type
 */
typedef	unsigned char	boolean;

#define	TRUE	1
#define	FALSE	0

/*
 * EQUAL
 */
#define EQUAL(a,b) (!(strcmp(a,b)))

/*
 * Data type for address arithmetic
 */
typedef	unsigned long	address;

/*
 * ON Condition
 */
#ifndef	mips
typedef	struct	{
	char	name[9];	/* condition name */
	}
	CONDITION;

#define ON(condition)		if (setjmp(on(&condition)))
#define REVERT(condition)	revert(&condition)
#define SIGNAL(condition)	signal(&condition)
#else	mips
/*
 * not sure if its ok to trash the stack,
 * so we'll implement this with generic
 * setjmp()/longjmp() calls for now...
 */
typedef	struct	{
	char	name[9];	/* condition name */
	jmp_buf jbuf;
	}
	CONDITION;
#define ON(condition)		if (setjmp(condition.jbuf))
#define REVERT(condition)	if (setjmp(condition.jbuf))
#define SIGNAL(condition)	longjmp(condition.jbuf)
#endif	mips

/*
 * Error table entry
 */
struct	errortab {
	short	msgnum;		/* the message number from error.h */
	short	action;		/* the action to take */
	char	*text;		/* the actual message text */
};

#define _PANIC_	 	0x8000	/* Flags:  panic() */
#define _SILENT_	0x4000	/*         do not print message text */
#define _PERROR_	0x2000	/*         perror() */
				/*       else printf() */

#define _CODE_		0x0FFF	/* Action codes		*/
#define _RETURN_	1	/*	return		*/
#define _RETURNTRUE_	2	/*	return(TRUE)	*/
#define _RETURNFALSE_	3	/*	return(FALSE)	*/
#define _DYNAMIC_	4095	/*	error_action() will determine ultimate action	*/

/*
 * Global variables
 */
extern int Debug;		/* debugging flag */
extern int Verbose;		/* verbose output flag */

extern char *ccopts;		/* cc options */
extern char *ldopts;		/* ln options */
extern int errno;		/* C library error number */
extern char *cwd;		/* current working directory */
extern char *master_dot_d;		/* master.d directory path */
extern CONDITION	ERROR;		/* universal error condition */
extern CONDITION	IOERROR;	/* read_and_check() or seek_and_check() routine failed */
extern CONDITION	ABORT;		/* load of bootprogram failed */

extern int              interrupts;	/* number of interrupt routines required */
extern int              IRTNSIZE;	/* size of an interrupt routine */

extern struct driver *driver;		/* head of struct driver linked list */

extern int              driver_text;	/* total size of driver text */
extern int              driver_symbol;	/* maximum number of symbols for any one driver */
extern int		fstypcnt;
extern int		fsincnt;
extern int              cdevcnt;
extern int              bdevcnt;
extern int		fmodcnt;
extern short		nfstyp;

extern char             *root;		/* root prefix for file searches */
extern char             *etcsystem;	/* /etc/system path name */
extern char		*kernel_master;	/* /unix path name */
extern char		*kernel_object;	/* /unix path name */
extern char             *slash_boot;	/* /boot directory name */
extern char             *master_dot_d;	/* master file directory name */
extern dev_t            rootdev;
extern dev_t            pipedev;
extern dev_t            dumpdev;
extern dev_t            swapdev;
extern daddr_t          swplo;
extern int              nswap;



/*
 * All external functions
 */
extern void            bcopy();		/* copy memory-to-memory */
extern boolean         blankline();	/* is a line entirely blank? */
extern void            edtscan();	/* scan all EDT's in the system */
extern int             error();		/* error handling routine */
extern long            eval();		/* evaluate a prefix polish expression */
extern void            exclude();	/* mark a driver to be excluded */
extern void            exit();
extern void            findsystem();	/* get path name of the system file */
extern void            free();		/* return malloc'ed memory to free status; see malloc(3C) */
extern boolean         fsinit();	/* initialize the UNIX file system */
extern void            fsystem();	/* process system file from opened FILE */
extern void            generate();	/* define, allocate and initialize data structures */
extern char           *getcwd();	/* get current working directory */
extern char           *getenv();	/* get environment variable */
extern void            ignore();	/* remember EDT entries to be ignored */
extern boolean         ignoredt();
extern void            include();	/* mark a driver to be included */
extern char           *itoa();		/* convert integer to ASCII string */
extern char	      *lcase();		/* convert uppercase string to lower case */
extern void            loadunix();	/* do actual self-configuration */
extern void            longjmp();	/* non-local goto; see setjmp(3C) */
extern void	       ls();		/* ls(1) look-alike */
extern char           *malloc();	/* storage allocator; see malloc(3C) */
extern struct master	*mkboot();	/* return (pointer to) master structure */
extern char           *mymalloc();	/* storage allocator with error checking */
extern int            *on();		/* enable an ON condition handler */
#ifndef	_NFILE
extern void            printf();	/* call firmware printf() routine */
#endif	_NFILE
extern void            read_and_check();/* read(2) system call with error checking */
extern void            revert();	/* disable an ON condition handler */
extern boolean         routine();	/* search driver boothdr's for `routine' names */
extern struct driver   *searchdriver();
extern void            seek_and_check();/* lseek(2) system call with error checking */
extern int             setjmp();	/* non-local goto; see setjmp(3C) */
extern void            signal();	/* invoke an ON condition handler */
extern char           *strcat();	/* character string concatenate; see string(3C) */
extern char           *strcpy();	/* character string copy; see string(3C) */
extern char           *strchr();
extern char           *strrchr();
extern int             strcspn();	/* character string search; see string(3C) */
extern int             strlen();	/* compute character string length; see string(3C) */
extern char           *strncat();	/* character string concatenate; see string(3C) */
extern char           *strncpy();	/* character string copy; see string(3C) */
extern char           *strpbrk();	/* character string search; see string(3C) */
extern int             strspn();	/* character string search; see string(3C) */
extern char           *strtok();	/* character string parse; see string(3C) */
extern long            strtol();	/* convert ASCII string to integer */
extern void            System();	/* process system file */

extern int             chdir();		/* chdir(2) system call */
extern void            close();		/* close(2) system call */
extern long            lseek();		/* lseek(2) system call */
extern int             open();		/* open(2) system call */
extern int             read();		/* read(2) system call */
extern int             stat();		/* stat(2) system call */

#ifndef	huhidontgetit
extern FILE           *fdopen();	/* open a buffered stream */
#endif	huhidontgetit
extern char	      *fgets();		/* read a line from a buffered stream */
extern int             fread();		/* read a buffered stream */
extern int             fseek();		/* reposition a file pointer for a buffered stream */



#ifdef u3b5
#define	ISLBE	0x04		/* this is the entry for the LBE driver */
#endif
#if defined(u3b2) || defined(mips)
#define	ISLBE	0x00		/* 3B2 has no such thing as a LBE */
#endif

/*
 * Is this controller on an extended local bus?
 */
#ifdef u3b5
#define	ONLBE(maj)	((maj)&0x30)
#endif
#if (u3b2 || mips)
#define ONLBE(maj)	(FALSE)
#endif
