📄 m512_mtd.c
字号:
FLDword *dwNextAddressPtr,
unsigned *dwDOC_PhyAddress,
FLBoolean fResetAll)
{
FLFlash *flash;
FLDword dwWinSize = 0x2000 ;
volatile FLWord wChipId,wChipIdConfirm;
FLByte bIF_CFG ;
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: docWindowBaseAddress Entered.\r\n");
/* if memory range to search for DiskOnChip window is not specified */
/* assume the standard x86 PC architecture where DiskOnChip Plus appears */
/* in a memory range reserved for BIOS expansions */
#ifndef FL_ADD_ADDRESS_0_SUPPORT
if (dwLowAddress == 0x0L)
{
dwLowAddress = M512_DEFAULT_START_ADR;
dwHighAddress = M512_DEFAULT_STOP_ADR;
}
else if (dwHighAddress == 0x0L)
{
dwHighAddress = M512_DEFAULT_STOP_ADR;
}
#endif
/* Initialize socket memory access routine */
flash = flFlashOf(bSocketNo);
/*** Step 1 : Set all possible controllers (ASIC) to RESET MODE ***/
for (bIF_CFG=16;bIF_CFG>=8;bIF_CFG=bIF_CFG-8)
{
#ifndef FL_NO_USE_FUNC
if(M512_setBusType(flash,flBusConfig[bSocketNo],2,bIF_CFG)==FALSE)
{
continue ;
}
#endif /* FL_NO_USE_FUNC */
dwWinSize = M512_DocWindow(flash) ;
if(fResetAll == TRUE)
{
for(*dwNextAddressPtr = dwLowAddress;*dwNextAddressPtr<=dwHighAddress;*dwNextAddressPtr+=dwWinSize)
{
flash->win = (NDOC2window)physicalToPointer(*dwNextAddressPtr,dwWinSize,bSocketNo);
/*** The 1st read from the MDOC_512 is Dummy read ***/
M512_DirectRead8BitReg (flash,M512_NOP_REG) ;
/*** Exit for DPD mode into the last mode (RESET/NORMAL) ***/
M512_deepPowerDownMode (flash,EXIT_DEEP_POWER_DOWN) ;
/*** set controller (ASIC) to RESET MODE ***/
M512_asicSetMode (flash,RESET_MODE) ;
}
}
}
/*** Step 2 : Read chip ID while skipping alias addresses ***/
for(*dwNextAddressPtr = dwLowAddress ;
*dwNextAddressPtr <= dwHighAddress ;
*dwNextAddressPtr += dwWinSize)
{
/*** Step 2 : Read chip ID while skipping alias addresses ***/
for (bIF_CFG=16;bIF_CFG>=8;bIF_CFG=bIF_CFG-8)
{ /*** If this bus configuration is suported reset the FLASH with it ***/
flash->if_cfg = bIF_CFG ;
#ifndef FL_NO_USE_FUNC
if(M512_setBusType(flash,flBusConfig[bSocketNo],2,bIF_CFG)==FALSE)
{
continue ;
}
#endif /* FL_NO_USE_FUNC */
DBG_PRINT_WRN_PRM(FLZONE_MTD,(FLTXT("Looking for G3/P3 MDOC Devices while assuming IF_CFG=%u.\r\n"),(FLWord)bIF_CFG));
flash->win = (NDOC2window)physicalToPointer(*dwNextAddressPtr,dwWinSize,bSocketNo);
/* set controller (ASIC) to NORMAL MODE */
M512_asicSetMode (flash,NORMAL_MODE) ;
/* Read the CHIP_ID */
wChipId = M512_ReadChipID(flash);
wChipIdConfirm = M512_ReadChipID_Confirm(flash) ;
if (((wChipId != M512_CHIP_ID ) ||
(wChipIdConfirm != M512_CHIP_ID_COMPLEMENT) ||
(M512_Read8BitReg(flash,M512_ALIAS_RESOLUTION_REG) == M512_ALIAS_RESOLUTION)) &&
/*** Or MDOC256 chip i.d was found ***/
((wChipId != M256_CHIP_ID ) ||
(wChipIdConfirm != M256_CHIP_ID_COMPLEMENT) ||
(M512_Read8BitReg(flash,M512_ALIAS_RESOLUTION_REG) == M512_ALIAS_RESOLUTION)) &&
/*** Or MDOC_1G chip i.d was found ***/
((wChipId != M1G_CHIP_ID) ||
(wChipIdConfirm != M1G_CHIP_ID) ||
(M512_Read8BitReg(flash,M512_ALIAS_RESOLUTION_REG) == M512_ALIAS_RESOLUTION)))
continue;
#ifndef FL_NO_USE_FUNC
/* Now that we found the controller use the correct if_cfg and interleave */
if(M512_setBusType(flash,flBusConfig[bSocketNo],2,(FLByte)(M512_Find_IF_CFG(flash)))==FALSE)
{
M512_setBusType(flash,flBusConfig[bSocketNo],2,bIF_CFG);
continue;
}
#endif /* FL_NO_USE_FUNC */
/* DiskOnChip found, mark alias resolution register */
M512_Write8BitReg(flash,M512_ALIAS_RESOLUTION_REG,M512_ALIAS_RESOLUTION);
dwLowAddress = *dwNextAddressPtr ; /* save DiskOnChip address */
*dwNextAddressPtr += dwWinSize;
DBG_PRINT_WRN(FLZONE_MTD,"G3/P3 DiskOnChip was FOUND ");
DBG_PRINT_WRN_PRM(FLZONE_MTD,(FLTXT("on address %lx.\r\n"),dwLowAddress));
/*** DOC was found ***/
*dwDOC_PhyAddress = ((unsigned)(dwLowAddress >> 12)) ;
flash->mediaType = M512_G3_TYPE; /* Prevent identification of other devices */
/* Remember the chip id until MTD_VARS will be initialized */
flash->unitsInFirstFloor = wChipId;
/*** Return flOK ***/
return flOK ;
}
}
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: docWindowBaseAddress Exit (NOT FOUND).\r\n");
/* DiskOnChip memory window not found */
*dwDOC_PhyAddress = 0 ;
return flAdapterNotFound ;
}
/************************************************************************
* flRegisterDOCM512SOC *
* *
* The routine searches for DOC and if found it updates the noOfSockets *
* global variable and the socket struct with baseaddress,size,... *
* *
* Parameters: *
* dwLowAddress : Low range of search *
* dwHighAddress: High range of search *
* *
* Returns: *
* FLStatus : 0 on success, otherwise failure *
************************************************************************/
FLStatus flRegisterDOCM512SOC(FLDword dwLowAddress, FLDword dwHighAddress)
{
int serialNo;
FLBoolean fResetAll = TRUE;
FLStatus status ;
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: flRegisterDOCOM512SOC Entered.\r\n");
if( noOfSockets >= SOCKETS )
return flTooManyComponents;
/* Try to register DiskOnChip using */
for(serialNo = 0 ; noOfSockets < SOCKETS ; serialNo++ , noOfSockets++)
{
/*** Step 1 : Get a pointer to the last socket ***/
/*** noOfSockets - Is a global variable that holds the number of ***/
/*** sockets found. ***/
FLSocket * socket = flSocketOf(noOfSockets);
/*** Step 2 : Set the Socket volNo field ***/
/*** Set the socket volNo field to be the current noOfSockets ***/
socket->volNo = noOfSockets;
/*** Step 3 : Set the Socket fields ***/
/*** Set the socket fields by calling to docSocketInit routine ***/
/*** Found in DOCSOC.C and initializes the socket fields which ***/
/*** are not relevant for the MTD ***/
docSocketInit(socket);
/*** Step 4 : Set the Socket.window.baseAddress field ***/
/*** Search for base address of DOC that was not found yet ***/
/*** dwLowAddress recieves the next address to search ***/
status = M512_docWindowBaseAddress (noOfSockets,dwLowAddress,dwHighAddress,
&dwLowAddress,&socket->window.baseAddress,fResetAll) ;
fResetAll = FALSE; /* Don't change to reset mode on the next itteration */
/*** If (socket->window.baseAddress==0 => DOC was not found => return) ***/
/*** else repets STEP 1..5 ***/
if (status) /* DiskOnChip not detected */
break;
/*** Step 5 : Set the Socket.window.size & vol.window.base ***/
/*** Set the socket field to be 8Kbyte ***/
flSetWindowSize(socket,M512_DocWindow(flFlashOf((FLByte)flSocketNoOf(socket)))>>12L); /* The second argument is 4k units => 8K = 2*4 KBytes */
}
/*** In case that no DOC was found ***/
if( serialNo == 0 )
return flAdapterNotFound;
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: flRegisterDOCM512SOC Entered.\r\n");
return flOK;
}
/************************************************************************
***************************** Init functions ***************************
************************************************************************/
/***********************************************************************
* Name: M512_checkAndFixAccessError
* Recover from protection/Sequence error of the current asic state
* machine.
*
* Parameters:
* flashPtr : Pointer identifying drive
*
* Note : In order to exit from protection/sequance error the routine
* forces the flash into reset mode.
* The routine would check that the error status is cleared
*
* Returns:
* flOK - No error accured
* flGeneralFailure - Failed clearing error
* flSequanceError - Sequance error was fixed
* flHWProtection - Protetion error was fixed
***********************************************************************/
static FLStatus M512_checkAndFixAccessError(FLFlash *flashPtr)
{
FLStatus status ;
FLByte bTemp ;
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: checkAndFixAccessError Entered.\r\n");
/*** Check if there really is a violation and remmember it ***/
if (M512_IsProtectionError (flashPtr))
{
DBG_PRINT_ERR(FLZONE_MTD,"M512_checkAndFixAccessError:Protection error occurred.\r\n");
status = flHWProtection;
}
else if (M512_IsSequenceError (flashPtr))
{
DBG_PRINT_ERR(FLZONE_MTD,"M512_checkAndFixAccessError:Sequence error occurred.\r\n");
status = flSequenceError;
}
else
return flOK ;
bTemp = M512_Read8BitReg (flashPtr,M512_FLASH_CONTROL_REG) ;
/*** Remove the WP ***/
bTemp &= ~(M512_FWP_SIGNAL_ACTIVE) ;
/*** set FCE_SIGNAL_ACTIVE ***/
bTemp |= M512_FCE_SIGNAL_ACTIVE ;
M512_Write8BitReg (flashPtr,M512_FLASH_CONTROL_REG,bTemp) ;
/*** Clear either protection error or sequence error ***/
M512_reset_Seq (flashPtr) ;
/*** Check if protection error was removed => if not return error ***/
if(M512_IsSequenceOrProtectionError(flashPtr))
{
DBG_PRINT_ERR(FLZONE_MTD,"checkAndFixAccessError:Can't recover from protection / sequance violation.\r\n");
return flGeneralFailure;
}
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: checkAndFixAccessError Exit.\r\n");
return status;
}
#ifndef FL_NO_USE_FUNC
/************************************************************************
* Name:M512_setBusType *
* *
* Check validity and set the proper memory access routines for MTD. *
* *
* Parameters: *
* volume : Pointer identifying drive *
* dBusConfig : Socket access discriptor *
* bInterleave : Interleave factor (1,2) *
* bIF_CFG : if_cfg state: *
* 8 - 8 bit *
* 16 - 16 bit *
* *
* Returns: *
* TRUE if routines are available and fit the DiskOnChip *
* configuration otherwise FALSE. *
* *
* The variable pointer to busConfig is added TrueFFS private *
* MTD descriptors. *
************************************************************************/
static FLBoolean M512_setBusType(FLFlash *volume,FLDword dBusConfig,FLByte bInterleave,FLByte bIF_CFG)
{
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: setBusType Entered.\r\n");
if (bIF_CFG==16)
dBusConfig |= FL_16BIT_DOC_ACCESS ;
else if (bIF_CFG==8)
dBusConfig |= FL_8BIT_DOC_ACCESS ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -