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 + -
显示快捷键?