⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l1rom.c

📁 TM1300/PNX1300系列DSP(主要用于视频处理)的自动boot程序
💻 C
字号:
/*
 *  copyright (c) 1995,2000 TriMedia Technologies Inc.    
 *
 *   +-----------------------------------------------------------------+
 *   | This software is furnished under a license and may only be used |
 *   | and copied in accordance with the terms and conditions of such  |
 *   | a license and with the inclusion of the this copy right notice. |
 *   | this software or any other copies of this software may not be   |
 *   | provided or otherwise made available to any other person. The   |
 *   | ownership and title of this software is not transferred.        |
 *   +-----------------------------------------------------------------+
 *
 *  Module name:
 *	l1rom.c
 *
 *  Description:
 *	Generates an EEPROM image (binary file)
 *
 *  Input:
 *	f.mi - generated using -mi option of tmld
 *
 *  Output:
 *	f.eeprom
 *	f.eeprom contains 47 header bytes as required by
 *	TM1 autoboot protocol, followed by the program bytes
 *	(bytes are swapped as required by boot)
 *
 *  Assumption:
 *	1. f.mi contains less than 2001 bytes, divisible by four
 *	   (as required by the boot protocol).
 *	2. short is 2 bytes.
 *
 *  Update History:
 *	May 23, 1998	Modify to accept SDRAM_BASE and SDRAM_LIMIT
 *			macros values from the Makefile.
 */

#if defined(__sun) || defined(__hpux)
#include <unistd.h>
#endif
#if defined(__hpux)
#define _INCLUDE_POSIX_SOURCE
#endif
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>

#if !defined(SDRAM_BASE) || !defined(SDRAM_LIMIT)
#error "Macros SDRAM_BASE and SDRAM_LIMIT have to be defined for this file to build"
#endif

#define MAX_FILE_SIZE		2000
#define MAX_EPROM_SIZE		(1024 * 2)
#define BUF_SIZE		MAX_EPROM_SIZE
#define NUM_HEADER_BYTES	47

#define MSB_1ST(n)		(unsigned char)(((n) >> 24) & 0xff)
#define MSB_2ND(n)		(unsigned char)(((n) >> 16) & 0xff)
#define MSB_3RD(n)		(unsigned char)(((n) >> 8) & 0xff)
#define MSB_4TH(n)		(unsigned char)((n) & 0xff)


static void
basename(char *fname, char *bname)
{
  char *ptr, *ptr2;
  int i;

  if ((ptr = strrchr(fname, '.')) == NULL) {
    strcpy(bname, fname);
  }
  else {
    for (ptr2 = fname, i = 0; ptr2 != ptr; ptr2++, i++) {
      bname[i] = *ptr2;
    }
    bname[i] = '\0';
  }
}


int
read_file(unsigned char *buffer, char *filename)
{
  FILE       *L1fp;
  int         L1fd, n, nbytes;
  struct stat file_stat;

  if ((L1fd = open(filename, O_RDONLY)) == -1) {
    fprintf(stderr, "Unable to open file: %s\n", filename);
    fprintf(stderr, "File doesn't exist or not readable\n");
    exit(1);
  }

  if (fstat(L1fd, &file_stat)) {
    fprintf(stderr, "Unable to fstat file: %s\n", filename);
    exit(1);
  }
  nbytes = (unsigned long)file_stat.st_size;
  close(L1fd);

  if ((L1fp = fopen(filename, "rb")) == NULL) {
    fprintf(stderr, "Unable to open file: %s\n", filename);
    fprintf(stderr, "File doesn't exist or not readable\n");
    exit(1);
  }

  if (nbytes > MAX_FILE_SIZE) {
    fprintf(stderr, "File has %5d bytes. must be less than %5d bytes\n",
	    nbytes, MAX_FILE_SIZE);
    exit(1);
  }

  n = fread(buffer, 1, nbytes, L1fp);
  if (n != nbytes) {
    fprintf(stderr, "Unable to read %5d bytes, error no: %5d\n",
	    nbytes, errno);
    exit(1);
  }

  fprintf(stderr, "      Program Size: %5d bytes\n", nbytes);
  return nbytes;
}


