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

📄 ixdp2400.c

📁 ixp2400 bsp for vxworks
💻 C
字号:
/*ixdp2400.c - npu, master/slave and flashmode identification routines*//*modification history--------------------01a,14jan03,scm  add enum PciBarId here...rev, 1apr02, vgd - creation*/#include "vxWorks.h"#include "config.h"#include "ixdp2400.h"#include "ixdp2400Misc.h"#define QDR2/*global variables*/UINT32 strapOptionsVal = 0;UINT32 sramSize =0;UINT32 ixp2400XtalFreq;UINT32 sramChanSize[4]={0,0,0,0};static UINT32 _period;struct board_config *pBoardCfgData =(struct board_config *)IXP2400_SCRATCH_BASE;struct SPCfg spCfgCpld;/*externs*/extern UINT32 boardRev;/****************************************************************************** * int isNPUMaster(void) - identify whether the code is running on Master NPU or *                         slave NPU *This routine reads the STRAP OPTIONs register and if bit 2 is 1, then the npu  *is master. It returns a value representative of whether or not running on the  *master NPU * * RETURNS:  TRUE if running on master	   		FALSE if running on slave.		 */int isNPUMaster (void){	FAST int locKey;    /* Lock Interrupts */    locKey = intLock();    /*Read STRAP_OPTIONS register*/		IXP2400_REG_READ(IXP2400_STRAP_OPTIONS,strapOptionsVal);	/* UnLock Interrupts */    intUnlock (locKey);	return ( (strapOptionsVal & CFG_PCI_BOOT_HOST) ? TRUE : FALSE); 	}/****************************************************************************** * int isNPUFlashEnabled(void) - identify the flash on the NPU where the code is                                 running has flash or not. *This routine reads the STRAP OPTIONs register and returns a value representative *of whether the nPU's flash is enabled or not. The master NPU flash is always  *enabled, while the slave NPU's flash could be either enabled or disabled * * RETURNS:  TRUE if Flash enabled	   		FALSE if Flash disabled.		 */int isNPUFlashEnabled (void){		 FAST int locKey;    /* Lock Interrupts */    locKey = intLock();    /*Read STRAP_OPTIONS register*/		IXP2400_REG_READ(IXP2400_STRAP_OPTIONS,strapOptionsVal);	 /* UnLock Interrupts */    intUnlock (locKey);	return ( (strapOptionsVal & CFG_PROM_BOOT) ? TRUE : FALSE); 	}/******************************************************************************** *int getProductID (void) - return the product id *This function returns the major product type, minor product type, major revision,  *and minor revision fields. *[31:21] RES Reserved *[20:16] MAJ_PROD_TYPE 0 = IXP2000 others will be assigned as needed  *[15:8] MIN_PROD_TYPE	0 = IXP2800 with Crypto *			1 = IXP2800 *			2 = IXP2400 * *[7:4] MAJ_REV Current Revision. Starts at 0  *[3:0] MIN_REV Current Revision. Starts at 0  *   *Return Value: IDData value  */int getProductID (unsigned int mask){	int	IDData;	FAST int locKey;    /* Lock Interrupts */    locKey = intLock();	/*Read the Product ID register */ 	IDData=((*(volatile unsigned int *)(IXP2400_PROD_ID))&mask);	/* UnLock Interrupts */    intUnlock (locKey);	return(IDData);}/****************************************************************************** * STATUS sysCFGDATAcopy(void ) - copies config data on I2C EEPROM attached to  * master onto to SRAM on the master NPU. * *Return: OK if sucessful	     else ERROR */STATUS sysCFGDATAcopy(void){	int i;	struct EEPROM_CONTENT temp;    FAST int locKey;	if(isNPUMaster())	{	/* read config data and save it*/			i2c_seq_read(0xa2, 0x0, (unsigned char *)&temp, CONFIG_DATA_SIZE);	if(temp.prom_fmt == '0')	{	locKey = intLock ();	for(i = 0; i < CONFIG_DATA_SIZE; i += 4)	{	*((UINT32 *)((UINT32)&(pBoardCfgData->config_data) + i)) = *((UINT32 *)((UINT32)&temp + i)); 	}	intUnlock (locKey);	pBoardCfgData->config_valid = CONFIG_DATA_VALID;	}		}	return OK;}/****************************************************************************** * STATUS ixdp2400SRAMInit(int channel, int skipCsr, int frmPci, int offset )  * Initializes SRAM with max size and the  dynamically sizes it. * *Return: OK if sucessful	     else ERROR */STATUS ixdp2400SRAMInit(int channel, int skipCsr, int frmPci, int offset){	int i;	int j;	int qdrChSize = MIN_SRAM_SIZE;	int qdrChanCsrBase;	int qdrBase;	volatile UINT32 *sramCmpLoc;	volatile UINT32 *sramTstLoc;	int sramDetected =0;			UINT32 sramCsrVal, temp, addr;    FAST int locKey;#ifndef INCLUDE_PCI		qdrChanCsrBase =  IXP2400_QDR_CH_CSR_BASE + (channel * 0x400000);		qdrBase        =  IXP2400_SRAM_CH0_BASE + (channel * 0x10000000);#else	/*calculate the csr base and qdr base*/	if(frmPci)	{		qdrChanCsrBase =  pSlave->bar[CSR_BAR].address + SLAVE_QDR_CH_BASE + (channel * 0x400);		qdrBase		   =  pSlave->bar[SRAM_BAR].address + (channel * 0x10000000);	}	else	{		qdrChanCsrBase =  IXP2400_QDR_CH_CSR_BASE + (channel * 0x400000);		qdrBase        =  IXP2400_SRAM_CH0_BASE + (channel * 0x10000000);	}#endif	/* Init CSRs*/	if(!skipCsr)	{		locKey = intLock ();		/*Program Slew rate tables for normal Rcomp operation*/		/* Rcomp registers are only 4 bytes distant. So, when this function		 * will be called by pci init it won't work properly due to pci bug.		 * Insert dummy read cycle in between write operations		 */		for(addr = 0x340; addr <= 0x3bc; addr+=4)		{			IXP2400_REG_WRITE((qdrChanCsrBase+addr),0xCCCC);	#if A0_REV			IXP2400_REG_READ((qdrChanCsrBase+addr),temp);#endif		}				/*Invert rcomp polarity*/		IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_RCMP_SETUP_CONTROL_OFF), 0x00010060);#ifdef QDR1 		/* Set 50 ohm ref resistor in real board/tester*/		IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_RCOMP_OFF), 0xFFFF3);				/*wait for 1 ms*/		delayUSec(1000);		IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_RX_DLL_OFF),0x48);#else	  /* Set 50 ohm ref resistor in real board/tester*/		IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_RCOMP_OFF), 0x518C3);				/*wait for 1 ms*/		delayUSec(1000);		IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_RX_DLL_OFF),0x52);#endif			IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_RX_DESKEW_OFF),0x12);		/*Set SRAM CSR to use max size*/		IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_CH_CONTROL_OFF),MAX_SRAM_SIZE_CSR_VAL);		/*wait for 3 ms*/		delayUSec(3000);			IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_RD_PTR_OFF), 0x4);		/*read RD_PTR back to ensure write is completed*/		IXP2400_REG_READ((qdrChanCsrBase+IXP2400_QDR_RD_PTR_OFF), temp);        	    intUnlock (locKey);	   	}	if(!frmPci)	{		locKey = intLock ();		for(j=1;j<=5;j++)		{			IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_CH_CONTROL_OFF),(PIPELINE|(j<<7)));									/*wait for 3 ms*/			delayUSec(3000);			/*Now probe for the right size*/			for(i = 0; i < SRAM_SIZE_LOOPS; i++)			{				sramCmpLoc  = (UINT32 *)(qdrBase + qdrChSize);				*sramCmpLoc = 0xAA55AA55;				if(*sramCmpLoc != 0xAA55AA55)				{					break;				}				sramCmpLoc  = (UINT32 *)(qdrBase + offset);				sramTstLoc  = (UINT32 *)(qdrBase + (qdrChSize/2) + offset);				*sramCmpLoc = 0xA5A5A5A5;				*sramTstLoc = 0x55AAAA55;				if(*sramCmpLoc == *sramTstLoc)				{					break;				}				sramDetected = 1;				qdrChSize *= 2;			}		}				if(!sramDetected)		{			qdrChSize = 0;		}				sramChanSize[channel] = qdrChSize;		/*save sram size*/		sramSize += qdrChSize;		temp = 1024 * 1024;		for(i = 0; i < 6; i++)		{			temp = temp * 2;			if(temp == qdrChSize)				break;		}		sramCsrVal = i << 7;		sramCsrVal = sramCsrVal | PIPELINE;		/* init channel 0*/		IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_CH_CONTROL_OFF), sramCsrVal);				intUnlock (locKey);	}	if(!frmPci && qdrChSize )	{				locKey = intLock ();		/*Init whole SRAM with 0x0 so that the parity errors are not generated*/		memset((char *)(qdrBase+offset), 0, (qdrChSize-offset));		if(boardRev >= 3)		{			/*Parity is working only on board rev3 and above*/			*((UINT32*)(qdrChanCsrBase + IXP2400_QDR_CH_CONTROL_OFF)) |= PARITY_ENABLE;		}		intUnlock (locKey);	}	return OK;}void ixp2400Timer1Init(UINT32 period){ 	FAST int locKey;   	_period = period;	locKey = intLock ();	/* load the counter */	*((UINT32 *)IXP2400_TIMER1_LOAD) = period;	/* start the timer */	*((UINT32 *)IXP2400_TIMER1_CONTROL) = (1 << 7);		intUnlock (locKey);}/* Read the current value of the clock, returning the number of hardware * "ticks" that have occurred (i.e. how far away the current value is from * the start)  */void ixp2400Timer1read(UINT32 *pvalue){	FAST int locKey;	locKey = intLock ();	/* read the current counter value */    *pvalue = *((UINT32 *)IXP2400_TIMER1_STATUS);		 intUnlock (locKey);}/* Delay for some usecs. */void delayUSec(UINT32 delay){    UINT32 now, last, diff, ticks, ticks_per_usec;	ticks_per_usec  = ixp2400XtalFreq / 1000000;    ixp2400Timer1read(&last);    diff = ticks = 0;    while (delay > ticks) {	ixp2400Timer1read(&now);	if (now > last)	    diff += ((_period - now) + last);	else	    diff += (last - now);	last = now;	if (diff >= ticks_per_usec) {	    ticks += (diff / ticks_per_usec);	    diff %= ticks_per_usec;	}    }}void getXtalFreq(void){	UINT32 cpld_rev;	UINT32 board_rev;	FAST int locKey;	locKey = intLock ();	cpld_rev = *((volatile UINT32*)(CPLD_REV));  	intUnlock (locKey);		board_rev = (cpld_rev & 0xF0) >> 4;	if(board_rev < 4)	{		ixp2400XtalFreq = IXP2400_DEFAULT_CLK_RATE / 12;	}	else	{		int numerator, denominator;		int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8};		numerator = ((*(volatile UINT32*)(SYS_CLK_M)) & 0xFF)*2;		denominator = denom_array[((*(volatile UINT32*)(SYS_CLK_N)) & 0x7)];		ixp2400XtalFreq = (3125000 * numerator) / denominator;		ixp2400XtalFreq = ixp2400XtalFreq/2;	}}void ixdp2400SPCfgSave(struct SPCfg *slowPortCfg){		FAST int locKey;	locKey = intLock ();	IXP2400_REG_READ(IXP2400_SP_CCR, slowPortCfg->spCCR); 	IXP2400_REG_READ(IXP2400_SP_WTC2, slowPortCfg->spWTC2); 	IXP2400_REG_READ(IXP2400_SP_RTC2, slowPortCfg->spRTC2); 	IXP2400_REG_READ(IXP2400_SP_PCR, slowPortCfg->spPCR); 	IXP2400_REG_READ(IXP2400_SP_ADC, slowPortCfg->spADC);     intUnlock (locKey);}void ixdp2400SPCfgRestore(struct SPCfg *slowPortCfg){	FAST int locKey;	locKey = intLock ();		IXP2400_REG_WRITE(IXP2400_SP_CCR, slowPortCfg->spCCR); 	IXP2400_REG_WRITE(IXP2400_SP_WTC2, slowPortCfg->spWTC2); 	IXP2400_REG_WRITE(IXP2400_SP_RTC2, slowPortCfg->spRTC2); 	IXP2400_REG_WRITE(IXP2400_SP_PCR, slowPortCfg->spPCR); 	IXP2400_REG_WRITE(IXP2400_SP_ADC, slowPortCfg->spADC);	    intUnlock (locKey);}#ifdef _DIAB_TOOL__asm void sync_dcache (){% lab loop_667;! "r0", "r1"    mov r0, #0x70000000    add r1, r0, #0x8800loop_667:    mcr p15, 0, r0, c7, c2, 5    add r0, r0, #32    teq r1, r0    bne loop_667    mcr p15, 0, r0, c7, c6, 0    mrc p15, 0, r1, c2, c0, 0    mov r1, r1    sub pc, pc, #4    mcr p15, 0, r0, c7, c10, 4    mrc p15, 0, r1, c2, c0, 0    mov r1, r1    sub pc, pc, #4    nop}#endifvoid dcacheSync(void){#ifdef _DIAB_TOOL        sync_dcache ();#else    /* The best way to evict a dirty line is by using the          */    /* line allocate operation on non-existent memory.             */        __asm ("mov    r0, #0x70000000;"   /* use upper 256M of SDRAM for cache flush region */        "add    r1, r0, #0x8800;"   /* 32KB cache + 2KB mini cache */        "667: "        "mcr    p15,0,r0,c7,c2,5;"  /* allocate a line    */        "add    r0, r0, #32;"       /* 32 bytes/line      */        "teq    r1, r0;"        "bne    667b;"        "mcr    p15,0,r0,c7,c6,0;"  /* invalidate data cache */        /* cpuwait */        "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */        "mov    r1,r1;"        "sub    pc,pc,#4;"        "mcr    p15,0,r0,c7,c10,4;" /* and drain the write buffer */        /* cpuwait */        "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */        "mov    r1,r1;"        "sub    pc,pc,#4;"        "nop"        :        :        : "r0","r1"      /* Clobber list */        );#endif}void dcacheOn(void){        /* Enable data cahce and MMU by writing 1 to bits 0 and 2*/        __asm ("mrc  p15,0,r1,c7,c10,4;"   /* drain write buffer */        "mrc    p15,0,r1,c1,c0,0;"        "orr    r1,r1,#0x0004;"        "mcr    p15,0,r1,c1,c0,0;"        "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read*/        "mov    r1,r1;"        "sub    pc,pc,#4;"        "mcr    p15,0,r1,c7,c6,0;" /* invalidate data cache*/         );}void dcacheOff(void){        __asm ("mrc  p15,0,r1,c1,c0,0;"        "bic    r1,r1,#0x0004;"        "mcr    p15,0,r1,c1,c0,0;"        "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read*/        "mov    r1,r1;"        "sub    pc,pc,#4;"        "mcr    p15,0,r1,c7,c6,0;" /* invalidate data cache*/        "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read*/        "mov    r1,r1;"        "sub    pc,pc,#4;"        );}#ifdef _DIAB_TOOL__asm void flush_dcache(void){% lab loop_fd1;! "r0", "r1", "r2"    ldr  r0, =0x0    add  r1, r0, #8192loop_fd1:    ldr  r2, [r0], #32    teqs r1, r0    bne  loop_fd1    mcr  p15, 0, r0, c7, c10, 4    mcr  p15, 0, a1, c7, c6, 0    mov  pc, lr}#endifvoid dcacheFlush(void){#ifdef _DIAB_TOOL        flush_dcache();#else        __asm ("ldr    r0,=0x0;"        "add    r1,r0,#8192;"        "1:;"        "ldr    r2,[r0],#32;"        "teqs   r1,r0;"        "bne    01b;"        "mcr    p15,0,r0,c7,c10,4;"        "mcr    p15,0,a1,c7,c6,0;"        "mov    pc,lr;"        );#endif}#ifdef _DIAB_TOOL__asm int cp15_val (void){! "r0"    mrc p15, 0, r0, c1, c0, 0}#endifunsigned int getCP15(void){    unsigned int x = 0;#ifdef _DIAB_TOOL    x = cp15_val();#else    __asm ("mrc p15, 0, %0, c1, c0, 0;" : "=r"(x) :);#endif    return x;}

⌨️ 快捷键说明

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