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

📄 dsploader.c

📁 vxWorks下通过PCI加载DM642的程序源码。对于使用PPC+DM642方案的开发人员是一个很好的参考。
💻 C
字号:
/*DM642 DSP PCI loader, could be reformed to working in a different OS. Tao Chen, Oct 18, 2004*/

#include "vxWorks.h"  /*for vxworks OS*/
#include "config.h"   /*for pentium platform*/

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


#define IRAM_BASE            0x00000000
#define SDRAM_BASE           0x80000000
#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                      */
};

static UINT32  base0, base1, base2=0;
static int 	DSPP = 0;
void sysMemOutLong(UINT32 address, UINT32 data)
{
	*((UINT32*)address) = data;
}

vDspRegWrite32(UINT32 reg, UINT32 value)
{
	UINT32 addr = base1+(reg-0x01800000UL);
	sysMemOutLong(addr, value);
}
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(0x01800000UL, EmifA[0]);
    vDspRegWrite32(0x01800004UL, EmifA[1]);
    vDspRegWrite32(0x01800008UL, EmifA[2]);


    vDspRegWrite32( 0x01800010UL, EmifA[3]  );
    vDspRegWrite32( 0x01800014UL, EmifA[4]  );
    vDspRegWrite32( 0x01800018UL, EmifA[5]  );
    vDspRegWrite32( 0x0180001CUL, EmifA[6]  );
    vDspRegWrite32( 0x01800020UL, EmifA[7]  );

    vDspRegWrite32( 0x01800044UL, EmifA[8]  );
    vDspRegWrite32( 0x01800048UL, EmifA[9]  );

    vDspRegWrite32( 0x01800050UL, EmifA[10] );
    vDspRegWrite32( 0x01800054UL, EmifA[11] );

}
int iDspPciInit()
{
	int	busNo, devNo, fcnNo=0;
	UINT16	command = 0;
	/* Find DSP PCI device*/
	if(pciFindDevice( 0x104C, 0x9065, 0, &busNo, &devNo, &fcnNo) != OK)
		return 0;
	pciConfigInLong (busNo, devNo, fcnNo, PCI_CFG_BASE_ADDRESS_0, &base0);
	pciConfigInLong (busNo, devNo, fcnNo, PCI_CFG_BASE_ADDRESS_1, &base1);
	pciConfigInLong (busNo, devNo, fcnNo, PCI_CFG_BASE_ADDRESS_2, &base2);
	base0 &= 0xFFFFFFF0;
	base1 &= 0xFFFFFFF0;
	base2 &= 0xFFF0;
	/*read and set the PCI commander register to enable the memory access*/
	pciConfigInWord(busNo, devNo, fcnNo, PCI_CFG_COMMAND, &command);
	command |= 0x3;
	pciConfigOutWord(busNo, devNo, fcnNo, PCI_CFG_COMMAND, command);
	printf("DSP PCI commmand register: 0x%0x\n", command);

	command = 0;
	pciConfigInWord(busNo, devNo, fcnNo, PCI_CFG_COMMAND, &command);
	printf("base0: 0x%0x, base1: 0x%0x, base2: 0x%0x\n", base0, base1, base2);
	return 1;

}

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;
		sysOutWord(base2+0x08, 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;
	UINT8 byte, count, shift=0;

	pciAddr = iDsp2PciAddr(address);
	sysMemOutLong(pciAddr, data);
	/*printf("Write %08xh to %08xh, DSPP: %xh\n", data, pciAddr, sysInWord(base2+0x8));*/

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

  int i,j;
  coff_filehdr *fhdr;
  coff_aouthdr *ahdr;
  coff_scnhdr *shdr;
  struct stat filestat;
  FILE *fp;
  char *fbuf;
  char *fileptr, *fileptr_saved;
  char byte_swapped = 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));
  
  /* 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;

  /* check magic number */
  if (!ISCOFF(fhdr->f_magic))
  {
      swap2byte(&(fhdr->f_magic));
      if (!ISCOFF(fhdr->f_magic)) 
      {
	printf("bad magic number %d in target binary `%s' (not an executable)",
		fhdr->f_magic, fname);
	return 0;
      }
      byte_swapped = 1;
      /* swap the rest of the header */
      swap2byte(&(fhdr->f_nscns));
      swap4byte(&(fhdr->f_timdat));
      swap4byte(&(fhdr->f_symptr));
      swap4byte(&(fhdr->f_nsyms));
      swap2byte(&(fhdr->f_opthdr));
      swap2byte(&(fhdr->f_flags));
      swap2byte(&(fhdr->f_target_id));
  }

  /* goto aout header */
  ahdr = (coff_aouthdr *) fileptr;
  fileptr = fileptr + sizeof(coff_aouthdr);
  
  /* swap bytes in the aouthdr if necessary */
  if (byte_swapped == 1) 
  {
    swap2byte(&(ahdr->magic));
    swap2byte(&(ahdr->vstamp));
    swap4byte(&(ahdr->tsize));
    swap4byte(&(ahdr->dsize));
    swap4byte(&(ahdr->bsize));
    swap4byte(&(ahdr->entrypt));
    swap4byte(&(ahdr->text_start));
    swap4byte(&(ahdr->data_start));
  }
  
  printf("processing %d sections\n", fhdr->f_nscns);
  
  /* loop through the section headers and then the sections */
  fileptr_saved = fileptr;
  for (i = 0; i < fhdr->f_nscns; i++)
  {
      fileptr = fileptr_saved;
      shdr = (coff_scnhdr *) fileptr;
      fileptr += sizeof(coff_scnhdr);
      fileptr_saved = fileptr;
      
      /* swap bytes in the scnhdr if necessary, except s_name */
      if (byte_swapped == 1) 
      {
	swap4byte(&(shdr->s_paddr));
	swap4byte(&(shdr->s_vaddr));
	swap4byte(&(shdr->s_size));
	swap4byte(&(shdr->s_scnptr));
	swap4byte(&(shdr->s_relptr));
	swap4byte(&(shdr->s_lnnoptr));
	swap4byte(&(shdr->s_nreloc));
	swap4byte(&(shdr->s_nlnno));
	swap4byte(&(shdr->s_flags));
	swap2byte(&(shdr->s_reserved));
	swap2byte(&(shdr->s_page));
      }


      /*printf("%8s %8u %8x %8x %8x %8x\n", shdr->s_name, shdr->s_size, 
            shdr->s_paddr, shdr->s_vaddr, shdr->s_scnptr, shdr->s_flags);*/

      if (shdr->s_flags == COFF_SECTYPE_COPY) /*skip copy section?*/
      {
	 printf("copy section '%s', flag: 0x%xh, ignored\n", shdr->s_name,  shdr->s_flags);

      }
      else if (shdr->s_flags & COFF_SECTYPE_TEXT) /*load text section*/
      {
	
	 printf("text section '%s', flag: 0x%xh, starting at 0x%08x with %d bytes\n", shdr->s_name,  shdr->s_flags, shdr->s_vaddr, shdr->s_size);
	 fileptr = fbuf + shdr->s_scnptr;
	 for (j = 0; j < shdr->s_size; j+=4) 
         {
	   UINT8 a, b, c, d;
	   UINT32 data;
	   a = *(fileptr+j);
	   b = *(fileptr+j+1);
	   c = *(fileptr+j+2);
	   d = *(fileptr+j+3);
	   data = (d << 24) | (c << 16) | (b << 8) | (a);
	   vDspMemoryWrite(shdr->s_vaddr + j, 4, data);
	 }
      } 
      else if (shdr->s_flags & COFF_SECTYPE_DATA) /*load data section*/
      {

	if (shdr->s_size > 0) 
        {
	  printf("data section '%s', flag: 0x%xh, starting at 0x%08x with %d bytes\n", shdr->s_name, shdr->s_flags, shdr->s_vaddr, shdr->s_size);
	  fileptr = fbuf + shdr->s_scnptr;
	  for (j = 0; j < shdr->s_size; j+=4) 
          {
	    UINT8 a, b, c, d;
	    UINT32 data;
	    a = *(fileptr+j);
	    b = *(fileptr+j+1);
	    c = *(fileptr+j+2);
	    d = *(fileptr+j+3);
	    data = (d << 24) | (c << 16) | (b << 8) | (a);
	    vDspMemoryWrite(shdr->s_vaddr + j, 4, data);
	  }
	}
	else
	  printf("section '%s' size equal to zero\n", shdr->s_name);

      } 
      else if (shdr->s_flags & COFF_SECTYPE_BSS) /*skip bss section*/
      {
	if (shdr->s_size > 0) 
        {
	  printf("bss section '%s' starting at 0x%08x with %d bytes, ignored\n", shdr->s_name, shdr->s_vaddr, shdr->s_size);
	  fileptr = fbuf + shdr->s_scnptr;
	  for (j = 0; j < shdr->s_size; j+=4) 
          {
	    UINT8 a, b, c, d;
	    UINT32 data;
	    a = *(fileptr+j);
	    b = *(fileptr+j+1);
	    c = *(fileptr+j+2);
	    d = *(fileptr+j+3);
	    data = (d << 24) | (c << 16) | (b << 8) | (a);
	    vDspMemoryWrite(shdr->s_vaddr + j, 4, data);
	  }
	}
	else
	  printf("section '%s' size equal to zero\n", shdr->s_name);

      }
      else 
      {
	 printf("unknown section `%s', flag: 0x%xh, ignored\n", shdr->s_name, shdr->s_flags);
      }
	
    }
  
  free(fbuf);
  fclose(fp);
  return(ahdr->entrypt);

}
/*warm reset the DSP*/
void vDspReset()
{
	int i=0;
	sysOutByte(base2+0x4, 0x1);
	for(i=0; i<10000; i++)
	{
		/*wait 18 DSP cycle to get response*/
	}
}
/*send DSPINT to start the execution*/
void vDspStart()
{
	sysOutByte(base2+0x4, 0x2);
	printf("DSP started!\n");
}
/*load the coff to dsp and get it running, filename: a coff filename (.out)*/
int iDspLoad(char* filename)
{
	char buf = 0;
	if(!iDspPciInit())
	{
		printf("Can't find the DSP PCI device\n");
		return 0;
	}
	
	/*warm reset the dsp*/
	vDspReset();

	/*init the EMIF, and clear 4M EMIF space to zero*/
	vDspEmifInit();
	sysOutWord(base2+0x8, 0x200);
	memset(base0, 0, 0x400000);

	/*set DSP page register to 0 and clear 256K IRAM space to zero*/
	DSPP = 0;
	sysOutWord(base2+0x08, DSPP);
	memset(base0, 0, 0x40000);

	/*check the pci boot mode*/
	buf = sysInByte(base2+0x04);
	if(!(buf&0x4))
	{
		printf("Not in PCI boot mode\n");
		return 0;
	}

	/*load .out file to DSP memory*/
	ulDspLoad(filename);
	/*start dsp*/
	vDspStart();
	return 1;
}

⌨️ 快捷键说明

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