/*
 * Header bytes are hard-coded. Read the TM-1 boot block paper
 * to see what needs to go in here for AUTO boot.
 */
int
output_eeprom_header(int nbytes, unsigned char obuffer[])
{
  int i = 0;

  /* Output eeprom header bytes 0 thru 46, as per
   * Chapter 12 of TM 1000 Data Book (April 1997 edition).
   * These go into output array index 0 onwards
   */

  /* 0xc8 for 50 and 40 MHz TRI_CLKIN. 0xcc for 33 MHz */

  obuffer[i++] = 0xc8;     /* 0 */

  /* Sub-system Id */

  obuffer[i++] = 0x00;     /* 1 */
  obuffer[i++] = 0x03;     /* 2 */

  /* Sub-system Vendor Id */

  obuffer[i++] = 0x11;     /* 3 */
  obuffer[i++] = 0x31;     /* 4 */

  /* Bytes 5 6 7: MM Config register */

  /*
   * Byte 6 and 4 bits of byte 7 determine refresh rate.
   * The refresh rate is 4c4 for 80MHz sdram clock, 384 for 60 Mhz.
   * Use Table 11-10 Refresh Intervals of TM 1000 Preliminary Data
   * for other SDRAM clock speeds and interpolate for speeds not
   * mentioned in that table
   */

  obuffer[i++] = 0x00;     /* 5 */
  obuffer[i++] = 0x4c;     /* 6 */
  obuffer[i++] = 0x44;     /* 7 */

  /* Byte 8: PLL Ratios */

  obuffer[i++] = 0x00;     /* 8 */

  /*
   * Byte 9:  Most significant bit is 1 for stand-alone boot
   * Least 3 bits of byte 9 and 8 bits of byte 10 determine
   * L1 boot program code size. 11 bits == 2K bytes at most
   */

  obuffer[i++] = (0x80 | ((nbytes >> 8) & 0x7));
  obuffer[i++] = (nbytes & 0xfc);

  /* MMIO base register address, MSB first */
  obuffer[i++] = 0xef;			/* 11 */
  obuffer[i++] = 0xf0;			/* 12 */
  obuffer[i++] = 0x04;			/* 13 */
  obuffer[i++] = 0x00;			/* 14 */
  /* MMIO base register value, MSB first */
  obuffer[i++] = 0xef;			/* 15 */
  obuffer[i++] = 0xe0;			/* 16 */
  obuffer[i++] = 0x00;			/* 17 */
  obuffer[i++] = 0x00;			/* 18 */

  /* DRAM base register address, MSB first */
  obuffer[i++] = 0xef;			/* 19 */
  obuffer[i++] = 0xf0;			/* 20 */
  obuffer[i++] = 0x00;			/* 21 */
  obuffer[i++] = 0x00;			/* 22 */
  /* DRAM base register value, MSB first */
  obuffer[i++] = MSB_1ST(SDRAM_BASE);	/* 23 */
  obuffer[i++] = MSB_2ND(SDRAM_BASE);	/* 24 */
  obuffer[i++] = MSB_3RD(SDRAM_BASE);	/* 25 */
  obuffer[i++] = MSB_4TH(SDRAM_BASE);	/* 26 */

  /* DRAM limit register address, MSB first */
  obuffer[i++] = 0xef;			/* 27 */
  obuffer[i++] = 0xf0;			/* 28 */
  obuffer[i++] = 0x00;			/* 29 */
  obuffer[i++] = 0x04;			/* 30 */
  /* DRAM limit register value, MSB first */
  obuffer[i++] = MSB_1ST(SDRAM_LIMIT);	/* 31 */
  obuffer[i++] = MSB_2ND(SDRAM_LIMIT);	/* 32 */
  obuffer[i++] = MSB_3RD(SDRAM_LIMIT);	/* 33 */
  obuffer[i++] = MSB_4TH(SDRAM_LIMIT);	/* 34 */

  /* DRAM cacheable limit reg address, MSB first */
  obuffer[i++] = 0xef;			/* 35 */
  obuffer[i++] = 0xf0;			/* 36 */
  obuffer[i++] = 0x00;			/* 37 */
  obuffer[i++] = 0x08;			/* 38 */
  /* DRAM cacheable limit reg value, MSB first */
  obuffer[i++] = MSB_1ST(SDRAM_LIMIT);	/* 39 */ /* assumes to be the same as SDRAM_LIMIT */
  obuffer[i++] = MSB_2ND(SDRAM_LIMIT);	/* 40 */
  obuffer[i++] = MSB_3RD(SDRAM_LIMIT);	/* 41 */
  obuffer[i++] = MSB_4TH(SDRAM_LIMIT);	/* 42 */

  /* DRAM base reg value, MSB first */
  obuffer[i++] = MSB_1ST(SDRAM_BASE);   /* 43 */
  obuffer[i++] = MSB_2ND(SDRAM_BASE);   /* 44 */
  obuffer[i++] = MSB_3RD(SDRAM_BASE);   /* 45 */
  obuffer[i++] = MSB_4TH(SDRAM_BASE);   /* 46 */

  if (i != NUM_HEADER_BYTES) {
    fprintf(stderr, "Error: header bytes count = %5d, shd be %5d\n",
	    i, NUM_HEADER_BYTES );
    exit(1);
  }
  fprintf(stderr, "EEPROM Header Size: %5d bytes\n", NUM_HEADER_BYTES);

  return i;
}


