ixp2400 bsp for vxworks

源代码在线查看: ixdp2400.c

软件大小: 2247 K
上传用户: invill
关键词: vxworks 2400 ixp bsp
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*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 						{							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						{							IXP2400_REG_WRITE((qdrChanCsrBase+IXP2400_QDR_CH_CONTROL_OFF),(PIPELINE|(j														/*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 						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 										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, #0x8800								loop_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				}				#endif								void 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, #8192								loop_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				}				#endif								void 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				}				#endif								unsigned 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;				}							

相关资源