4.3BSD-Tahoe/usr/src/cci/enpload.c

Compare this file to the similar file:
Show the results in this format:

#include <a.out.h>
#include <fcntl.h>
#include <stdio.h>

#define mkioctl(type,value) (0x20000000|('type'<<8)|value)

#define ENPIOGO		mkioctl( S,1 )		/* start the enp */
#define ENPIORESET	mkioctl( S,2 )		/* reset the enp */

#define	ENP0		0x0	/* Enp's 0 Memory		*/
#define	ENP1		0x0	/* Enp's 1 Memory		*/
#define	ENP2		0x0	/* Enp's 2 Memory		*/
#define	ENP3		0x0	/* Enp's 3 Memory		*/

#define	RELO		0x03FFFF	/* ENP->Kernel Mask		*/

#define	BUTTON		0x1000		/* Addr to "push" for startup	*/
#define	JADDR		0x1004		/* Start vector goes here	*/
#define	JUMP		0x8080		/* "jump" command		*/

/*
 *		ENP "device" table (so we can load multiple ENPs)
 *		See ENP/30 User Guide
*/

typedef struct	enp
{
	char	name[8];		/* Device's "name"		*/
	long	mstart;			/* Host's idea of enp mem org	*/
	long	button;			/* Addr of "go" button		*/
	long	jaddr;			/* Addr of "jump" command	*/
} ENP;

ENP	enp_tab[] =
{
	{ "enp0", ENP0, ENP0 + BUTTON, ENP0 + JADDR, },
	{ "enp1", ENP1, ENP1 + BUTTON, ENP1 + JADDR, },
	{ "enp2", ENP2, ENP2 + BUTTON, ENP2 + JADDR, },
	{ "enp3", ENP3, ENP3 + BUTTON, ENP3 + JADDR, },
};
short	num_enp = sizeof(enp_tab) / sizeof(enp_tab[0]);

ENP	*getenp();
short	enpfid = -1;			/* dev "enpram" fid	*/


/*
 *		For loading from a.out files ...
*/

#define	BSIZE		512		/* Size buffer we use	*/
#define	MAXFILE		4		/* Max of 4 a.outs	*/
#define MAXBIN		4		/* bin files on command line */

typedef struct	bins
{
	short	b_fid;
	char	*b_name;
} BINS;

BINS	file_tab[ MAXFILE ];		/* fid/name of a.outs	*/

char	enpdev[] = "/dev/enpXram";
char	buff[ BSIZE ];			/* I/O Buffer		*/
char	zbuf[ BSIZE ];			/* For quick clearing	*/

int	nostart;
int	noload;

main( argc,argv )
int	argc;
char	**argv;
{
	register BINS	*fp;			/* File params		*/
	register short	fcnt,i;			/* Files to load	*/
	struct exec 	hdr;			/* a.out header		*/
	int		cnt;			/* I/O count		*/
	long		f_size,bss_size;	/* text + data & bss	*/

	register ENP	*ep;			/* enp_tab pointer	*/
	unsigned long	enp_go;			/* Start up vector	*/
	short		enp_jump = JUMP;	/* "jump" command	*/
	long		lstart;			/* Start loading at	*/
	long		cstart;			/* Clear from		*/


	if( (argc < 3) || (argc > 3 + MAXBIN) )
	{
		printf( "usage: enpload dev file_1 [ file_2 ... file_4 ]\n" );
		exit( 1 );
	}
	argv++;
	if( (ep = getenp( *argv++ )) == 0 )
	{
		printf( "Bad ENP device name!\n" );
		exit( 1 );
	}

	enpdev[8] = ep->name[3];
	dup2(1,2);	/* redirect sdterr to stdout */
	if( (enpfid = open(enpdev,O_RDWR)) == -1 )
	{
		 sprintf(zbuf, "enpload: Can't open %s ram", ep->name);
	   	 perror( zbuf );
		 exit( 1 );
	}

/*	Collect file names and compute number of them		*/

	fp = file_tab; fcnt = 0;
	while( *argv )
	{
		if( argv[0][0] == '-' )
		{
			if( argv[0][1] == 'L' )		
				noload = 1;
			else
			if( argv[0][1] == 'S' )
				nostart = 1;
			argv++;
		}
		else
		{
			fp->b_name = *argv++;
			fp++; fcnt++;
		}
	}

/*	Zero buffer used to clear bss storage in ENP		*/

	for( i = 0; i < BSIZE; i++ )
	{
		zbuf[i] = 0;
	}

	if( noload )
	{
		printf("Restart %s at 0xf02000\n", ep->name);
		ioctl( enpfid,ENPIOGO,0xf02000 );
		exit( 0 );
	}
	ioctl( enpfid,ENPIORESET,0 );

/*	Open, validate, and load each file_tab[] file		*/

	for( i = 0; i < fcnt; i++ )
	{
		fp = &file_tab[i];
		if( (fp->b_fid = open( fp->b_name,O_RDONLY )) == -1 )
		{
			printf( "enpload: Can't open %s!\n",fp->b_name );
			closem( i-1 );
			exit( 1 );
		}

		if( read( fp->b_fid,&hdr,sizeof( hdr ) ) != sizeof( hdr) )
		{
			printf( "enpload: %s Bad header!\n",fp->b_name );
			closem( i );
			exit( 1 );
		}

		if( N_BADMAG( hdr ) )
		{
			printf( "enpload: %s Bad magic!\n",fp->b_name );
			closem( i );
			exit( 1 );
		}

		f_size = hdr.a_text + hdr.a_data;
		bss_size = hdr.a_bss;
		lstart = (ep->mstart + (hdr.a_entry & RELO)) - 0x1000;
		cstart = lstart + f_size;
			
		printf("Loading %s --- ", enpdev);
		printf( "with file: %s --- ",fp->b_name );
/*
		printf( "text + data: %d  bss: %d\n",f_size,bss_size );
		printf( "ENP's a_entry addr: %06X\n",hdr.a_entry );
		printf( "load start:%06X  bss start:%06X\n",lstart,cstart );

		printf( "Clearing bss ... " );
*/
		lseek( enpfid,cstart,0 );
		while( bss_size >= BSIZE )
		{
			if( write( enpfid,zbuf,BSIZE ) != BSIZE )
				printf("enpload: bss write error\n");
			bss_size -= BSIZE;
		}
		if( bss_size > 0 )
		{
			write( enpfid,zbuf,bss_size );
		}
/*
		printf( "DONE!\n" );
*/

/*
		printf( "Loading ... " );
*/
		lseek( enpfid,lstart,0 );
		while( f_size > BSIZE )
		{
			cnt = read( fp->b_fid,buff,BSIZE );
			f_size -= cnt;
			if( write( enpfid,buff,cnt ) != cnt )
				perror("enpload: write");
		}
		if( f_size > 0 )
		{
			cnt = read( fp->b_fid,buff,f_size );
			write( enpfid,buff,cnt );
		}
		printf( "DONE!\n" );
	}

/*	Last file, we exec this one	*/

	if( nostart == 0 )
	{
		enp_go = hdr.a_entry;
/*
		printf( "Starting ENP execution at %X ... ",enp_go );
*/
		ioctl( enpfid,ENPIOGO, enp_go );
/*
		printf( "DONE!\n" );
*/
	}
}


ENP *
getenp( np )
register char	*np;
{
	register ENP	*ep;

	for( ep = enp_tab; ep < &enp_tab[num_enp]; ep++ )
	if( strcmp( np,ep->name ) == 0 )
	{
		return( ep );
	}
	return( 0 );
}


closem( cnt )
register short	cnt;
{
	register BINS	*fp;

	for( fp = file_tab; fp < &file_tab[cnt]; fp++ )
	{
		close( fp->b_fid );
	}
	if( enpfid != -1 )
	{
		close( enpfid );
	}
}