rdram.c 5.25 KB
#ifdef __sgi__
#include <bstring.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <verify.h>

#include "rdram.h"

static int rdramfd;

unsigned int quiet_mode = 0;

/*
 * Arguments:
 *  file - file name (.rdram extension added)
 *  rw - rw flag
 *  hflag - hidden flag
 *  nrdrams - number of rdrams (0 is don't care)
 *  addresses for main & hidden addrs and sizes
 * 
 *  rw	h   Meaning
 *   0	0   read only no hidden part, size 
 *   0  1   read only, hidden part required , size must be 2 1/4 or 4 1/2 Meg
 *   1  0   read/write, no hidden part, If file doesn't exist will be created to 2/4 Meg
 *   1  1   read/write, hidden part, file created or expanded to 2 1/4 or 4 1/2 Meg
 */
int
rdraminit(char *file, int rw, int hflag, int nrdrams,
unsigned char **mainaddrp, long *mainsizep,
unsigned char **hiddenaddrp, long *hiddensizep)
{
    struct stat statbuf;
    char filename[1024];
    unsigned char *mainaddr, *hiddenaddr;
    long nbytes;	    /* only used in r/w case */
    VerifyInfo *vp;
    
if (!quiet_mode)
  fprintf(stderr, "rdraminit: file is %s\n", file);

    /* Open file, and then mmap them in, file must exist already */
    
    sprintf(filename, "%s.rdram", file);
    if (stat(filename, &statbuf) == -1) {
	fprintf(stderr, "Could not stat <%s>\n", filename);
	perror("");
	return 0;
    }
    
    if (nrdrams < 0 || nrdrams > 4) {
	fprintf(stderr, "nrdrams not 0, 1, 2, 3, or 4.  (is %d)\n", nrdrams);
	return 0;
    }

    /*
     * Compute nrdrams, if specifed as zero
     */
    if (nrdrams == 0) {
	if (statbuf.st_size == 0)
	    nrdrams = 1;
	else if ( statbuf.st_size <= (TOTAL_MEMORY_SIZE) )
	    nrdrams = 1;
	else if ( statbuf.st_size <= (TOTAL_MEMORY_SIZE * 2) )
	    nrdrams = 2;
	else if ( statbuf.st_size <= (TOTAL_MEMORY_SIZE * 3) )
	    nrdrams = 3;
	else if ( statbuf.st_size <= (TOTAL_MEMORY_SIZE * 4) )
	    nrdrams = 4;
	else {
	    fprintf(stderr, "rdram file size 0x%x too big\n", 
		statbuf.st_size);
	    return 0;
	}
    }

    /* size check */
    if (rw) {				/* Read/Write */

	if ( statbuf.st_size != 0 && statbuf.st_size != 
	  (nrdrams * MAIN_MEMORY_SIZE) && statbuf.st_size != 
	  (nrdrams * TOTAL_MEMORY_SIZE) ) {
	    fprintf(stderr, "%s bad size 0x%x (write)\n", 
	      filename, statbuf.st_size);
	    return 0;
	} else {
	    if (hflag )
		nbytes = (nrdrams * TOTAL_MEMORY_SIZE);
	    else 
		nbytes = (nrdrams * MAIN_MEMORY_SIZE);
	}
	*hiddensizep = statbuf.st_size - (nrdrams * MAIN_MEMORY_SIZE);
    } else {				/* Read Only */
	
	if (hflag) {
	    if ( statbuf.st_size != (nrdrams * TOTAL_MEMORY_SIZE) ) {
		fprintf(stderr, "%s bad size 0x%x (read)\n", 
		  filename, statbuf.st_size);
		return 0;   
	    }
	} else {
	    if ( statbuf.st_size != (nrdrams * MAIN_MEMORY_SIZE) &&
	      statbuf.st_size != (nrdrams * TOTAL_MEMORY_SIZE) ) {
		fprintf(stderr, "%s bad size 0x%x (read)\n", 
		  filename, statbuf.st_size);
		return 0;   
	    }
	}
	*hiddensizep = statbuf.st_size - (nrdrams * MAIN_MEMORY_SIZE);
    }
    
    if (rw) {
        if ((rdramfd = open(filename, (O_RDWR | O_CREAT), 0644)) == -1) {
	    fprintf(stderr, "Could not open <%s>\n", filename);
	    return 0;
	}

#ifndef __sgi__   /* On Linux we have to grow file by ourself */
         if (nbytes > statbuf.st_size) {
             char cc='\0';
             lseek(rdramfd, nbytes-1, SEEK_SET);
             write(rdramfd, &cc, 1);
         }  
#endif

	mainaddr = mmap(NULL, nbytes, (PROT_READ | PROT_WRITE),
#ifdef __sgi__
		(MAP_SHARED | MAP_AUTOGROW), rdramfd, 0);
#else
		(MAP_SHARED), rdramfd, 0);
#endif
	hiddenaddr = mainaddr + (MAIN_MEMORY_SIZE * nrdrams);
	
	/* grow the file? */
	if (statbuf.st_size != nbytes) {
	    if (!quiet_mode)
	      fprintf(stderr, "Warning! %s grew, was 0x%x now 0x%x\n",
		      filename, statbuf.st_size, nbytes);
	    *(mainaddr + nbytes - 1) = 0;
	    /* need to copy hidden bits up  if expanding from 2.25 to 4.5 Meg */
	    if (statbuf.st_size == TOTAL_MEMORY_SIZE && 
		    nbytes == 2 * TOTAL_MEMORY_SIZE) {
	        bcopy(mainaddr + MAIN_MEMORY_SIZE, hiddenaddr, HIDDEN_MEMORY_SIZE);
	        bzero(mainaddr + MAIN_MEMORY_SIZE, HIDDEN_MEMORY_SIZE);
	    }
    }

    } else {
        if ((rdramfd = open(filename, O_RDONLY)) == -1) {
	    fprintf(stderr, "Could not open <%s>\n", filename);
	    return 0;
	}
	mainaddr = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, rdramfd, 0);
	hiddenaddr = mainaddr + (MAIN_MEMORY_SIZE * nrdrams);
 	
    }
    
    if (!quiet_mode)
      fprintf(stderr, "rdram_mmap_init: mainaddr is 0x%x\n", mainaddr);

    if (mainaddr == (unsigned char *)-1) {
	fprintf(stderr, "Could not mmap <%s>\n", filename);
	return 0;
    }
    if (!quiet_mode)
      fprintf(stderr, "rdram_mmap_init: hiddenaddr is 0x%x\n", hiddenaddr);
    
    /* set addresses and counts */
    *mainaddrp = mainaddr;
    *hiddenaddrp = hiddenaddr;
    if (nrdrams == 1)
	*mainsizep = MAIN_MEMORY_SIZE;
    else
	*mainsizep = 2*MAIN_MEMORY_SIZE;
	
    vp = (VerifyInfo *)(mainaddr + VERIFY_INFO_PHYSADDR);

#ifdef __sgi__    
    if (vp->magicNumber != MAGICNUMBER) {
#else
    if (ntohl(vp->magicNumber) != MAGICNUMBER) {
#endif

	fprintf(stderr, "Warning! VerifyInfo magic number is 0x%x, not 0x%x\n",
	    vp->magicNumber,  MAGICNUMBER);
    }
     
    return 1;
    
}