dm642loader.c

来自「dm642pci加载代码 DM642 DSP PCI loader, coul」· C语言 代码 · 共 598 行 · 第 1/2 页

C
598
字号
/*DM642 DSP PCI loader, could be reformed to working in a different OS. */

#ifdef VXWORKS
#include "vxWorks.h"  /*for vxworks OS*/
#endif

#include "stdio.h"
#include "dirent.h"

#ifdef VXWORKS
#include "stat.h"
#endif
#ifdef LINUX
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/io.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
#endif

#include "DM642Registers.h"
#include "DM642Types.h"


#define COFF_MAGIC_2 	     0302
#define ISCOFF(x) ((x) == COFF_MAGIC_2)

#define COFF_SECTYPE_TEXT 0x0020
#define COFF_SECTYPE_DATA 0x0040
#define COFF_SECTYPE_BSS 0x0080
#define COFF_SECTYPE_COPY 0x0050

typedef struct _coff_filehdr coff_filehdr;
struct _coff_filehdr {
  UINT16  f_magic;        /* magic number                         */
  UINT16  f_nscns;        /* number of sections                   */
  INT32  f_timdat;       /* time & date stamp                    */
  INT32  f_symptr;       /* file pointer to symtab               */
  INT32  f_nsyms;        /* number of symtab entries             */
  UINT16  f_opthdr;       /* sizeof(optional hdr)                 */
  UINT16  f_flags;        /* flags                                */
  UINT16  f_target_id;    /* target architecture id               */
};

typedef struct _coff_aouthdr coff_aouthdr;
struct _coff_aouthdr {
  INT16  magic;          /* optional file header magic number    */
  INT16  vstamp;         /* version stamp                        */
  INT32  tsize;          /* text size in bytes, padded to FW bdry*/
  INT32  dsize;          /* initialized data "  "                */
  INT32  bsize;          /* uninitialized data "   "             */
  INT32  entrypt;        /* entry pt.                            */
  INT32  text_start;     /* base of text used for this file      */
  INT32  data_start;     /* base of data used for this file      */
};

typedef struct _coff_scnhdr coff_scnhdr;
struct _coff_scnhdr {
  char  s_name[8];      /* old COFF version name fld   */
   INT32  s_paddr;        /* physical address                    */
   INT32  s_vaddr;        /* virtual address                     */
   INT32  s_size;         /* section size                        */
   INT32  s_scnptr;       /* file ptr to raw data for section    */
   INT32  s_relptr;       /* file ptr to relocation              */
   INT32  s_lnnoptr;      /* file ptr to line numbers            */
   UINT32  s_nreloc;       /* number of relocation entries        */
   UINT32  s_nlnno;        /* number of line number entries       */
   UINT32  s_flags;        /* flags                               */
   INT16  s_reserved;     /* reserved 2 bytes                    */
   UINT16  s_page;         /* memory page id                      */
};

UINT32 u32Base1[MAX_DM642_CHIPS] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
static UINT32  base0, base1, base2 = 0;
static UINT8   dsp_irq=0;
static int     DSPP = 0;


#ifdef LINUX
extern int fd642;
extern struct DM642Channel dm642[MAX_DM642_CHIPS];
struct DM642_ioctl oCTL={0,0,0};
#endif



void sysMemOutLong(UINT32 address, UINT32 data)
{
	*((UINT32*)address) = data;
}

void vDspRegWrite32(UINT32 reg, UINT32 value)
{
#ifdef VXWORKS
  UINT32 addr = base1 + (reg-DM642_REG_BASE);
  sysMemOutLong(addr, value);
#endif
#ifdef LINUX
  oCTL.ulRegNum = reg - DM642_REG_BASE;
  oCTL.ulRegData = value;
  ioctl(fd642, DM642_IOCTL_SET_REGISTER, &oCTL);
#endif
}

void vDspEmifInit()
{
    UINT32 EmifA[12] = { 0x00092078UL,        /* GCTL     - 0x01800000*/
                         0xF3A88E02UL,        /* CE1      - 0x01800004*/
                         0xFFFFFFDEUL,        /* CE0      - 0x01800008*/
                         /* Address split 3*/
                         0x22a28a22UL,        /* CE2      - 0x01800010*/
                         0x22a28a42UL,        /* CE3      - 0x01800014*/
                         0x57115000UL,        /* SDRAMCTL - 0x01800018*/
                         0x0000081bUL,        /* SDRAMTIM - 0x0180001c*/
                         0x000a8529UL,        /* SDRAMEXT - 0x01800020*/
                         /* Address split 9*/
                         0x00000002UL,        /* CE1ECCTL - 0x01800044*/
                         0x00000002UL,        /* CE0ECCTL - 0x01800048*/
                         /* Address split */
                         0x00000002UL,        /* CE2ECCTL - 0x01800050*/
                         0x00000073UL,        /* CE3ECCTL - 0x01800054*/
                        };

    vDspRegWrite32(DM642_REG_BASE + 0x00UL, EmifA[0]);
    vDspRegWrite32(DM642_REG_BASE + 0x04UL, EmifA[1]);
    vDspRegWrite32(DM642_REG_BASE + 0x08UL, EmifA[2]);
    vDspRegWrite32(DM642_REG_BASE + 0x10UL, EmifA[3]);
    vDspRegWrite32(DM642_REG_BASE + 0x14UL, EmifA[4]);
    vDspRegWrite32(DM642_REG_BASE + 0x18UL, EmifA[5]);
    vDspRegWrite32(DM642_REG_BASE + 0x1CUL, EmifA[6]);
    vDspRegWrite32(DM642_REG_BASE + 0x20UL, EmifA[7]);
    vDspRegWrite32(DM642_REG_BASE + 0x44UL, EmifA[8]);
    vDspRegWrite32(DM642_REG_BASE + 0x48UL, EmifA[9]);
    vDspRegWrite32(DM642_REG_BASE + 0x50UL, EmifA[10]);
    vDspRegWrite32(DM642_REG_BASE + 0x54UL, EmifA[11]);

}
int iDspPciInit(int index)
{
#ifdef VXWORKS
	int	busNo, devNo, fcnNo=0;
	UINT16	command = 0;

	/* Find DSP PCI device*/
	if(pciFindDevice( 0x104C, 0x9065, index, &busNo, &devNo, &fcnNo) != OK)
		return 0;
	pciConfigInLong (busNo, devNo, fcnNo, 0x10, &base0);
	pciConfigInLong (busNo, devNo, fcnNo, 0x14, &base1);
	pciConfigInLong (busNo, devNo, fcnNo, 0x18, &base2);
	pciConfigInByte (busNo, devNo, fcnNo, 0x3C, &dsp_irq);

	base0 &= 0xFFFFFFF0;
	base1 &= 0xFFFFFFF0;

	u32Base1[index]= base1;

	base2 &= 0xFFF0;
	printf("base0: 0x%0x, base1: 0x%0x, base2: 0x%0x\n", base0, base1, base2);

	/*read and set the PCI commander register to enable the memory access*/
	pciConfigInWord(busNo, devNo, fcnNo, 0x04, &command);
	command |= 0x3;
	pciConfigOutWord(busNo, devNo, fcnNo, 0x04, command);

	return 1;
#endif

#ifdef LINUX
	/* set the device context */
	base0 = (UINT32)dm642[index].poIOTables;
	base1 = (UINT32)dm642[index].pvRegisterIO;
	base2 = (UINT32)dm642[index].pvPortIO;
	oCTL.u642 = index;

	printf("base0: 0x%0x, base1: 0x%0x, base2: 0x%0x\n", base0, base1, base2);

	/* Note! The driver enables memory access when opened (it must
		 happen before we get here) */
#endif

}

UINT32 iDsp2PciAddr(UINT32 addr)
{
	int count = 0;	
	if(addr >= 0x400000) /*memory window range 4M, 0~3FFFFF)*/
	{
		while(addr >= 0x400000)
		{
			addr -= 0x400000;
			count++;
		}
	}
	if(DSPP != count)
	{
		DSPP = count;
		/*printf("iDsp2PciAddr: setting page %d\n", count);*/
		sysOutWord(base2 + DM642_IO_DSPP, DSPP);
	}

	return base0 + addr;
}

void swap2byte(UINT16 *addr) 
{
  UINT16 tmp = *addr;
  UINT16 tmp1, tmp2;
  tmp1 = tmp & 0xff;
  tmp2 = (tmp >> 8) & 0xff;
  *addr = (tmp1 << 8) | (tmp2);
}

void swap4byte(UINT32 *addr) 
{
  UINT32 tmp = *addr;
  UINT32 tmp1, tmp2, tmp3, tmp4;
  tmp1 = tmp & 0xff;
  tmp2 = (tmp >> 8) & 0xff;
  tmp3 = (tmp >> 16) & 0xff;
  tmp4 = (tmp >> 24) & 0xff;
  *addr = (tmp1 << 24) | (tmp2 << 16) | (tmp3 << 8) | (tmp4);
}

void  vDspMemoryWrite(UINT32 address, int size, UINT32 data)
{
  UINT32 pciAddr = 0;

  pciAddr = iDsp2PciAddr(address);
  if (size==1)
    *(unsigned char *)pciAddr = data;
  else
    sysMemOutLong(pciAddr, data);

  /*printf("Write %08xh to %08xh, DSPP: %xh\n", data, pciAddr, sysInWord(base2 + DM642_IO_DSPP));*/
}

/*load coff file into DSP memory, return the entry point address*/
UINT32 ulDspLoad(char *fname) 
{

  int i,j;
  coff_filehdr *fhdr;
  coff_aouthdr *ahdr=0;
  coff_scnhdr *shdr;
  struct stat filestat;
  FILE *fp;
  char *fbuf;
  char *fileptr, *fileptr_saved;
  char byte_swapped = 0;
  UINT32 u32EntryPoint=0;

  /* stat the file and figure out it's size */
  if (stat(fname, &filestat) != 0) 
  {
    printf("unable to open target binary `%s' for getting file size.\n", fname);
    return 0;
  }

  /* open the program for reading */
  fp = fopen(fname, "r");
  
  if (!fp) 
  {
    printf("unable to open target binary `%s' for reading", fname);
    return 0;
  }

  /* about 1k more than reqd is malloced to read file into memory */
/*  fbuf = (char *) malloc((filestat.st_size + 0x200) & ~(0x200));*/
  fbuf = (char *) malloc(filestat.st_size + 0x800);

  /*printf("\nDSP Load: fbuf=%lx\n", (long)fbuf);*/
  
  /* load the program into memory */
  if (fread(fbuf, 1, filestat.st_size, fp) < 1) 
  {
    printf("unable to read from target binary `%s'", fname);
    return 0;
  }

  /* done with the executable, close it */
  if (fclose(fp)) 
  {
    printf("unable to close target binary '%s'", fname);
    return 0;
  }

  printf("target binary '%s' read in %ld bytes\n", fname, filestat.st_size);



  /* start of file ptrs */
  fileptr = fbuf;
  fileptr_saved = fbuf;

  /* goto the file header */
  fhdr = (coff_filehdr *) fileptr;
  fileptr = fileptr + 22;

⌨️ 快捷键说明

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