/* BootParam structure-- taken from the SOLO 0.97 boot loader package
 * (http://www.csh.rit.edu/~shaggy/software.html)
 * and modified, with the author's permission.
 */


typedef struct Bpi Bpi;
typedef struct BpStat BpStat;
typedef struct BpChan BpChan;


/* IMPORTANT NOTE:
 *	the Shannon bootloader was compiled with tools that have
 *	the following calling conventions:
 *		r0 = param0
 *		sp+8 = param1
 *		sp+12 = param2
 *		etc...
 *	to call this from normal APCS, you'll need to add
 *	five dummy arguments between the first and second parameter.
 */



/* Upon invocation of a program from the Shannon boot loader,
 * the address of the Bpi structure is passed in r0
 */


/* BootParam interface format v1.0: */
struct Bpi {

	/* Generic, (mostly) portable interface: */

	uint8	bootver_major;	/* major number of boot loader version */
	uint8	bootver_minor;	/* minor number of boot loader version */
	uint8	bpi_major;	/* major number of bootparam version */
	uint8	bpi_minor;	/* minor number of bootparam version */
	char	*bootname;	/* name of boot loader (without the version) */
	int	argc;		/* argc for main() */
	char	**argv;		/* *argv[] for main() */
	char	**envp;		/* *envp[] for main() (currently unused) */
	uint32	flags;
	uint32	_2;
	uint32	_3;
	uint32	entry;		/* starting execution address */
	uint32	lomem;		/* lowest virtual address available */
	uint32	himem;		/* highest virtual address available + 1 */
	uint32	_4;

	uint32	msgbuf;		/* kernel message buffer */
	uint16	msgsize;	/* size of message buffer */
	uint16	msgptr;		/* current pointer into message */
	uint32	_5;
	uint32	_6;

	uint32	_7[14];

	int	console_fd;	/* file descriptor for console */
	int	_8;		/* self_fd - not used */

	/* Note: because the bootloader was built with Inferno
	 * tools and this code isn't, we have to put all
	 * the calls with dummy arguments for r1 through r3
	 * If gcc has some way to specify a different calling
	 * convention for just these calls, that would be 
	 * great, but I couldn't find one.
	 */
	void	(*exit)(uint32 code);		/* exit from kernel */
	void	(*reboot)(int cold);		/* warm/cold reboot */
	int	(*open)				/* open file and */
		(char *name, int oflag);	/* return 0 or fd */
	int	(*close)(int);			/* close a file */
	void	*_9;				/* readdir */
	int32	(*read)				/* read from a file/device */
		(int, void *adr, uint32 len);
	int32	(*write)			/* write to a file/device */
		(int, void *adr, uint32 len);
	int	(*fstat)
		(int, BpStat *stbuf);
	int	(*seek)				/* set file position */
		(int, uint32 ofs);
	void	(*file2chan)(BpChan*);		/* register a file callback */
	int	(*poll)(int ms);		/* wait for events on file2chans */
	void	*_12;
	int	(*exec)				/* execute binary at addr */
		(void *adr, Bpi *, int flags);
	void	*_[3];


	/* StrongARM-specific Interface: */

	uint32	flashbase;	/* base address of flash memory */
	uint32	cpuspeed;	/* CPU speed, in HZ */
	uint32	pagetable;	/* page table virtual address */
	uint32	_14[5];

	/* for interfacing to serial port, etc for raw connection: */
	int	(*send)(void *buf, int r1, int r2, int r3, int len);
	int	(*recv)(void *buf, int r1, int r2, int r3, int len, int ms);
	
	/* for taking over the filesystem connection from the monitor: */
	int	bps;
	int	rootfid;
	uint32	_15[4];	
};

enum {
	BP_FLAG_DEBUG = 0x0001,
	BP_FLAG_HARDWARE_RESET = 0x0010,
	BP_FLAG_SOFTWARE_RESET = 0x0020,
	BP_FLAG_WATCHDOG_RESET = 0x0040,
	BP_FLAG_SLEEPMODE_RESET = 0x0080,
};

enum {
	BP_EXEC_FLAG_SYSMODE = 0x0001,	/* exec in system/kernel mode */
};

enum {
	BP_O_RDONLY = 1,	/* rb */
	BP_O_RDWR = 3, 		/* r+b */
	BP_O_WRONLY = 5,	/* w+ */
};

struct BpStat {
	uint32	size;	/* total file size */
	uint32	flags;	/* various file-type flags */
};

enum {
	BPSTAT_TTY = 0x0010,	/* device is a TTY */
	BPCHAN_BLOCKED = -2,	/* BPChan->read/write can return this */
};


/* BpChan structure is used to register additional files/channels
 * with the filesystem exported by the monitor code over the serial port.
 * This structure can be omitted if this functionality will not be used
 */

struct BpChan {
	struct {
		char	name[28];
		char	uid[28];
		char	gid[28];
		struct {
			uint32	path;
			uint32	vers;
		} qid;
		uint32	mode;
		int	atime;
		int	mtime;
		uint32	length;
		uint16	type;
		uint16	dev;
	} d;
	int (*open)(BpChan*, int mode);		/* OREAD, OWRITE, etc */
	void (*clunk)(BpChan*);
	int (*read)(BpChan*, void *buf, long count, long offset);
	int (*write)(BpChan*, void *buf, long count, long offset);
	void *aux;

	char *err;	/* points to error string if an error occurs */
	BpChan *link;
};