rdramTest2c.c 8.4 KB
/*
 * rdramTest2c.c:routines to read .text section of a coff file "rdramTest", 
 *		which contains an rdram test program and rom->rdram boot 
 *	        procedure (for reloading the gng program after the rdram test
 * 		clobbers the original version booted by the standard IPL3 
 *		code) The code is then printf'd as a C structure which is then
 *		compiled into the gng boot function, which copies this code
 *		into dmem/imem and jumps to it.
 *
 *		Cloned from an OS conversion utility suite
 *
 * Copyright 1996, Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
 * the contents of this file may not be disclosed to third parties, copied or
 * duplicated in any form, in whole or in part, without the prior written
 * permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to restrictions
 * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
 * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
 * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
 * rights reserved under the Copyright Laws of the United States.
 *
 * $Revision: 1.2 $
 */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef __sgi__
#include "sex.h"
#include "sym.h"
#include "cmplrs/stsupport.h"
#include "filehdr.h"
#include "ldfcn.h"
#include "scnhdr.h"
#else
#include "sym.h"
#include "ecoff.h"
#include "mips.h"
#include <sys/stat.h>
#endif
#include "errno.h"

unsigned int Address;                   /* Address being Dumped.    */
unsigned int Data0;                     /* Data being Dumped.       */
unsigned int Data1;                     /* Data being Dumped.       */
int      Swap   = 0;                    /* Swap Text Words.         */
char    *OFileName;                     /* Object File To Dump.     */
char    *AFileName;                     /* ASCII File To Dump into. */
char    *SName;                         /* Section to Dump.         */
#ifdef __sgi__
LDFILE  *LDPtr;                         /* File's ld Pointer.       */
SCNHDR   SHeader;                       /* Section Header.          */
FILE    *AFile;                         /* ASCII File.              */
#endif

extern int Extract(unsigned int *buf);
extern int readCoff(char *fname, unsigned int *buf);
extern void usage(void);
static void getBootFile(char *bootFileName);
static char *gloadFindFile(char *fullpath, char *postRootSuffix, char *fname);

char *progName;

unsigned char *bootBuf;
int bootWordAlignedByteSize;

void
usage(void)
{
    fprintf(stderr, 
"usage: rdramTest2c <bootstrap coff executable>\n");
    exit(1);
}

main(int argc, char *argv[])
{
    char *bootFileName;
    int i;
    unsigned int *bootWordPointer;

    if ( (argc != 2) ||
      ((bootFileName = argv[1]) == NULL) || (strlen(bootFileName) == 0) ) {
	usage();
    }

    progName = argv[0];

    /*
     * Load the rdramTest executable into a buffer, then write these buffers 
     * out to stdout as a 'C' structure which we'll redirect to a .c file.
     */
    getBootFile(bootFileName);

    printf ("/*\n");
    printf (" * Do not edit this file.  It was automatically generated\n");
    printf (" * by \"%s\" from the file \"%s\".\n", argv[0], argv[1]);
    printf (" *\n");
    printf (" * rdramTest executable size = %d bytes\n", bootWordAlignedByteSize);
    printf (" */\n\n");

    printf ("int rdramTest_data_size = %d;\n\n", bootWordAlignedByteSize);
    printf ("int rdramTest_data[] = {\n");

    bootWordPointer = (unsigned int *)bootBuf;

    for (i = 0; i < (bootWordAlignedByteSize >> 2); i++) {
	printf ("    0x%x,\n", *bootWordPointer++);
    }
    printf("};\n");

    if (bootBuf)
	free(bootBuf);
    exit(0);
}

static void
getBootFile(char *bootFileName)
{
    int bootFd;
    char scratchFileName[256];
    struct stat buf;
    char errMessage[256];

    /*
     * Load the bootstrap file (provide a default if none was supplied)
     */
    if (!bootFileName) {
	if ( gloadFindFile(scratchFileName, "./", "rdramTest") ) {
	    bootFileName = scratchFileName;
	}
    }

    if (bootFileName) {
	if ((bootFd = open(bootFileName, O_RDONLY | O_NOCTTY)) < 0) {
	    sprintf(errMessage, "%s: unable to open %s", progName, bootFileName);
	    perror(errMessage);
	    exit(1);
	}
	/*
	 * Load the bootstrap file.
	 */
	if (fstat(bootFd, &buf) < 0) {
	    sprintf(errMessage, "%s unable to stat %s", progName, bootFileName);
	    perror(errMessage);
	    close(bootFd);
	    exit(1);
	}

	bootBuf = (unsigned char *)malloc(buf.st_size);
	if (bootBuf == NULL) {
	    fprintf(stderr, "%s: unable to malloc buffer to hold %d bytes\n",
		progName, buf.st_size);
	    close(bootFd);
	    exit(1);
	}
	close(bootFd);
	bootWordAlignedByteSize = readCoff(bootFileName, (unsigned int *)bootBuf);
    } else {
	bootBuf = NULL;
    }
}

static char *
gloadFindFile(char *fullpath, char *postRootSuffix, char *fname)
{
    char *rootname, *rootpath;
    int fd;
    int try;

    for (try = 0; try <= 2; try++) {
	fullpath[0] = '\0';

	switch (try) {
	    case 0: rootname = "ROOT"; break;
	    case 1: rootname = "WORKAREA"; break;
	    case 2: rootname = NULL; break;
	}
	if (rootname != NULL) {
	    if ((rootpath = (char *)getenv(rootname)) == NULL)
		continue;
	    strcat(fullpath, rootpath);
	}

	if (postRootSuffix) {
	    strcat(fullpath, postRootSuffix);
	    strcat(fullpath, "/");
	}

	strcat(fullpath, fname);

	if (!access(fullpath, R_OK))
	    return(fullpath);
    }

    fprintf(stderr, "gloadFindFile: can't find file %s\n", fullpath);
    fullpath[0] = '\0';
    return(NULL);
}


/*
 * Read a COFF file into a buffer.  Return number of bytes read,
 * -1 if error.
 */
int
readCoff(char *fname, unsigned int *buf)
{
    int textSize, dataSize, bssSize;

    OFileName = fname;
    SName     = ".text";	/* set section name = .text */
    textSize = Extract(buf);

    if (textSize < 0)
	return(-1);

    return( textSize );
}

int
Extract(unsigned int *buf)
{
    int bytesRead;

#ifdef __sgi__
    if ((LDPtr = (LDFILE *) ldopen (OFileName, LDPtr)) == NULL)
    {                                   /* Open File.               */
       fprintf (stderr, "Extract(): Cannot open %s.\n", OFileName);
       return (-1);
    }

    switch (HEADER (LDPtr).f_magic) 
    {
    case MIPSEBMAGIC:
    case MIPSEBMAGIC_2:
    case MIPSEBMAGIC_3:
           Swap = (gethostsex () == LITTLEENDIAN);
           break;

    case MIPSELMAGIC:
    case MIPSELMAGIC_2:
    case MIPSELMAGIC_3:
           Swap = (gethostsex () == BIGENDIAN);
           break;
    }
    if (ldnshread (LDPtr, SName, &SHeader) == FAILURE)
    {
       fprintf (stderr, "Warning:  %s has no %s section.\n", OFileName, SName);
    } else {

       FSEEK (LDPtr, SHeader.s_scnptr, BEGINNING);

       for (Address = SHeader.s_paddr; 
	 (Address - SHeader.s_paddr) < SHeader.s_size; Address += 8) {
           FREAD ((char *)&Data0, 1, 4, LDPtr);
           if (Swap) Data0 = swap_word (Data0);
           FREAD ((char *)&Data1, 1, 4, LDPtr);
           if (Swap) Data1 = swap_word (Data1);
           if (Swap) {
	      *buf = Data1;
	      *(buf+1) = Data0;
           } else {
	      *buf = Data0;
	      *(buf+1) = Data1;
	   }
	   buf += 2;
       }
    }
    ldclose (LDPtr);                    /* Close File.              */
    return(SHeader.s_size);		/* # of bytes read */
#else
    FILE *fp;
    FILHDR hdr;
    SCNHDR scn;
    int n, i;
    unsigned short magic;
    if ((fp = fopen(OFileName, "r")) == NULL) {
	fprintf(stderr, "Extract(): Cannot open %s.\n", OFileName);
	return -1;
    }
    fread(&hdr, sizeof hdr, 1, fp);
    magic = hdr.f_magic[1] | hdr.f_magic[0] << 8;
    switch (magic) {
    case MIPS_MAGIC_BIG:
    case MIPS_MAGIC_BIG2:
    case MIPS_MAGIC_BIG3:
#if 0
	Swap = (gethostsex () == LITTLEENDIAN);
#endif
	break;

    case MIPS_MAGIC_LITTLE:
    case MIPS_MAGIC_LITTLE2:
    case MIPS_MAGIC_LITTLE3:
#if 0
	Swap = (gethostsex () == BIGENDIAN);
#endif
	break;
    }
    /* skip aout header */
    fseek(fp, sizeof(AOUTHDR), SEEK_CUR);
    n = ntohs(hdr.f_nscns[0] | hdr.f_nscns[1] << 8);
    for(i = 0; i < n; i++) {
	fread(&scn, sizeof scn, 1, fp);
	if (strcmp(scn.s_name, SName) == 0) {
	    fseek(fp, ntohl(scn.s_scnptr[0] | scn.s_scnptr[1] << 8 | scn.s_scnptr[2] << 16 | scn.s_scnptr[3] << 24), SEEK_SET);
	    bytesRead = fread(buf, 1, ntohl(scn.s_size[0] | scn.s_size[1] << 8 | scn.s_size[2] << 16 | scn.s_size[3] << 24), fp);
	    break;
	}
    }
    fclose(fp);
    return bytesRead;
#endif
}