📄 sysflash.c
字号:
/* sysFlash.c - BSP Intel Strataflash flash driver *//* * Copyright 2002 - 2006 Wind River Systems, Inc. * * The right to copy, distribute, modify or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. *//*modification history--------------------01d,29aug06,jb3 Fix for WIND00056331 TFFS Building01c,16jul06,??? PPC Dec Timer vxBus complaint01b,30jan04,nrv modified to get it to work with mv550001a,08mar02,gtf new*//*DESCRIPTIONThis library provides NVRAM in flash and general IntelStrataflash driver support. Strataflash driver functions areimplemented as specified in the Strataflash datasheet. Thefunctions testFlashIntel() and testFlashBufferIntel() at theend of this file are provided to illustrate driver usage andalso serve as a test driver.Note that none of the driver functions are protected for simultaneous usage (e.g. with a semaphore) so if this isintended by the user wrapper functions should be implemented.Two types of flash write routines are provided one that usesbuffer mode programming versus one that does not. Whenprogramming large buffers it is suggested that the buffer modewrite routine be used.A comment on the flash functions. Two auxiliary routines,sysMsrMaskBits() and sysMsrSetBits() were required in orderto turn off EE and relocate IP back to 0x0000000 when anyflash command is given to the flash. The reason for this isthe exception vectors are in flash by default (and jump toSDRAM locations) so that SDRAM can support two vxWorks images,one for processor A and one for processor B. When a flashcommand is given, any code or data in the flash devices areno longer readable. Since the exception vectors and bootcode are in the same physical device as the general purposeflash at 0x7c000000, this approach is necessary.Finally, the flash write routines assume that the input datais 32 bit aligned and that a multiple of 32 bits are written.This means that any functions calling the flash write functionsare required to provide programming data to the flash write routines with these restrictions. See sysFlashSet() belowfor an example of how this is done.*/#include <vxWorks.h>#include "config.h"#include "sysFlash.h"#include <cacheLib.h>#include <drv/timer/ppcDecTimer.h>#include <logLib.h>#include <string.h>#include <arch/ppc/vxPpcLib.h>#include <tickLib.h>#include <stdio.h>/* NOR FLASH DRIVER FUNCTIONS */#if FALSE /* This sysFlashGet/sysFlashSet can be used for NVRAM in flash. *//******************************************************************************** sysFlashGet - return data from the simulated NVRAM in Flash.* This is a glue function to the nvRamToFlash.c driver.** RETURNS: OK**/STATUS sysFlashGet ( char *string, int strLen, int offset ) { bcopy((const char *)(NV_RAM_BASE_ADRS+offset),(char *)string,strLen); return OK ; }/******************************************************************************** sysFlashSet - Sets the simulated NVRAM location in flash with the requested data.* This is a glue function to the nvRamToFlash.c driver. Note that it is not* necessary to manage the data across sector boundaries as 1 sector of the 29F040* device is reserved to NVRAM.** RETURNS: OK, or ERROR if unable to program flash.**/UINT8 progBuf[NV_RAM_SIZE] ; STATUS sysFlashSet ( char *string, int strLen, int offset ) { if ( strLen <= 0 ) { logMsg("sysFlashSet: strLen <= 0!\n",1,2,3,4,5,6); return ERROR ; } if ( offset < 0 ) { logMsg("sysFlashSet: offset < 0!\n",1,2,3,4,5,6); return ERROR ; } /* Need a shared memory semaphore here for both sides in case they try to write nvram at the same time. Use the sysBusTas() used for the pci shared memory backplane. Reading at the same time should not be a problem. */ /* check to see if string is already in flash.. */ if ( !bcmp((char *)(NV_RAM_BASE_ADRS+offset),(char*)string,strLen) ) return OK ; /* Save current sector contents */ bcopy((const char *)NV_RAM_BASE_ADRS,(char *)progBuf,sizeof(progBuf)); /* "Program" the temp buffer */ bcopy((const char *)string,(char*)(progBuf+offset),strLen) ; /* Erase sector contents */ if ( sysFlashSectorEraseIntel((char *)NV_RAM_BASE_ADRS) != OK ) { logMsg("sysFlashSet: sysFlashSectorErase failure!\n",1,2,3,4,5,6); return ERROR ; } if ( sysFlashSectorWriteIntel((char *)(NV_RAM_BASE_ADRS),(char*)progBuf,sizeof(progBuf)) != OK ) { logMsg("sysFlashSet: sysFlashSectorWrite failure!\n",1,2,3,4,5,6); return ERROR ; } if ( bcmp((char *)NV_RAM_BASE_ADRS,(char*)progBuf,sizeof(progBuf)) ) { logMsg("sysFlashSet: NVRAM not programmed correctly!\n",1,2,3,4,5,6); return ERROR ; } return OK ; }#endif/******************************************************************************** sysFlashDelay - introduce a small delay.** RETURNS: OK, or ERROR **/void sysFlashDelay(void) { int i; /* need at least a 210 nsec delay..., @ 400MHz or 2.5nsec per cycle*/ /* need 84 counts -> 100 counts */ for ( i=0;i<100;i++ ); }/******************************************************************************** sysFlashReadIdIntel - Read mfgr id and device id from the Strataflash.** RETURNS: OK, or ERROR **/LOCAL UINT32 i28f128found = 0 ;LOCAL UINT32 i28f640found = 0 ;LOCAL UINT32 i28f320found = 0 ;/* chips are hooked up x16 on mv5500, and sectors are 128K */LOCAL UINT32 i28f128SectorSize = INTEL28F128_SECTOR_SZ ;LOCAL UINT32 i28f640SectorSize = INTEL28F640_SECTOR_SZ ;LOCAL UINT32 i28f320SectorSize = INTEL28F320_SECTOR_SZ ;LOCAL UINT32 i28f128NumSectors = INTEL28F128_NUM_SECTORS ;LOCAL UINT32 i28f640NumSectors = INTEL28F640_NUM_SECTORS ;LOCAL UINT32 i28f320NumSectors = INTEL28F320_NUM_SECTORS ;LOCAL UINT32 strataFlashDeviceId = 0 ;LOCAL UINT32 strataFlashNumSectors = 0 ;LOCAL UINT32 strataFlashSectorSize = 0 ;STATUS sysFlashReadIdIntel ( volatile FlashWord *adrs ) { FlashWord mfgrId, deviceId ; adrs->l = 0x00ff00ff ; sysFlashDelay(); adrs->l = 0x00900090 ; mfgrId.l = adrs[0].l ; deviceId.l = adrs[1].l ; switch ( deviceId.l ) { case INTEL28F320_DEVICE_ID: /* 32 Mbit */ if ( deviceId.l == INTEL28F320_DEVICE_ID ) { i28f320found = 1 ; strataFlashDeviceId = deviceId.c[1] ; strataFlashNumSectors = i28f320NumSectors ; strataFlashSectorSize = i28f320SectorSize ;#ifdef FLASH_DEBUG printf("sysFlashReadIdIntel: Intel 28F320 Strataflash found!\n");#endif } break; case INTEL28F640_DEVICE_ID: /* 64 Mbit */ if ( deviceId.l == INTEL28F640_DEVICE_ID ) { i28f640found = 1 ; strataFlashDeviceId = deviceId.c[1] ; strataFlashNumSectors = i28f640NumSectors ; strataFlashSectorSize = i28f640SectorSize ;#ifdef FLASH_DEBUG printf("sysFlashReadIdIntel: Intel 28F640 Strataflash found!\n");#endif } break; case INTEL28F128_DEVICE_ID: /* 128 Mbit */ if ( deviceId.l == INTEL28F128_DEVICE_ID ) { i28f128found = 1 ; strataFlashDeviceId = deviceId.c[1] ; strataFlashNumSectors = i28f128NumSectors ; strataFlashSectorSize = i28f128SectorSize ;#ifdef FLASH_DEBUG printf("sysFlashReadIdIntel: Intel 28F128 Strataflash found!\n");#endif } break; default: printf("sysFlashReadIdIntel: invalid deviceId - 0x%x\n",(unsigned)deviceId.c[1]); adrs->l = 0x00ff00ff ; sysFlashDelay(); return ERROR ; } if ( mfgrId.l != INTEL_MFGR_ID ) { adrs->l = 0x00ff00ff ; sysFlashDelay();#ifdef FLASH_DEBUG printf("sysFlashReadIdIntel: Intel Strataflash not found!\n");#endif return ERROR ; } else if ( strataFlashDeviceId < 0x16 || strataFlashDeviceId > 0x18 ) { adrs->l = 0x00ff00ff ; sysFlashDelay();#ifdef FLASH_DEBUG printf("sysFlashReadIdIntel: Intel Strataflash not found!\n");#endif return ERROR ; } adrs->l = 0x00ff00ff ; sysFlashDelay(); return OK ; }/******************************************************************************** sysFlashBlockLockStatusIntel - retrieve the lock status of the given block.** RETURNS: OK - block locked, or ERROR - block not locked.**/STATUS sysFlashBlockLockStatusIntel ( FlashWord * adrs ) { FlashWord * ptr ; volatile UINT32 temp ; volatile UINT32 s1 ; STATUS status ; temp = (volatile UINT32) adrs ; temp &= ~(INTEL28F128_SECTOR_SZ-1) ; ptr = (FlashWord *)temp ; ptr->l = 0x00980098 ; ptr++ ; ptr++ ; s1 = ptr->l ; /* ? find correct location of lock bit in x32 mode */#if FLASH_DEBUG printf("lock status: s1 - 0x%8.8x\n", s1);#endif /* return chips to read mode */ ptr->l = 0x00ff00ff ; sysFlashDelay() ; if ( s1&0x00010001 ) status = OK ; else status = ERROR ; return status ; }/******************************************************************************** checkStatusIntel - check the status word from flash.** RETURNS: OK, or ERROR **/int checkStatusIntel ( UINT32 status1 ) { if ( status1&0x00200000 || status1&0x00000020 ) { printf("sysFlashPollDataIntel: block erase error.\n"); return -1 ; } if ( status1&0x00080000 || status1&0x00000008 ) /* Vpp low */ { printf("sysFlashPollDataIntel Vpp low.\n"); return -1 ; } if ( status1&0x00020000 || status1&0x00000002 ) /* block lock bit detected */ { printf("sysFlashPollDataIntel: block lock bit detected.\n"); return -1 ; } if ( !(status1&0x00040004) ) /* program completed */ return 0 ; else return 1 ; }/******************************************************************************** sysFlashPollDataIntel - poll the flash status register for completion.** RETURNS: OK, or ERROR **/STATUS sysFlashPollDataIntel ( FlashWord * adrs ) { FlashWord * ptr = adrs ; UINT32 s1 ; int status ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -