BSD 4_3_Tahoe development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Wed, 2 Jul 1986 03:23:14 +0000 (19:23 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Wed, 2 Jul 1986 03:23:14 +0000 (19:23 -0800)
Work on file usr/src/cci/enpload.c

Synthesized-from: CSRG/cd2/4.3tahoe

usr/src/cci/enpload.c [new file with mode: 0644]

diff --git a/usr/src/cci/enpload.c b/usr/src/cci/enpload.c
new file mode 100644 (file)
index 0000000..d4c767f
--- /dev/null
@@ -0,0 +1,262 @@
+#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 );
+       }
+}