int
main(int argc, char **argv)
{
  int            i, j, file_size;
  int            header_bytes;
  FILE          *fp;
  char          *o_file_name, *cp;
  unsigned char ibuffer[BUF_SIZE] = {0};
  unsigned char obuffer[BUF_SIZE] = {0};

  if (argc < 2) {
    fprintf(stderr, "Usage: l1prom file.mi \n");
    exit(1);
  }

  /* find output file name */

  i = strlen(argv[1]);

  /* .eeprom extension needs 7+1 chars */
  o_file_name = (char *)malloc(i+8);
  if (o_file_name == NULL) {
    fprintf(stderr, "unable to malloc\n");
    exit(1);
  }

  /* skip all directory names */

  if ((cp = strrchr(argv[1], '/')) == NULL) {
    cp = argv[1];
  }
  basename(cp, o_file_name);
  i = strlen(o_file_name);
  o_file_name[i++] = '.';
  o_file_name[i++] = 'e';
  o_file_name[i++] = 'e';
  o_file_name[i++] = 'p';
  o_file_name[i++] = 'r';
  o_file_name[i++] = 'o';
  o_file_name[i++] = 'm';
  o_file_name[i++] = '\0';

  if ((fp = fopen(o_file_name, "wb")) == NULL) {
    fprintf(stderr, "Could not open (binary) file %s for write\n",
	    o_file_name);
    exit(1);
  }

  file_size = read_file(ibuffer, argv[1]);

  header_bytes = output_eeprom_header(file_size, obuffer);

  /*
   *  Output 4 bytes at a time.
   *  Swap the byte ordering since boot block expects
   *  words in eeprom to have MSB first and LSB last.
   */

  for (i = header_bytes; i < file_size + header_bytes; i += 4) {
    obuffer[i]   = ibuffer[i+3-header_bytes];
    obuffer[i+1] = ibuffer[i+2-header_bytes];
    obuffer[i+2] = ibuffer[i+1-header_bytes];
    obuffer[i+3] = ibuffer[i-header_bytes];
  }

  j = fwrite(obuffer, sizeof(char), file_size + header_bytes, fp);
  if (j != file_size + header_bytes) {
    fprintf(stderr, "Unable to write %5d bytes. Wrote %5d \n",
	    file_size + header_bytes);
    exit(1);
  }

  close(fp);
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -