2604 lines
105 KiB
C
2604 lines
105 KiB
C
/*
|
|
* $Log: V:/Flite/archives/TrueFFS5/Src/DOCBDK.C_V $
|
|
*
|
|
* Rev 1.32 Apr 15 2002 20:14:30 oris
|
|
* Bug fix - No longer ignore the last binary block of high capacity (512MB and up) INFTL formatted device. This bug caused the placeExbByBuffer routine to fail.
|
|
* Bug fix - Physical size of INFTL formatted binary partition was 1 unit smaller then the real size.
|
|
*
|
|
* Rev 1.31 Apr 15 2002 07:35:38 oris
|
|
* Bug fix - bdkErase routine did not made sure not to erase OTP and DPS
|
|
* units of floors > 0.
|
|
*
|
|
* Rev 1.30 Feb 19 2002 20:58:44 oris
|
|
* Changed debug print.
|
|
* Bug fix - binary partition physical length was not reported properly , due to bad casting.
|
|
*
|
|
* Rev 1.29 Jan 20 2002 11:09:42 oris
|
|
* Added debug print.
|
|
*
|
|
* Rev 1.28 Jan 17 2002 22:58:56 oris
|
|
* Force calling bdkInit if not called.
|
|
* Moved declaration of internal variables to mtdsa.c
|
|
* Bug fix NO_INFTL_FAMILY_SUPPORT and NO_NFTL_FAMILY_SUPPORT where changed to NO_INFTL_SUPPORT and NO_INFTL_SUPPORT to comply with header file.
|
|
* Prevent creating binary partition with signature 0xffff ffff
|
|
* bdkInit uses tffsset instead of zeroing all the structure fields.
|
|
* Bug fix - retrieveHeader routine used a word variable instead of dword.
|
|
* freePointer call uses DOC_WIN_SIZE instead of DOC_WIN (part of new docsys ,mechanism).
|
|
* BDK now take socket and flash records using flSocketOf() and flFlashOf(). The records themselves are defined in mtdsa.c
|
|
* Use PROTECTABLE definition instead of 1 in calls to protectionSet.
|
|
* Added support for flVerifyWrite runtime variable for binary partitions
|
|
*
|
|
* Rev 1.27 Nov 16 2001 00:19:48 oris
|
|
* Bug fix - TrueFFS with verify write calling erase and then update block without erase flag, will fail.
|
|
*
|
|
* Rev 1.26 Nov 08 2001 10:45:04 oris
|
|
* Removed warnings.
|
|
* Bug fix - DiskOnChip with different number of blocks in the last floor.
|
|
*
|
|
* Rev 1.25 Oct 18 2001 22:17:02 oris
|
|
* Bug fix - Missing support for binary partiiton on M+ that spans over a single floor.
|
|
*
|
|
* Rev 1.24 Oct 10 2001 19:48:14 oris
|
|
* Bug fix - missing return statment caused the bdkGetProtectionType routine to call bdkSetProtectionType and therfore return a failing status.
|
|
*
|
|
* Rev 1.23 Sep 25 2001 17:37:00 oris
|
|
* Bug fix - bdkIdentifyProtection routine did not update after change protection call.
|
|
*
|
|
* Rev 1.22 Sep 15 2001 23:45:04 oris
|
|
* Bug fix - Changeable protection type was reported by the MTD even if user did not ask for it.
|
|
* Bug fix - Big endian casting caused wrong protection type to be returned.
|
|
*
|
|
* Rev 1.21 Jul 13 2001 01:00:48 oris
|
|
* Bug fix - when skipping bad blocks we no longer mark the bad block with the signature.
|
|
* Send default key before any protection change operation.
|
|
*
|
|
* Rev 1.20 May 30 2001 21:10:22 oris
|
|
* Bug fix - meida header was converted from little indien twice therefore suppling wrong data.
|
|
*
|
|
* Rev 1.19 May 17 2001 21:17:50 oris
|
|
* Improoved documentation of error codes.
|
|
*
|
|
* Rev 1.18 May 17 2001 16:51:08 oris
|
|
* Removed warnings.
|
|
*
|
|
* Rev 1.17 May 16 2001 21:17:04 oris
|
|
* Bug fix - One of the "ifndef" statement of NO_DOCPLUS_FAMILY_SUPPORT was coded as "ifdef".
|
|
* Bug fix - bdkEraseBootArea routine.
|
|
* Changed bdkCopyBootAreaFile and bdkUpdateBootAreaFile interface. The signature is not an unsigned char pointer and not signed.
|
|
* Removed warnings.
|
|
* Added arguments check in bdkSetProtectionType routine and forced the presence of PROTECTABLE flag.
|
|
* Compilation problems for MTD_STANDALONE were fixed.
|
|
* Changed DATA definition to FL_DATA.
|
|
*
|
|
* Rev 1.16 May 09 2001 00:32:02 oris
|
|
* Removed the DOC2000_FAMILY and DOCPLUS_FAMILY defintion and replaced it with NO_DOC2000_FAMILY_SUPPORT, NO_DOCPLUS_FAMILY_SUPPORT, NO_NFTL_SUPPORT and NO_INFTL_SUPPORT.
|
|
* Bug fix - bdkEraseBootArea did not erase more then a single unit.
|
|
* Bug fix - protection routine did not support floors properly.
|
|
* Added OTP and unique ID routines for Millennium Plus .
|
|
*
|
|
* Rev 1.15 May 06 2001 22:41:42 oris
|
|
* Removed warnings.
|
|
*
|
|
* Rev 1.14 May 02 2001 06:43:56 oris
|
|
* Bug fix - bdkRetrieveHeader routine with cascaded floors.
|
|
*
|
|
* Rev 1.13 May 01 2001 14:23:28 oris
|
|
* Removed warrnings.
|
|
*
|
|
* Rev 1.12 Apr 30 2001 17:59:04 oris
|
|
* Removed misleading debug massage when calling bdkCheckSignOffset.
|
|
* Reviced bdkRetrieveHeader routine not to use the MTD readBBT routine.
|
|
* Added initialization of the erasbleBlockSizeBits variable in order to simplify multiplications.
|
|
* Changed bdkSetBootPartitonNo, bdkGetProtectionType, bdkSetProtection prototypes.
|
|
* Bug fix - bdkGetPartitionType routine. Missing case caused type to be 0 at all times.
|
|
*
|
|
* Rev 1.11 Apr 16 2001 13:30:54 oris
|
|
* Bug fix - bad comparison with bdk flag.
|
|
* Bug fix - proection prevented read binary area since the dps were read protected.
|
|
* Removed warrnings.
|
|
*
|
|
* Rev 1.10 Apr 12 2001 06:49:50 oris
|
|
* Added forceDownload routine
|
|
* Changed checkWinForDoc routine to be under ifndef MTD_STANDALONE.
|
|
*
|
|
* Rev 1.9 Apr 10 2001 16:40:56 oris
|
|
* bug fixed for big_endien in bdkmount routine.
|
|
*
|
|
* Rev 1.8 Apr 09 2001 14:59:24 oris
|
|
* Bug fix in retreave header routine - header was searched on the first floor only.
|
|
* End with an empty line.
|
|
*
|
|
* Rev 1.7 Apr 01 2001 07:50:18 oris
|
|
* Updated copywrite notice.
|
|
* Removed nested comments.
|
|
* Removed static type from bdkVol for placinf exb file and standlone applications.
|
|
* Changed readBBT function call since prototype was changed.
|
|
* Bug fix in bdkretreave header routine - added casting to bbt pointer and iUnit.
|
|
* Fix for Big endien compilation problems.
|
|
* Remove unneeded variables.
|
|
* Bad spelling of "..changable..".
|
|
* Changed h\w to h/w.
|
|
* Changed 2400 family to doc plus family.
|
|
* Adde casting in calls to protection routine.
|
|
*
|
|
* Rev 1.6 Feb 20 2001 15:55:28 oris
|
|
* Bug fix - global partiton and socket variables were redaclared in bdcall routine.
|
|
*
|
|
* Rev 1.5 Feb 14 2001 02:36:44 oris
|
|
* Changed FLFlash and FLScoket records (used for the BDK) from static to global for the putImage utility.
|
|
*
|
|
* Rev 1.4 Feb 13 2001 01:41:50 oris
|
|
* bdkPartitionInfo returns the number of binary partitions in flags field of the bdkStruct and not irFlags
|
|
*
|
|
* Rev 1.3 Feb 07 2001 18:15:24 oris
|
|
* Changed else in bdkRetreaveHeader routine otherwise would not compiling bdk with a single doc family.
|
|
* Changed the socketTable and mtdTable so BDK package can compile.
|
|
*
|
|
* Rev 1.2 Feb 05 2001 20:46:30 oris
|
|
* Read the changable protection flag in protectionChangeInit routine
|
|
* from the media header and not from the MTD.
|
|
*
|
|
* Rev 1.1 Feb 05 2001 20:10:56 oris
|
|
* Removed // comments and added missing ;
|
|
*
|
|
* Rev 1.0 Feb 02 2001 13:19:44 oris
|
|
* Initial revision.
|
|
*
|
|
*/
|
|
|
|
/***********************************************************************************/
|
|
/* M-Systems Confidential */
|
|
/* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001 */
|
|
/* All Rights Reserved */
|
|
/***********************************************************************************/
|
|
/* NOTICE OF M-SYSTEMS OEM */
|
|
/* SOFTWARE LICENSE AGREEMENT */
|
|
/* */
|
|
/* THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE */
|
|
/* AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT */
|
|
/* FOR THE SPECIFIC TERMS AND CONDITIONS OF USE, */
|
|
/* OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE: */
|
|
/* E-MAIL = info@m-sys.com */
|
|
/***********************************************************************************/
|
|
|
|
/************************************************/
|
|
/* B i n a r y D e v e l o p m e n t K i t */
|
|
/* ------------------------------------------- */
|
|
/************************************************/
|
|
|
|
/*****************************************************************************
|
|
* File Header *
|
|
* ----------- *
|
|
* Name : docbdk.c *
|
|
* *
|
|
* Description : This file contains the binary partition handling routines. *
|
|
* *
|
|
* Note : The file has 2 interfaces each under its own compilation flag: *
|
|
* *
|
|
* BDK package - Standalone package that exports routines for binary *
|
|
* partitions handling(MTD_STANDALONE compilation flag). *
|
|
* OSAK module - Separated module of the OSAK package that exports a *
|
|
* common entry point to the same routines. (BDK_ACCESS *
|
|
* compilation flag). *
|
|
* *
|
|
* Warning : Do not use this file with the BDK_ACCESS compilation flag unless *
|
|
* you own the full OSAK package. *
|
|
*****************************************************************************/
|
|
|
|
#include "docbdk.h"
|
|
#ifndef MTD_STANDALONE
|
|
#include "doc2exb.h"
|
|
#include "blockdev.h"
|
|
#endif /* MTD_STANDALONE */
|
|
|
|
#if (defined(MTD_STANDALONE) && defined(ACCESS_BDK_IMAGE)) || defined(BDK_ACCESS)
|
|
|
|
/*********************** Global Variables Start******************************/
|
|
|
|
/* conversion table from OSAK handles to binary partition handles */
|
|
static byte handleTable[SOCKETS][MAX_BINARY_PARTITIONS_PER_DRIVE];
|
|
static byte noOfPartitions=0; /* number of mounted binary partition */
|
|
static byte globalPartitionNo=0; /* The current partition number */
|
|
static byte globalSocketNo = 0;
|
|
BDKVol bdkVols[BINARY_PARTITIONS]; /* binary partitions records */
|
|
BDKVol* bdkVol=bdkVols; /* pointer to current binary partition */
|
|
#ifdef MTD_STANDALONE
|
|
FLBoolean globalInitStatus = FALSE;
|
|
#endif /* MTD_STANDALONE */
|
|
/*********************** Internal Function Protoype *************************/
|
|
|
|
static FLStatus bdkMount (void);
|
|
static FLStatus getBootAreaInfo (word startUnit , byte FAR2* signature);
|
|
static CardAddress getPhysAddressOfUnit(word startUnit);
|
|
|
|
/*--------------------------------------------------------------------------*
|
|
* b d k I n i t
|
|
*
|
|
* Initialize all binary partition global variables
|
|
*
|
|
* Note : This function is called automaticly by bdkFindDiskOnChip.
|
|
*
|
|
* Parameters: None
|
|
*
|
|
* global variable output:
|
|
* bdkVols - initialized array of binary partitions records
|
|
* bdkVol - current binary partition record set to the first
|
|
*
|
|
* Return: Nothing
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void bdkInit(void)
|
|
{
|
|
byte index;
|
|
|
|
/* initialize binary partitions records with defaultive values */
|
|
|
|
tffsset(bdkVols,0,sizeof(bdkVols));
|
|
tffsset(handleTable,BDK_INVALID_VOLUME_HANDLE,sizeof(handleTable));
|
|
|
|
for (bdkVol=bdkVols,index=0;index<BINARY_PARTITIONS;bdkVol++,index++)
|
|
{
|
|
bdkVol->bdkGlobalStatus = BDK_S_INIT;
|
|
bdkVol->bdkSignOffset = BDK_SIGN_OFFSET;
|
|
#ifdef EDC_MODE
|
|
bdkVol->bdkEDC = EDC;
|
|
#endif /* EDC_MODE */
|
|
#ifdef UPDATE_BDK_IMAGE
|
|
bdkVol->updateImageFlag = BDK_COMPLETE_IMAGE_UPDATE;
|
|
#endif /* UPDATE_BDK_IMAGE */
|
|
}
|
|
|
|
/* Initialize binary handles conversion table with invalid values */
|
|
#ifdef MTD_STANDALONE
|
|
noOfMTDs = 0;
|
|
globalPartitionNo=0;
|
|
globalSocketNo = 0;
|
|
globalInitStatus = TRUE;
|
|
#endif /* MTD_STANDALONE */
|
|
noOfPartitions=0;
|
|
bdkVol=bdkVols;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*
|
|
* g e t P h y s A d d r e s s O f U n i t
|
|
*
|
|
* Return the physical address of a unit according to its number
|
|
* in the binary sub partition.
|
|
*
|
|
* Note : The sub partition is assumed to be mounted (BDK_S_INFO_FOUND is on).
|
|
*
|
|
* Parameters :
|
|
* startUnit : unit number in the binary sub partition.
|
|
*
|
|
* global variable input:
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* signBuffer - the sub partition signature
|
|
* bdkSignOffset - current signature offset
|
|
* erasableBlockBits - number of bits representing a unit
|
|
*
|
|
* Return :
|
|
* Physical address of the unit in the BDK partition or 0 if failed
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
static CardAddress getPhysAddressOfUnit(word startUnit)
|
|
{
|
|
word iBlock;
|
|
byte signRead[BDK_SIGNATURE_NAME];
|
|
FLFlash * flash=bdkVol->flash;
|
|
FLStatus status;
|
|
|
|
for(iBlock=bdkVol->startImageBlock;
|
|
((startUnit > 0) && (iBlock <= bdkVol->endImageBlock));iBlock++)
|
|
{
|
|
if ((dword)(iBlock % bdkVol->blockPerFloor) < bdkVol->flash->firstUsableBlock)
|
|
{
|
|
iBlock = (word)(iBlock + bdkVol->flash->firstUsableBlock);
|
|
if (iBlock > bdkVol->endImageBlock)
|
|
break;
|
|
}
|
|
status = flash->read( flash , bdkVol->bdkSignOffset +
|
|
((CardAddress)iBlock << bdkVol->erasableBlockBits) ,
|
|
signRead , BDK_SIGNATURE_NAME , EXTRA);
|
|
if(status!=flOK)
|
|
{
|
|
DEBUG_PRINT(("(EXTRA)read failed.\r\n"));
|
|
return 0L;
|
|
}
|
|
|
|
if(tffscmp((void FAR1*)signRead,(void FAR1*)(bdkVol->signBuffer),BDK_SIGNATURE_NAME)==0)
|
|
startUnit--;
|
|
}
|
|
return( (CardAddress)iBlock << bdkVol->erasableBlockBits );
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*
|
|
* g e t B o o t A r e a I n f o
|
|
*
|
|
* Mount the binary sub partitions by reading the signature area of each
|
|
* unit of the entire partition.
|
|
*
|
|
* Note : Assume that the DiskOnChip was already found (bdkFoundDiskOnChip).
|
|
*
|
|
* Parameters :
|
|
* startUnit : unit number in the binary sub partition.
|
|
* signature : signature of the binary sub partition.
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* bdkGlobalStatus - partition predsent status.
|
|
* bdkSavedStartUnit - start unit of previous access
|
|
* bdkSavedSignOffset - signature offset of previous access
|
|
* bdkSignOffset - current signature offset
|
|
* bdkDocWindow - explicitly sets the windows address
|
|
*
|
|
* global variable output :
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* signBuffer - initialize with given signature
|
|
* bdkSavedStartUnit - save start unit for next access
|
|
* bdkSavedSignOffset - save current signature for next access
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW read protection was triggerd
|
|
* flFeatureNotSupported - Not a DiskOnChip device.
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
static FLStatus getBootAreaInfo( word startUnit , byte FAR2* signature )
|
|
{
|
|
FLFlash * flash;
|
|
word iBlock;
|
|
word numBlock;
|
|
#ifdef MTD_STANDALONE
|
|
dword temp;
|
|
|
|
checkStatus(bdkFindDiskOnChip((dword FAR2 *)&temp,(dword FAR2 *)&temp));
|
|
DEBUG_PRINT(("Debug: getBootAreaInfo() - DiskOnChip found.\r\n"));
|
|
#endif /* MTD_STANDALONE */
|
|
|
|
/* set bdkVol pointer to the proper binary partition */
|
|
|
|
checkStatus(bdkMount());
|
|
DEBUG_PRINT(("Debug: getBootAreaInfo() - BDK mount succeed.\r\n"));
|
|
/* Check if this sub-partition was already analized */
|
|
|
|
if ((!(bdkVol->bdkGlobalStatus & BDK_S_INFO_FOUND)) ||
|
|
(tffscmp((void FAR1 *)(bdkVol->signBuffer),
|
|
(void FAR1 *)signature,BDK_SIGNATURE_NAME) != 0) ||
|
|
(bdkVol->bdkSignOffset!=bdkVol->bdkSavedSignOffset) ||
|
|
(startUnit<bdkVol->bdkSavedStartUnit) ||
|
|
(bdkVol->bdkSavedStartUnit + (bdkVol->realBootImageSize >>
|
|
bdkVol->erasableBlockBits)<= startUnit))
|
|
{
|
|
|
|
/* The partition needs mounting */
|
|
|
|
tffscpy((void FAR1 *)(bdkVol->signBuffer),(void FAR1 *)signature,
|
|
BDK_SIGNATURE_NAME);
|
|
bdkVol->bdkSavedSignOffset = bdkVol->bdkSignOffset;
|
|
bdkVol->bdkSavedStartUnit = startUnit;
|
|
|
|
bdkVol->startImageBlock = 0;
|
|
bdkVol->bootImageSize = 0L;
|
|
bdkVol->realBootImageSize = 0L;
|
|
|
|
/* Find the boundries and number of the units marked with the signature */
|
|
|
|
DEBUG_PRINT(("Debug: searching for signtured blocks.\r\n"));
|
|
|
|
flash = bdkVol->flash;
|
|
|
|
numBlock = 0;
|
|
|
|
|
|
for (numBlock = 0 , iBlock = bdkVol->startPartitionBlock;
|
|
iBlock<=bdkVol->endPartitionBlock;iBlock++)
|
|
{
|
|
if ((dword)(iBlock % bdkVol->blockPerFloor) < bdkVol->flash->firstUsableBlock)
|
|
{
|
|
iBlock = (word)(iBlock + bdkVol->flash->firstUsableBlock);
|
|
if (iBlock > bdkVol->endPartitionBlock)
|
|
break;
|
|
}
|
|
/* check for unit signature */
|
|
DEBUG_PRINT(("Debug: getBootAreaInfo() - Reading unit signature...\r\n"));
|
|
checkStatus(flash->read(flash,bdkVol->bdkSignOffset +
|
|
((CardAddress)iBlock << bdkVol->erasableBlockBits),
|
|
bdkVol->signBuffer,SIGNATURE_LEN,EXTRA));
|
|
DEBUG_PRINT(("Debug: getBootAreaInfo() - Signature read done.\r\n"));
|
|
|
|
if(tffscmp( (void FAR1 *)signature , (void FAR1 *)bdkVol->signBuffer,
|
|
BDK_SIGNATURE_NAME ) == 0 )
|
|
{
|
|
if( numBlock == 0 )
|
|
bdkVol->startImageBlock = iBlock;
|
|
|
|
numBlock++;
|
|
bdkVol->endImageBlock = iBlock;
|
|
if(( bdkVol->realBootImageSize == 0L ) && (numBlock>startUnit) &&
|
|
(tffscmp((void FAR1 *)&bdkVol->signBuffer[BDK_SIGNATURE_NAME],
|
|
(void FAR1 *)"FFFF", SIGNATURE_NUM) == 0 ))
|
|
{
|
|
bdkVol->realBootImageSize =
|
|
((dword)(numBlock - startUnit) << bdkVol->erasableBlockBits);
|
|
}
|
|
}
|
|
}
|
|
if (numBlock<=startUnit)
|
|
{
|
|
DEBUG_PRINT(("Debug: getBootAreaInfo() - No space in volume.\r\n"));
|
|
return( flNoSpaceInVolume );
|
|
}
|
|
|
|
bdkVol->bootImageSize = (dword)numBlock << bdkVol->erasableBlockBits;
|
|
if( bdkVol->realBootImageSize == 0L ) /* In case the image without FFFF */
|
|
bdkVol->realBootImageSize =
|
|
((dword)(numBlock - startUnit) << bdkVol->erasableBlockBits);
|
|
|
|
tffscpy((void FAR1 *)(bdkVol->signBuffer),(void FAR1 *)signature,
|
|
BDK_SIGNATURE_NAME);
|
|
|
|
bdkVol->bdkGlobalStatus |= BDK_S_INFO_FOUND;
|
|
}
|
|
|
|
return( flOK );
|
|
}
|
|
|
|
#ifndef NO_INFTL_SUPPORT
|
|
/*----------------------------------------------------------------------*/
|
|
/* b d k R e t r i e v e H e a d e r */
|
|
/* */
|
|
/* Retreave media header by oring the headers of each floor */
|
|
/* */
|
|
/* Note: The header of each floor is read to the first half of the */
|
|
/* buffer and then ORed to the second half therfore constructing the */
|
|
/* real header in the upper half. The data is copied to the first half */
|
|
/* while cast back from little endian */
|
|
/* */
|
|
/* Parameters: */
|
|
/* headerBuffer - buffer returning the retieved header. */
|
|
/* */
|
|
/* Returns: */
|
|
/* flOK on success any other value on error */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkRetrieveHeader (dword * headerBuffer)
|
|
{
|
|
word iUnit;
|
|
dword endUnit; /* Might be larger then word */
|
|
dword * bbt = (headerBuffer+BDK_HEADER_FIELDS);
|
|
FLFlash * flash=bdkVol->flash;
|
|
byte floorNo;
|
|
FLBoolean flag;
|
|
byte index;
|
|
FLStatus status;
|
|
|
|
tffsset(headerBuffer,0,BDK_HEADER_FIELDS * 2 * sizeof(LEmin));
|
|
|
|
for (endUnit = 0,floorNo = 0 ; floorNo < flash->noOfFloors ; floorNo++)
|
|
{
|
|
iUnit = (word)(endUnit + flash->firstUsableBlock);
|
|
|
|
endUnit += bdkVol->blockPerFloor;
|
|
for (flag = FALSE;(iUnit<endUnit)&&(flag==FALSE);iUnit++)
|
|
{
|
|
for (index=0;index<BDK_NO_OF_MEDIA_HEADERS;index++) /* all copies */
|
|
{
|
|
status = flash->read(flash,((CardAddress)iUnit<<flash->erasableBlockSizeBits)
|
|
+ index * BDK_HEADERS_SPACING,bbt,
|
|
BDK_HEADER_FIELDS*sizeof(LEmin),FL_DATA);
|
|
if (status != flOK)
|
|
{
|
|
DEBUG_PRINT(("Debug: ERROR reading original unit header.\r\n"));
|
|
return flBadFormat;
|
|
}
|
|
if (tffscmp(bbt, "BNAND", sizeof("BNAND")) == 0)
|
|
{
|
|
flag=TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (flag == FALSE) /* Header not found in all header copies */
|
|
{
|
|
DEBUG_PRINT(("Debug: binary partition data could not be found.\r\n"));
|
|
return flBadFormat;
|
|
}
|
|
/* merge with previous headers */
|
|
for (index = 0 ; index < BDK_HEADER_FIELDS; index++)
|
|
{
|
|
headerBuffer[index] |= bbt[index];
|
|
}
|
|
} /* loop of the floors */
|
|
return flOK;
|
|
}
|
|
|
|
#endif /* NO_INFTL_SUPPORT */
|
|
/*--------------------------------------------------------------------------*
|
|
* b d k M o u n t
|
|
*
|
|
* Routine that finds the media header unit and initializes it. The header
|
|
* supplies the number of binary partition in the DiskOnChip and their
|
|
* boundries. If the header is valid the curent partition pointer is set to
|
|
* the required partition.
|
|
*
|
|
* Note : 1) Drive argument is assumed to be O.K and DiskOnChip already found
|
|
* 2) If there are no binary partitions O.K will be returned but the
|
|
* bdkVol pointer will not be changed.
|
|
*
|
|
* Parameters : None
|
|
*
|
|
* global variable input :
|
|
* globalSocketNo : DiskOnChip drive number (always 0 for BDK)
|
|
* globalPartitionNo : Binary partition number in the DiskOnChip
|
|
* bdkGlobalStatus - was this partition accessed before
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* noOfPartitions - the current amount of partitions
|
|
* bdkVols - array of the binary partitions records
|
|
*
|
|
* global variable output :
|
|
* bdkVol - new current binary partition record
|
|
* handleTable - partition to record converion table
|
|
* bdkGlobalStatus - set to BDK_S_HEADER_FOUND
|
|
* erasableBlockBits - number of bits representing a unit
|
|
* startPartitionBlock - physical unit number of first unit
|
|
* endPartitionBlock - and last units of the partition
|
|
* noOfPartitions - increment with the new found partitions
|
|
*
|
|
* Return:
|
|
* flOK - success
|
|
* flBadFormat - TL format does not exists
|
|
* flFeatureNotSupported - Not a DiskOnChip device.
|
|
* flNoSpaceInVolume - No binary partition at all
|
|
* flBadDriveHandle - No such binary partition on the media or number
|
|
* binary partitions exceeds the cusomized limit.
|
|
* flDataError - fail in buffer reading codes
|
|
* flHWProtect - HW read protection was triggerd
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
static FLStatus bdkMount(void)
|
|
{
|
|
FLFlash * flash = bdkVol->flash;
|
|
dword iBlock;
|
|
dword noOfBlocks;
|
|
byte blockMultiplierBits;
|
|
byte maxPartition = 0;
|
|
byte buf1[TL_SIGNATURE];
|
|
byte buf2[TL_SIGNATURE];
|
|
#ifndef NO_INFTL_SUPPORT
|
|
LEmin headerBuffer[BDK_HEADER_FIELDS*2]; /* assume big enough */
|
|
VolumeRecord * volume;
|
|
#endif /* NO_INFTL_SUPPORT */
|
|
|
|
if ((bdkVol->bdkGlobalStatus & BDK_S_HEADER_FOUND)==0)/* header not found */
|
|
{
|
|
/* Find number of bits used to represent erasable block */
|
|
|
|
bdkVol->erasableBlockBits = flash->erasableBlockSizeBits;
|
|
noOfBlocks = (dword)(flash->chipSize * flash->noOfChips)
|
|
>> bdkVol->erasableBlockBits;
|
|
bdkVol->blockPerFloor = (word)
|
|
(flash->chipSize >> flash->erasableBlockSizeBits) *
|
|
((flash->noOfChips + (flash->noOfChips % flash->noOfFloors)) /
|
|
flash->noOfFloors);
|
|
|
|
DEBUG_PRINT(("Debug: searching for TL media header.\r\n"));
|
|
|
|
#ifndef NO_NFTL_SUPPORT
|
|
if (flash->flags & NFTL_ENABLED)
|
|
{
|
|
tffscpy(buf1,"ANAND",TL_SIGNATURE);
|
|
}
|
|
#endif /* NO_NFTL_SUPPORT */
|
|
#ifndef NO_INFTL_SUPPORT
|
|
if (flash->flags & INFTL_ENABLED)
|
|
{
|
|
tffscpy(buf1,"BNAND",TL_SIGNATURE);
|
|
}
|
|
#endif /* NO_INFTL_SUPPORT */
|
|
if ((flash->flags & (NFTL_ENABLED | INFTL_ENABLED))==0)
|
|
{
|
|
DEBUG_PRINT(("Debug: Not a DiskOnChip device therfore Binary partitions are not supported.\r\n"));
|
|
return( flFeatureNotSupported );
|
|
}
|
|
|
|
/* Find the medium boot record in order to get partition boundries */
|
|
|
|
for(iBlock=flash->firstUsableBlock;( iBlock < noOfBlocks );iBlock++)
|
|
{
|
|
checkStatus(flash->read(flash,(CardAddress)iBlock << bdkVol->erasableBlockBits,
|
|
buf2,TL_SIGNATURE,0));
|
|
|
|
if(tffscmp((void FAR1 *)buf2,(void FAR1 *)buf1,TL_SIGNATURE) == 0 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (iBlock==noOfBlocks)
|
|
{
|
|
DEBUG_PRINT(("Debug: TL format does not exists.\r\n"));
|
|
return( flBadFormat );
|
|
}
|
|
|
|
/* Analize The media header */
|
|
|
|
#ifndef NO_NFTL_SUPPORT
|
|
if (flash->flags & NFTL_ENABLED) /* NFTL - only a single partition */
|
|
{
|
|
DEBUG_PRINT(("NFTL media header encounterd.\r\n"));
|
|
bdkVol->startPartitionBlock = 0;
|
|
bdkVol->endPartitionBlock = (word)((iBlock) ? iBlock-1 : 0);
|
|
maxPartition = 1;
|
|
}
|
|
#endif /* NO_NFTL_SUPPORT */
|
|
#ifndef NO_INFTL_SUPPORT
|
|
if (flash->flags & INFTL_ENABLED) /* INFTL - parse media header */
|
|
{
|
|
DEBUG_PRINT(("INFTL media header encounterd.\r\n"));
|
|
maxPartition = 0;
|
|
checkStatus(bdkRetrieveHeader((dword *)headerBuffer));
|
|
volume = (VolumeRecord *) (headerBuffer+BDK_FIELDS_BEFORE_HEADER);
|
|
if (((LE4(volume->flags) & BDK_BINARY_FLAG)==0) && (globalPartitionNo == 0))
|
|
{
|
|
DEBUG_PRINT(("Device is not formated with a binary partition.\r\n"));
|
|
return flNoSpaceInVolume;
|
|
}
|
|
blockMultiplierBits = (byte)LE4(headerBuffer[MULTIPLIER_OFFSET]);
|
|
bdkVol = &bdkVols[noOfPartitions];
|
|
for (;(BINARY_PARTITIONS >= maxPartition + noOfPartitions) &&
|
|
(LE4(volume->flags) & BDK_BINARY_FLAG) ; bdkVol++,volume++)
|
|
{
|
|
maxPartition++;
|
|
bdkVol->startPartitionBlock = (word)LE4(volume->firstUnit) << blockMultiplierBits;
|
|
bdkVol->endPartitionBlock = (word)((LE4(volume->lastUnit)+1) << blockMultiplierBits) - 1;
|
|
bdkVol->flash = bdkVols[noOfPartitions].flash;
|
|
#ifdef PROTECT_BDK_IMAGE
|
|
bdkVol->protectionArea = (byte)LE4(volume->protectionArea);
|
|
bdkVol->protectionType = (word)LE4(volume->flags);
|
|
#endif /* PROTECT_BDK_IMAGE */
|
|
bdkVol->blockPerFloor = bdkVols[noOfPartitions].blockPerFloor;
|
|
bdkVol->erasableBlockBits = bdkVols[noOfPartitions].erasableBlockBits;
|
|
}
|
|
}
|
|
#endif /* NO_INFTL_SUPPORT */
|
|
|
|
/* Initialize the partitions that had been found */
|
|
|
|
for (blockMultiplierBits=0;blockMultiplierBits<maxPartition;
|
|
blockMultiplierBits++) /* reused blockMultiplierBits as counter */
|
|
{
|
|
bdkVol = &bdkVols[noOfPartitions];
|
|
handleTable[globalSocketNo][blockMultiplierBits] = noOfPartitions++;
|
|
bdkVol->bdkGlobalStatus = BDK_S_DOC_FOUND |
|
|
BDK_S_HEADER_FOUND;
|
|
}
|
|
}
|
|
|
|
/* set the current partition by changing the bdkVol global pointer */
|
|
|
|
if ((globalPartitionNo>MAX_BINARY_PARTITIONS_PER_DRIVE) ||
|
|
(handleTable[globalSocketNo][globalPartitionNo] == BDK_INVALID_VOLUME_HANDLE))
|
|
{
|
|
DEBUG_PRINT(("Device is not formated the specified binary partition.\r\n"));
|
|
return flBadDriveHandle;
|
|
}
|
|
else
|
|
{
|
|
bdkVol = &bdkVols[handleTable[globalSocketNo][globalPartitionNo]];
|
|
}
|
|
return flOK;
|
|
}
|
|
|
|
#ifdef MTD_STANDALONE
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k E x i t
|
|
*
|
|
* Reset BDK variables and Free 'bdkWin' memory.
|
|
*
|
|
* Parameters: None
|
|
*
|
|
* Return: Nothing
|
|
*-------------------------------------------------------------------*/
|
|
|
|
void bdkExit( void )
|
|
{
|
|
if( bdkVol->bdkGlobalStatus & BDK_S_DOC_FOUND ) /* DiskOnChip was found */
|
|
{
|
|
freePointer(bdkWin,DOC_WIN);
|
|
}
|
|
bdkInit();
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k S e t D o c W i n d o w
|
|
*
|
|
* Set DiskOnChip window explicitly
|
|
*
|
|
* Note : This routine should not be used after a DiskOnChip was already
|
|
* found since it does not initialize the Global binary variables.
|
|
* In order to switch between DiskOnChip call bdkexists before
|
|
* calling this routine.
|
|
*
|
|
* Parameters : 'docWindow' - DiskOnChip physical address
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
*
|
|
* global variable output :
|
|
* bdkDocWindow - initialized with the given address
|
|
*
|
|
* Return: Nothing
|
|
*
|
|
* Routine for BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
void bdkSetDocWindow( dword docWindow )
|
|
{
|
|
bdkVol->bdkDocWindow = docWindow;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* b d k F i n d D i s k O n C h i p
|
|
*
|
|
* Find DiskOnChip in the specified memory range and identify the flash
|
|
* media (initialize flash). Update 'docSize' and 'docAddress' according
|
|
* to the DiskOnChip size and address respectively.
|
|
*
|
|
* Note : If the DiskOnChip location is known, specify the same address
|
|
* for DOC_LOW_ADDRESS and DOC_HIGH_ADDRESS.
|
|
*
|
|
* Parameters : 'docAddress' - pointer to the DiskOnChip address
|
|
* 'docSize' - pointer to the returned size
|
|
*
|
|
* global variable input :
|
|
* bdkGlobalStatus - was this device found before
|
|
* bdkVol - current binary partition record
|
|
* bdkDocWindow - if > 0 only this address will be checked
|
|
*
|
|
* global variable output :
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - set to BDK_S_DOC_FOUND
|
|
* bdkDocWindow - save physical window address
|
|
*
|
|
* Return:
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
*
|
|
* Routine for BDK stand alone package.
|
|
*------------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkFindDiskOnChip(dword FAR2 *docAddress, dword FAR2 *docSize )
|
|
{
|
|
FLStatus status;
|
|
byte mtdIndex;
|
|
dword blockSize;
|
|
FLSocket *socket = flSocketOf(0);
|
|
FLFlash *flash = flFlashOf(0);
|
|
|
|
if(globalInitStatus==FALSE)
|
|
bdkInit();
|
|
|
|
if ((bdkVol->bdkGlobalStatus & BDK_S_DOC_FOUND) == 0) /* initialize MTD */
|
|
{
|
|
|
|
bdkVol = bdkVols;
|
|
bdkVol->flash = flash;
|
|
|
|
#ifndef NO_DOC2000_FAMILY_SUPPORT
|
|
flRegisterDOC2000();
|
|
#endif
|
|
#ifndef NO_DOCPLUS_FAMILY_SUPPORT
|
|
flRegisterDOCPLUS();
|
|
#endif
|
|
|
|
/* Search for ASIC in the given memory boundries */
|
|
|
|
for(mtdIndex=0;mtdIndex < noOfMTDs;mtdIndex++)
|
|
{
|
|
if( bdkVol->bdkDocWindow > 0 ) /* Set range explicitely */
|
|
{
|
|
status = socketTable[mtdIndex](socket,
|
|
bdkVol->bdkDocWindow,bdkVol->bdkDocWindow);
|
|
}
|
|
else
|
|
{
|
|
status = socketTable[mtdIndex](socket,
|
|
DOC_LOW_ADDRESS,DOC_HIGH_ADDRESS);
|
|
}
|
|
if (status == flOK)
|
|
{
|
|
/* Identify flash connected to the ASIC */
|
|
|
|
bdkVol->bdkDocWindow = pointerToPhysical(socket->base);
|
|
|
|
flash->socket = socket;
|
|
checkStatus(mtdTable[mtdIndex](flash));
|
|
break;
|
|
}
|
|
}
|
|
if (status != flOK)
|
|
return status;
|
|
|
|
bdkVol->bdkGlobalStatus |= BDK_S_DOC_FOUND;
|
|
|
|
/* Calculate erasable Block Size Bits */
|
|
for(blockSize = flash->erasableBlockSize>>1,flash->erasableBlockSizeBits = 0;
|
|
blockSize>0; flash->erasableBlockSizeBits++,blockSize = blockSize >> 1);
|
|
}
|
|
|
|
*docAddress = pointerToPhysical(socket->base);
|
|
*docSize = flash->chipSize * flash->noOfChips;
|
|
|
|
return flOK;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* b d k S e t B o o t P a r t i t i o n N o
|
|
*
|
|
* Set current binary partiton pointer to a specific binary partition
|
|
*
|
|
* Note : This routine is neccesay only for partitions > 0 .
|
|
* This routine can replace the bdkFindDiskOnChip call.
|
|
*
|
|
* Parameters : 'partitionNo' - serial number of binary partition
|
|
*
|
|
* global variable output :
|
|
* globalPartitionNo - changed to the current partition number.
|
|
*
|
|
* Return:
|
|
* flOK on success
|
|
* flBadParameter if BDK is not customized to support that many partitions.
|
|
*
|
|
* Routine for BDK stand alone package only.
|
|
*------------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkSetBootPartitionNo(byte partitionNo)
|
|
{
|
|
if (partitionNo < TFFSMIN(BINARY_PARTITIONS,MAX_BINARY_PARTITIONS_PER_DRIVE))
|
|
{
|
|
globalPartitionNo = partitionNo;
|
|
return flOK;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_PRINT(("BDK is not customized to support the specified partition number.\r\n"));
|
|
return flBadParameter;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k C h e c k S i g n O f f s e t
|
|
*
|
|
* Set BDK signature offset
|
|
*
|
|
* Note : Offset 0 does not support the use of EDC\ECC mechanizm and
|
|
* therfore it reconmended not to be used.
|
|
* The new found offset is stored in the bdkSignOffset field of the
|
|
* partitions global record.
|
|
*
|
|
* Parameters : 'signature' - 4-character signature of storage units
|
|
*
|
|
* global variable input :
|
|
* bdkGlobalStatus - was this partition accessed before
|
|
* bdkVol - current binary partition record
|
|
* bdkDocWindow - DiskOnChip window physical address
|
|
* (used to narrow search for DiskOnChip)
|
|
*
|
|
* global variable output :
|
|
* bdkSignOffset - the offset of the signature (either 0 or 8)
|
|
*
|
|
* bdkSavedStartUnit - save start unit for next access
|
|
* bdkSavedSignOffset - save current signatur for next access
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* signBuffer - initialize with given signature
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW protection was triggerd
|
|
*
|
|
* Routine for BDK stand alone package only.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkCheckSignOffset( byte FAR2 *signature )
|
|
{
|
|
FLStatus status;
|
|
|
|
bdkVol->bdkSignOffset = 0; /* Look for signature units with offset 0 */
|
|
|
|
status = getBootAreaInfo( 0 , signature );
|
|
|
|
if (status!=flOK)
|
|
{
|
|
bdkVol->bdkSignOffset = BDK_SIGN_OFFSET; /* Now try with offset 8 */
|
|
checkStatus(getBootAreaInfo( 0 , signature ));
|
|
}
|
|
return( flOK );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k C o p y B o o t A r e a
|
|
*
|
|
* Copy the BDK Image from the DiskOnChip to a RAM area starting at
|
|
* 'startAddress', with a size of 'areaLen' bytes.
|
|
*
|
|
* Note : Blocks in the DiskOnChip are marked with a 4-byteacter signature
|
|
* followed by a 4-digit hexadecimal number.
|
|
*
|
|
* This routine simple calls bdkCopyBootAreaInit and loops over
|
|
* bdkCopyBootAreaBlock.
|
|
*
|
|
* Parameters: 'startAddress' - pointer to the beginning of the RAM area
|
|
* 'startUnit' - start block in image for reading
|
|
* 'areaLen' - BDK image size
|
|
* 'checkSum' - pointer to the checksum modulo 0x100
|
|
* 'signature' - 4-byteacter signature of storage units
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* bdkGlobalStatus - partition predsent status.
|
|
* bdkSavedStartUnit - start unit of previous access
|
|
* bdkSavedSignOffset - signature offset of previous access
|
|
* bdkSignOffset - current signature offset
|
|
* bdkDocWindow - explicitly sets the windows address
|
|
*
|
|
* global variable output :
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* signBuffer - initialize with given signature
|
|
* bdkSavedStartUnit - save start unit for next access
|
|
* bdkSavedSignOffset - save current signature for next access
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD dependent.
|
|
* flHWProtect - HW read protection was triggerd
|
|
*
|
|
* Routine for BDK stand alone package only.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkCopyBootArea( byte FAR1 *startAddress,word startUnit,dword areaLen,
|
|
byte FAR2 *checkSum, byte FAR2 *signature )
|
|
{
|
|
dword curLen;
|
|
word copyLen;
|
|
|
|
checkStatus(bdkCopyBootAreaInit( startUnit, areaLen, signature ));
|
|
DEBUG_PRINT(("Debug: bdkCopyBootArea() - bdkCopyBootAreaInit was done succefully.\r\n"));
|
|
|
|
#ifdef BDK_CHECK_SUM
|
|
if (checkSum!=NULL)
|
|
*checkSum=0;
|
|
#endif /* BDK_CHECK_SUM */
|
|
|
|
for(curLen=0L;( curLen < areaLen );curLen+=bdkVol->flash->erasableBlockSize)
|
|
{
|
|
copyLen = (word)BDK_MIN((areaLen - curLen), bdkVol->flash->erasableBlockSize);
|
|
checkStatus(bdkCopyBootAreaBlock( (byte FAR1 *)startAddress, copyLen, checkSum ));
|
|
startAddress = (byte FAR1 *)addToFarPointer( startAddress, copyLen);
|
|
}
|
|
return flOK;
|
|
}
|
|
|
|
#endif /* MTD_STANDALONE */
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k G e t B o o t P a r t i t i o n I n f o
|
|
*
|
|
* Get DiskOnChip binary sub partition Information.
|
|
*
|
|
* Note : Blocks in the DiskOnChip are marked with a 4-byteacter signature
|
|
* followed by a 4-digit hexadecimal number.
|
|
*
|
|
* Parameters: 'startUnit' - start Unit for Actual sub Partition Size
|
|
* 'partitionSize' - pointer to return sub Partition Size parameter
|
|
* 'realPartitionSize' - pointer to return Actual sub Partition Size
|
|
* 'unitSize' - pointer to return Unit Size parameter
|
|
* 'signature' - 4-byteacter signature of storage units
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* bdkGlobalStatus - partition predsent status.
|
|
* bdkSavedStartUnit - start unit of previous access
|
|
* bdkSavedSignOffset - signature offset of previous access
|
|
* bdkSignOffset - current signature offset
|
|
* bdkDocWindow - explicitly sets the windows address
|
|
*
|
|
* global variable output :
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* signBuffer - initialize with given signature
|
|
* bdkSavedStartUnit - save start unit for next access
|
|
* bdkSavedSignOffset - save current signature for next access
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD dependent.
|
|
* flHWProtect - HW read protection was triggerd
|
|
*
|
|
* Routine for BDK stand alone package only.*
|
|
*-------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkGetBootPartitionInfo( word startUnit, dword FAR2 *partitionSize,
|
|
dword FAR2 *realPartitionSize,
|
|
dword FAR2 *unitSize, byte FAR2 *signature)
|
|
{
|
|
FLStatus st = flOK;
|
|
*partitionSize = 0L;
|
|
*unitSize = 0L;
|
|
|
|
st = getBootAreaInfo( startUnit , signature );
|
|
|
|
*partitionSize = bdkVol->bootImageSize;
|
|
*realPartitionSize = bdkVol->realBootImageSize;
|
|
*realPartitionSize -= ((startUnit - bdkVol->bdkSavedStartUnit) << bdkVol->erasableBlockBits);
|
|
*unitSize = bdkVol->flash->erasableBlockSize;
|
|
|
|
return( st );
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k C o p y B o o t A r e a I n i t
|
|
*
|
|
* Initialize read operations on the DiskOnChip starting at 'startUnit', with
|
|
* a size of 'areaLen' bytes and 'signature'.
|
|
*
|
|
* Note : Blocks in the DiskOnChip are marked with a 4-byteacter signature
|
|
* followed by a 4-digit hexadecimal number.
|
|
*
|
|
* Parameters: 'startUnit' - start block in image for reading
|
|
* 'areaLen' - BDK image size
|
|
* 'signature' - 4-byteacter signature of storage units
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - was this partition accessed before
|
|
* bdkSavedSignBuffer - signature offset of previous access
|
|
* bdkSignOffset - current signature offset
|
|
*
|
|
* global variable output :
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* signBuffer - initialize with given signature
|
|
* bdkSavedSignBuffer - save current signatur for next access
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* curReadImageAddress - current address to read from
|
|
* actualReadLen - length left to read
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW read protection was triggerd
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkCopyBootAreaInit(word startUnit ,
|
|
dword areaLen ,
|
|
byte FAR2 *signature)
|
|
{
|
|
dword realSize; /* remaining real size from start unit */
|
|
|
|
checkStatus(getBootAreaInfo( startUnit , signature ));
|
|
|
|
realSize = bdkVol->realBootImageSize;
|
|
realSize -= (startUnit - bdkVol->bdkSavedStartUnit) << bdkVol->erasableBlockBits;
|
|
if (areaLen>realSize)
|
|
{
|
|
DEBUG_PRINT(("got out of the partition.\r\n"));
|
|
return( flNoSpaceInVolume );
|
|
}
|
|
|
|
bdkVol->curReadImageBlock = startUnit;
|
|
bdkVol->actualReadLen = areaLen;
|
|
bdkVol->curReadImageAddress = getPhysAddressOfUnit( startUnit );
|
|
return( flOK );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
* bdkCopyBootAreaBlock - Read to 'buffer' from the DiskOnChip BDK Image area.
|
|
*
|
|
* Note : Before the first use of this function 'bdkCopyBootAreaInit'
|
|
* must be called
|
|
*
|
|
* Parameters: 'buf' - buffer to read into
|
|
* 'bufferLen' - buffer length in bytes
|
|
* 'checkSum' - pointer to the checksum modulo 0x100
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* signBuffer - sub partition signature
|
|
* bdkSignOffset - current signature offset
|
|
* curReadImageAddress - current address to read from
|
|
* actualReadLen - length left to read
|
|
* endImageBlock - last signatured block in sub partition
|
|
* erasableBlockBits - no' of bits used to represent a block
|
|
*
|
|
* global variable output :
|
|
* curReadImageAddress - updated address to read from
|
|
* actualReadLen - updated length left to read
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flBadLength - required length will cause crossing unit boundry
|
|
* flNoSpaceInVolume - no more signatured units found
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW read protection was triggerd
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkCopyBootAreaBlock( byte FAR1 *buf, word bufferLen, byte FAR2 *checkSum )
|
|
{
|
|
word iBlock, readLen;
|
|
byte modes;
|
|
byte signRead[BDK_SIGNATURE_NAME];
|
|
FLFlash * flash = bdkVol->flash;
|
|
FLStatus status;
|
|
|
|
if( (bufferLen > flash->erasableBlockSize ) ||
|
|
(bufferLen > bdkVol->actualReadLen))
|
|
return( flBadLength );
|
|
|
|
/* find next good unit */
|
|
|
|
if( (bdkVol->curReadImageAddress & (flash->erasableBlockSize-1)) == 0 )
|
|
{
|
|
iBlock = (word)( bdkVol->curReadImageAddress >> bdkVol->erasableBlockBits );
|
|
for(;( iBlock <= bdkVol->endImageBlock ); iBlock++)
|
|
{
|
|
if ((dword)(iBlock % bdkVol->blockPerFloor) < bdkVol->flash->firstUsableBlock)
|
|
{
|
|
iBlock = (word)(iBlock + bdkVol->flash->firstUsableBlock);
|
|
if (iBlock > bdkVol->endImageBlock)
|
|
break;
|
|
}
|
|
|
|
status = flash->read (flash , bdkVol->bdkSignOffset +
|
|
((CardAddress)iBlock << bdkVol->erasableBlockBits) ,
|
|
(byte FAR1 *)signRead, BDK_SIGNATURE_NAME,EXTRA);
|
|
if(status!=flOK)
|
|
{
|
|
DEBUG_PRINT(("(EXTRA)read failed.\r\n"));
|
|
return status;
|
|
}
|
|
if( tffscmp((void FAR1 *)signRead, (void FAR1 *)(bdkVol->signBuffer),
|
|
BDK_SIGNATURE_NAME ) == 0 )
|
|
break;
|
|
}
|
|
|
|
if( iBlock > bdkVol->endImageBlock )
|
|
return( flNoSpaceInVolume ); /* Finish (last block) */
|
|
|
|
bdkVol->curReadImageAddress = (CardAddress )iBlock << bdkVol->erasableBlockBits;
|
|
bdkVol->curReadImageBlock++;
|
|
}
|
|
|
|
/* read data */
|
|
|
|
readLen = (word)BDK_MIN(bdkVol->actualReadLen, (dword)bufferLen);
|
|
if((bdkVol->bdkEDC)&&(bdkVol->bdkSignOffset!=0))
|
|
{
|
|
modes=EDC;
|
|
}
|
|
else
|
|
{
|
|
modes=0;
|
|
}
|
|
|
|
status = (flash->read(flash, bdkVol->curReadImageAddress, buf, readLen, modes));
|
|
if(status!=flOK)
|
|
{
|
|
DEBUG_PRINT(("(EXTRA)read failed.\r\n"));
|
|
return status;
|
|
}
|
|
|
|
bdkVol->curReadImageAddress += (CardAddress )readLen;
|
|
bdkVol->actualReadLen -= (dword)readLen;
|
|
|
|
#ifdef BDK_CHECK_SUM
|
|
if (checkSum!=NULL)
|
|
{
|
|
while (readLen>0)
|
|
{
|
|
readLen--;
|
|
*checkSum+=buf[readLen];
|
|
}
|
|
}
|
|
#endif /* BDK_CHECK_SUM */
|
|
return( flOK );
|
|
}
|
|
|
|
#ifdef UPDATE_BDK_IMAGE
|
|
/*-------------------------------------------------------------------
|
|
* b d k U p d a t e B o o t A r e a I n i t
|
|
*
|
|
* Initialize update operations on the DiskOnChip starting at 'startUnit',
|
|
* with a size of 'areaLen' bytes and 'signature'.
|
|
*
|
|
* Note : Blocks in the DiskOnChip are marked with a 4-byteacter signature
|
|
* followed by a 4-digit hexadecimal number.
|
|
*
|
|
* Parameters: 'startUnit' - start unit in image for updating
|
|
* 'areaLen' - BDK image size
|
|
* 'updateFlag' - update whole image or part of it
|
|
* BDK_COMPLETE_IMAGE_UPDATE
|
|
* 'signature' - 4-byteacter signature of storage units
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - was this partition accessed before
|
|
* bdkSavedSignBuffer - signature offset of previous access
|
|
* bdkSignOffset - current signature offset
|
|
*
|
|
* global variable output :
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* signBuffer - initialize with given signature
|
|
* bdkSavedSignBuffer - save current signatur for next access
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* actualUpdateLen - length left to write
|
|
* curUpadateImageAddress - current address to write to
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW read protection was triggerd
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkUpdateBootAreaInit( word startUnit, dword areaLen,
|
|
byte updateFlag, byte FAR2 *signature )
|
|
{
|
|
word imageBlockSize;
|
|
|
|
checkStatus(getBootAreaInfo( startUnit , signature ));
|
|
|
|
imageBlockSize = (word)( bdkVol->bootImageSize >> bdkVol->erasableBlockBits);
|
|
|
|
if( ((dword)(imageBlockSize-startUnit) << bdkVol->erasableBlockBits) < areaLen )
|
|
return( flNoSpaceInVolume );
|
|
|
|
bdkVol->actualUpdateLen = areaLen;
|
|
bdkVol->curUpdateImageBlock = startUnit;
|
|
bdkVol->updateImageFlag = updateFlag;
|
|
bdkVol->curUpdateImageAddress = getPhysAddressOfUnit( startUnit );
|
|
bdkVol->bdkGlobalStatus &= ~BDK_S_INFO_FOUND;
|
|
return( flOK );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k U p d a t e B o o t A r e a B l o c k
|
|
*
|
|
* Write 'buffer' to the DiskOnChip BDK Image area.
|
|
*
|
|
* Note : Before the first use of this function 'bdkUpdateBootAreaInit'
|
|
* must be called
|
|
*
|
|
* Parameters: 'buf' - BDK image buffer
|
|
* 'bufferLen' - buffer length in bytes
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* signBuffer - sub partition signature
|
|
* bdkSignOffset - current signature offset
|
|
* curUpdateImageAddress - current address to read from
|
|
* actualUpdateLen - length left to read
|
|
* endImageBlock - last signatured block in sub partition
|
|
* erasableBlockBits - no' of bits used to represent a block
|
|
*
|
|
* global variable output :
|
|
* curUpdateImageAddress - updated address to read from
|
|
* actualUpdateLen - updated length left to read
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flBadLength - required length will cause crossing unit boundry
|
|
* flNoSpaceInVolume - no more signatured units found
|
|
* flDataError - MTD read fault
|
|
* flHWProtect - HW protection was triggerd
|
|
* flWriteFault - MTD write fault
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkUpdateBootAreaBlock( byte FAR1 *buf, word bufferLen )
|
|
{
|
|
word iBlock, writeLen, i0, j;
|
|
FLStatus status;
|
|
FLFlash* flash = bdkVol->flash;
|
|
byte modes;
|
|
byte signRead[SIGNATURE_LEN];
|
|
|
|
if( (bufferLen > flash->erasableBlockSize) ||
|
|
(bufferLen > bdkVol->actualUpdateLen))
|
|
return( flBadLength );
|
|
|
|
/* find next good unit and prepare it for work */
|
|
|
|
if( (bdkVol->curUpdateImageAddress & (flash->erasableBlockSize-1)) == 0 )
|
|
{
|
|
/* find next signatured unit */
|
|
|
|
iBlock = (word)( bdkVol->curUpdateImageAddress >> bdkVol->erasableBlockBits );
|
|
for(;( iBlock <= bdkVol->endImageBlock ); iBlock++)
|
|
{
|
|
if ((dword)(iBlock % bdkVol->blockPerFloor) < bdkVol->flash->firstUsableBlock)
|
|
{
|
|
iBlock = (word)(iBlock + bdkVol->flash->firstUsableBlock);
|
|
if (iBlock > bdkVol->endImageBlock)
|
|
break;
|
|
}
|
|
status = flash->read(flash , bdkVol->bdkSignOffset +
|
|
((CardAddress)iBlock << bdkVol->erasableBlockBits),
|
|
(byte FAR1 *)signRead, BDK_SIGNATURE_NAME ,EXTRA);
|
|
if(status!=flOK)
|
|
{
|
|
DEBUG_PRINT(("(EXTRA)read failed.\r\n"));
|
|
return status;
|
|
}
|
|
|
|
if( tffscmp( (void FAR1 *)signRead, (void FAR1 *)(bdkVol->signBuffer),
|
|
BDK_SIGNATURE_NAME ) == 0 )
|
|
break;
|
|
}
|
|
if( iBlock > bdkVol->endImageBlock )
|
|
return( flNoSpaceInVolume );
|
|
|
|
/* Erase the newly found unit */
|
|
|
|
#ifdef BDK_ACCESS
|
|
if(bdkVol->updateImageFlag & ERASE_BEFORE_WRITE)
|
|
#endif
|
|
checkStatus(flash->erase (flash, iBlock, 1 ));
|
|
|
|
/* Update signature number */
|
|
|
|
if( (bdkVol->actualUpdateLen <= flash->erasableBlockSize) &&
|
|
(bdkVol->updateImageFlag & BDK_COMPLETE_IMAGE_UPDATE) )
|
|
{
|
|
/* Last block FFFF */
|
|
tffscpy( (void FAR1 *)&bdkVol->signBuffer[BDK_SIGNATURE_NAME],
|
|
(void FAR1 *)"FFFF", SIGNATURE_NUM );
|
|
}
|
|
else
|
|
{
|
|
for(i0=bdkVol->curUpdateImageBlock,j=SIGNATURE_LEN;(j>BDK_SIGNATURE_NAME);j--)
|
|
{
|
|
bdkVol->signBuffer[j-1] = (i0 % 10) + '0';
|
|
i0 /= 10;
|
|
}
|
|
}
|
|
/* update internal pointers */
|
|
|
|
bdkVol->curUpdateImageAddress = (CardAddress )iBlock << bdkVol->erasableBlockBits;
|
|
bdkVol->curUpdateImageBlock++;
|
|
|
|
/* Mark new block */
|
|
status = flash->write(flash,
|
|
(bdkVol->bdkSignOffset + bdkVol->curUpdateImageAddress),
|
|
(byte FAR1 *)bdkVol->signBuffer, SIGNATURE_LEN, EXTRA);
|
|
#ifdef VERIFY_WRITE
|
|
if (status == flWriteFault) /* Check if failed due to erase operation */
|
|
{
|
|
/* Check signature is written properly */
|
|
flash->read(flash , (bdkVol->bdkSignOffset + bdkVol->curUpdateImageAddress),
|
|
(byte FAR1 *)signRead, SIGNATURE_LEN ,EXTRA);
|
|
if(tffscmp(signRead,bdkVol->signBuffer,BDK_SIGNATURE_NAME))
|
|
{
|
|
return flWriteFault;
|
|
}
|
|
/* Check unit number is not "FFFF" */
|
|
if(tffscmp(signRead+BDK_SIGNATURE_NAME,"FFFF",BDK_SIGNATURE_NAME))
|
|
{
|
|
dword tmp=0;
|
|
checkStatus(flash->write(flash,(bdkVol->bdkSignOffset +
|
|
bdkVol->curUpdateImageAddress), &tmp, sizeof (dword), EXTRA));
|
|
}
|
|
}
|
|
#endif /* VERIFY_WRITE */
|
|
}
|
|
|
|
/* Write the data to the flash and update internal pointers */
|
|
|
|
writeLen = (word)BDK_MIN(bdkVol->actualUpdateLen, (dword)bufferLen);
|
|
|
|
if((bdkVol->bdkEDC)&&(bdkVol->bdkSignOffset!=0))
|
|
{
|
|
modes=EDC;
|
|
}
|
|
else
|
|
{
|
|
modes=0;
|
|
}
|
|
checkStatus(flash->write(flash,bdkVol->curUpdateImageAddress,buf,writeLen,modes));
|
|
|
|
bdkVol->curUpdateImageAddress += (CardAddress)writeLen;
|
|
bdkVol->actualUpdateLen -= (dword)writeLen;
|
|
return( flOK );
|
|
}
|
|
|
|
#ifdef ERASE_BDK_IMAGE
|
|
/*-------------------------------------------------------------------
|
|
* b d k E r a s e A r e a
|
|
*
|
|
* Erase given number of blockds in the binary sub partition.
|
|
*
|
|
* Parameters: 'startUnit' - start unit in image for updating
|
|
* 'noOfBlocks' - number of blocks to erase
|
|
* 'signature' - 4-byteacter signature of storage units
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - was this partition accessed before
|
|
* bdkSavedSignBuffer - signature offset of previous access
|
|
* bdkSignOffset - current signature offset
|
|
*
|
|
* global variable output :
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* signBuffer - initialize with given signature
|
|
* bdkSavedSignBuffer - save current signatur for next access
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* actualUpdateLen - 0
|
|
* curUpadateImageAddress - address of first block to erase.
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW protection was triggerd
|
|
* flWriteFault - MTD write fault
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkEraseBootArea(word startUnit, word noOfBlocks, byte FAR2 * signature)
|
|
{
|
|
word iBlock,index;
|
|
FLStatus status;
|
|
FLFlash* flash;
|
|
|
|
flash = bdkVol->flash;
|
|
|
|
checkStatus(bdkUpdateBootAreaInit(startUnit,
|
|
(dword)noOfBlocks << bdkVol->erasableBlockBits,0,signature));
|
|
|
|
tffscpy( (void FAR1 *)&bdkVol->signBuffer, (void FAR1 *) signature, BDK_SIGNATURE_NAME);
|
|
tffscpy( (void FAR1 *)&bdkVol->signBuffer[BDK_SIGNATURE_NAME], /* Last block FFFF */
|
|
(void FAR1 *)"FFFF", SIGNATURE_NUM );
|
|
|
|
iBlock = (word)(bdkVol->curUpdateImageAddress >> bdkVol->erasableBlockBits);
|
|
|
|
for (index=0;index<noOfBlocks;index++,iBlock++)
|
|
|
|
/* find next good unit erase it and rewrite its signature */
|
|
{
|
|
do
|
|
{
|
|
if ((dword)(iBlock % bdkVol->blockPerFloor) < bdkVol->flash->firstUsableBlock)
|
|
{
|
|
/* Skip OTP and DPS if relevant */
|
|
iBlock = (word)(iBlock + bdkVol->flash->firstUsableBlock);
|
|
if (iBlock > bdkVol->endImageBlock)
|
|
return flGeneralFailure;
|
|
}
|
|
|
|
status = flash->read(flash , bdkVol->bdkSignOffset +
|
|
((CardAddress)iBlock << bdkVol->erasableBlockBits),
|
|
(byte FAR1 *)bdkVol->signBuffer, BDK_SIGNATURE_NAME ,EXTRA);
|
|
if(status!=flOK)
|
|
{
|
|
DEBUG_PRINT(("(EXTRA)read failed.\r\n"));
|
|
return status;
|
|
}
|
|
if (tffscmp((void FAR1 *)bdkVol->signBuffer,
|
|
(void FAR1 *)signature, BDK_SIGNATURE_NAME ) == 0)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
iBlock++;
|
|
}
|
|
if (iBlock > bdkVol->endImageBlock)
|
|
return( flNoSpaceInVolume );
|
|
}while(1);
|
|
|
|
checkStatus(flash->erase(flash, iBlock, 1 ));
|
|
checkStatus(flash->write(flash, bdkVol->bdkSignOffset +
|
|
((CardAddress)iBlock << bdkVol->erasableBlockBits),
|
|
(byte FAR1 *)bdkVol->signBuffer, SIGNATURE_LEN, EXTRA));
|
|
}
|
|
|
|
bdkVol->actualUpdateLen = 0L;
|
|
return( flOK );
|
|
}
|
|
|
|
#endif /* ERASE_BDK_IMAGE */
|
|
|
|
#ifdef CREATE_BDK_IMAGE
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k C r e a t e B o o t A r e a
|
|
* Init create operations on the DiskOnChip starting at 'startUnit', with
|
|
* a # of 'units' and 'signature'.
|
|
*
|
|
* Note : Blocks in the DiskOnChip are marked with a 4-character signature
|
|
* followed by a 4-digit hexadecimal number.
|
|
*
|
|
* Parameters: 'noOfBlocks' - number of blocks to erase
|
|
* 'oldSign' - 4-byteacter signature of the source units
|
|
* 'newSign' - 4-byteacter signature of the new units
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - was this partition accessed before
|
|
* bdkSavedSignBuffer - signature offset of previous access
|
|
* bdkSignOffset - current signature offset
|
|
*
|
|
* global variable output :
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* signBuffer - initialize with given signature
|
|
* bdkSavedSignBuffer - save current signatur for next access
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* actualUpdateLen - 0
|
|
* curUpadateImageAddress - address of first block to erase.
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW protection was triggerd
|
|
* flWriteFault - MTD write fault
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
FLStatus bdkCreateBootArea(word noOfBlocks, byte FAR2 * oldSign,
|
|
byte FAR2 * newSign)
|
|
{
|
|
word iBlock, index;
|
|
byte signRead[BDK_SIGNATURE_NAME];
|
|
FLStatus status;
|
|
FLFlash* flash;
|
|
|
|
flash = bdkVol->flash;
|
|
|
|
/* FFFF is not a valid signature */
|
|
if(*((dword FAR2*)newSign)==0xffffffffL)
|
|
{
|
|
DEBUG_PRINT(("Debug: can not use 'FFFF' signature for Binary partition.\r\n"));
|
|
return flBadParameter;
|
|
}
|
|
|
|
checkStatus(bdkUpdateBootAreaInit(0,(dword)noOfBlocks<<flash->erasableBlockSizeBits,
|
|
BDK_PARTIAL_IMAGE_UPDATE,oldSign));
|
|
|
|
tffscpy( (void FAR1 *)&bdkVol->signBuffer, (void FAR1 *) newSign, BDK_SIGNATURE_NAME);
|
|
tffscpy( (void FAR1 *)&bdkVol->signBuffer[BDK_SIGNATURE_NAME], /* Last block FFFF */
|
|
(void FAR1 *)"FFFF", SIGNATURE_NUM );
|
|
|
|
iBlock = (word)(bdkVol->curUpdateImageAddress >> bdkVol->erasableBlockBits);
|
|
|
|
for (index=0;index<noOfBlocks;index++)
|
|
|
|
/* find next good unit erase it and write its new signature */
|
|
{
|
|
for(;( iBlock <= bdkVol->endImageBlock ); iBlock++)
|
|
{
|
|
if ((dword)(iBlock % bdkVol->blockPerFloor) < bdkVol->flash->firstUsableBlock)
|
|
{
|
|
iBlock = (word)(iBlock + bdkVol->flash->firstUsableBlock);
|
|
if (iBlock > bdkVol->endImageBlock)
|
|
break;
|
|
}
|
|
|
|
status = flash->read(flash , bdkVol->bdkSignOffset +
|
|
((CardAddress)iBlock << bdkVol->erasableBlockBits),
|
|
(byte FAR1 *)signRead, BDK_SIGNATURE_NAME ,EXTRA);
|
|
if(status!=flOK)
|
|
{
|
|
DEBUG_PRINT(("(EXTRA)read failed.\r\n"));
|
|
return status;
|
|
}
|
|
|
|
if( tffscmp( (void FAR1 *)oldSign,
|
|
(void FAR1 *)(signRead), BDK_SIGNATURE_NAME ) == 0 )
|
|
break;
|
|
}
|
|
if( iBlock > bdkVol->endImageBlock )
|
|
return( flNoSpaceInVolume );
|
|
|
|
checkStatus(flash->erase(flash, iBlock, 1 ));
|
|
checkStatus(flash->write(flash, bdkVol->bdkSignOffset +
|
|
((CardAddress)iBlock << bdkVol->erasableBlockBits),
|
|
(byte FAR1 *)bdkVol->signBuffer, SIGNATURE_LEN, EXTRA));
|
|
}
|
|
|
|
bdkVol->actualUpdateLen = 0L;
|
|
return( flOK );
|
|
}
|
|
#endif /* CREATE_BDK_IMAGE */
|
|
#endif /* UPDATE_BDK_IMAGE */
|
|
|
|
#ifdef BDK_IMAGE_TO_FILE
|
|
#include <stdio.h>
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k C o p y B o o t A r e a F i l e
|
|
*
|
|
* Copy the BDK Image from the DiskOnChip to file 'fname' starting at
|
|
* 'startAddress', with a size of 'areaLen' bytes.
|
|
*
|
|
* Note : Blocks in the DiskOnChip are marked with a 4-character signature
|
|
* followed by a 4-digit hexadecimal number.
|
|
*
|
|
* Parameters: 'fname' - pointer to file name
|
|
* 'startUnit' - start block in image for reading
|
|
* 'areaLen' - BDK image size
|
|
* 'checkSum' - pointer to the checksum modulo 0x100
|
|
* 'signature' - 4-character signature of storage units
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - was this partition accessed before
|
|
* bdkSavedSignBuffer - signature offset of previous access
|
|
* bdkSignOffset - current signature offset
|
|
*
|
|
* global variable output :
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* signBuffer - initialize with given signature
|
|
* bdkSavedSignBuffer - save current signatur for next access
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* curReadImageAddress - address of last unit read
|
|
* actualReadLen - 0
|
|
*
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flGeneralFailure - could not open file
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW read protection was triggerd
|
|
*
|
|
* Routine for BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
FLStatus bdkCopyBootAreaFile( Sbyte FAR2 *fname, word startUnit, dword areaLen,
|
|
byte FAR2 *checkSum, byte FAR2 *signature )
|
|
{
|
|
dword curLen;
|
|
word copyLen;
|
|
FILE *fout;
|
|
byte buf[BLOCK];
|
|
|
|
checkStatus(bdkCopyBootAreaInit( startUnit, areaLen, signature ));
|
|
|
|
if( (fout = fopen(fname,"wb")) == NULL )
|
|
return( flGeneralFailure );
|
|
|
|
#ifdef BDK_CHECK_SUM
|
|
*checkSum = 0;
|
|
#endif /* BDK_CHECK_SUM */
|
|
for(curLen=0L;( curLen < areaLen );curLen+=BLOCK)
|
|
{
|
|
copyLen = (word)BDK_MIN((areaLen - curLen), BLOCK);
|
|
checkStatus(bdkCopyBootAreaBlock( (byte FAR1 *)buf, copyLen, checkSum ));
|
|
fwrite( buf, 1, copyLen, fout );
|
|
}
|
|
fclose(fout);
|
|
return( flOK );
|
|
}
|
|
|
|
#ifdef UPDATE_BDK_IMAGE
|
|
|
|
/*-------------------------------------------------------------------
|
|
* b d k U p d a t e B o o t A r e a F i l e
|
|
*
|
|
* Copy the BDK Image to the DiskOnChip from the file 'fname' starting at
|
|
* 'startUnit', with a size of 'areaLen' bytes and 'signature'.
|
|
*
|
|
* Note : Blocks in the DiskOnChip are marked with a 4-character signature
|
|
* followed by a 4-digit hexadecimal number.
|
|
*
|
|
* Parameters: 'fname' - pointer to file name
|
|
* 'startUnit' - start block in image for reading
|
|
* 'areaLen' - BDK image size
|
|
* 'signature' - 4-character signature of storage units
|
|
*
|
|
* global variable input :
|
|
* bdkVol - current binary partition record
|
|
* flash - flash record enabling media I\O
|
|
* bdkGlobalStatus - was this partition accessed before
|
|
* bdkSavedSignBuffer - signature offset of previous access
|
|
* bdkSignOffset - current signature offset
|
|
*
|
|
* global variable output :
|
|
* bdkGlobalStatus - set to BDK_S_INFO_FOUND
|
|
* signBuffer - initialize with given signature
|
|
* bdkSavedSignBuffer - save current signatur for next access
|
|
* bootImageSize - size of the entire sub partition in bytes
|
|
* realBootImageSize - number of units writen in the sub partition
|
|
* startPartitionBlock - low physical boundry of the partition
|
|
* endPartitionBlock - high physical boundry of the partition
|
|
* startImageBlock - physical unit number of the first and
|
|
* endImageBlock last units marked with the signature
|
|
* actualUpdateLen - 0
|
|
* curUpadateImageAddress - address of last written unit
|
|
* Return :
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flGeneralFailure - could not open file
|
|
* flUnknownMedia - failed in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flNoSpaceInVolume - there are 0 units marked with this signature
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW protection was triggerd
|
|
* flWriteFault - MTD write fault
|
|
*
|
|
* Routine for BDK stand alone package.
|
|
*-------------------------------------------------------------------*/
|
|
FLStatus bdkUpdateBootAreaFile( Sbyte FAR2 *fname, word startUnit,
|
|
dword areaLen , byte FAR2 *signature )
|
|
{
|
|
dword curLen;
|
|
word copyLen;
|
|
FILE *fout;
|
|
byte buf[BLOCK];
|
|
|
|
checkStatus(bdkUpdateBootAreaInit( startUnit, areaLen,
|
|
BDK_COMPLETE_IMAGE_UPDATE, signature ));
|
|
|
|
if( (fout = fopen(fname,"rb")) == NULL )
|
|
return(flGeneralFailure);
|
|
|
|
for(curLen=0L;( curLen < areaLen );curLen+=BLOCK)
|
|
{
|
|
copyLen = (word)BDK_MIN((areaLen - curLen), BLOCK);
|
|
fread( buf, 1, copyLen, fout );
|
|
checkStatus(bdkUpdateBootAreaBlock( (byte FAR1 *)buf, copyLen ));
|
|
}
|
|
fclose(fout);
|
|
return( flOK );
|
|
}
|
|
#endif /* UPDATE_BDK_IMAGE */
|
|
#endif /* BDK_IMAGE_TO_FILE */
|
|
|
|
#ifdef PROTECT_BDK_IMAGE
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* p r o t e c t i o n I n i t
|
|
*
|
|
* Makes suer the volume is mounted before calling protection calls.
|
|
*
|
|
* Note this routine is called directly by each of the protection routines
|
|
*
|
|
* return
|
|
* FLStatus flOK otherwise respective error code.
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
static FLStatus protectionInit(void)
|
|
{
|
|
/* Check that the partition is mounted */
|
|
#ifdef MTD_STANDALONE
|
|
dword temp;
|
|
|
|
checkStatus(bdkFindDiskOnChip((dword FAR2 *)&temp,(dword FAR2 *)&temp));
|
|
#endif /* MTD_STANDALONE */
|
|
checkStatus(bdkMount());
|
|
if (bdkVol->flash->flags & NFTL_ENABLED)
|
|
{
|
|
DEBUG_PRINT(("NFTL does not support protection.\r\n"));
|
|
return flFeatureNotSupported;
|
|
}
|
|
|
|
if ((bdkVol->protectionType & PROTECTABLE) == 0)
|
|
{
|
|
DEBUG_PRINT(("Not a protectable partition.\r\n"));
|
|
return flNotProtected;
|
|
}
|
|
return flOK;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* p r o t e c t i o n C h a n g e I n i t
|
|
*
|
|
* Makes sure the volume is mounted before calling protection calls.
|
|
* Makes sure the protection can be updated and functions arae vailable
|
|
*
|
|
* Note this routine is called directly by each of the protection routines
|
|
*
|
|
* return
|
|
* FLStatus flOK on success non zero otherwise
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
static FLStatus protectionChangeInit(word * type)
|
|
{
|
|
checkStatus(protectionInit());
|
|
|
|
if (!(bdkVol->protectionType & CHANGEABLE_PROTECTION))
|
|
{
|
|
DEBUG_PRINT(("Uncheangable protection.\r\n"));
|
|
return flFeatureNotSupported;
|
|
}
|
|
|
|
if ((bdkVol->flash->protectionBoundries == NULL) ||
|
|
(bdkVol->flash->protectionSet == NULL) ||
|
|
(bdkVol->flash->protectionKeyInsert == NULL) ||
|
|
(bdkVol->flash->protectionType == NULL))
|
|
{
|
|
DEBUG_PRINT(("H/W does not support protection.\r\n"));
|
|
return flFeatureNotSupported;
|
|
}
|
|
|
|
/* get the protection type */
|
|
checkStatus(bdkVol->flash->protectionType(bdkVol->flash,
|
|
bdkVol->protectionArea, (word *)type));
|
|
return (bdkVol->flash->protectionKeyInsert(bdkVol->flash,
|
|
bdkVol->protectionArea, (byte *)DEFAULT_KEY));
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* b d k G e t P r o t e c t i o n T y p e
|
|
*
|
|
* Return the current partition protection type.
|
|
*
|
|
*
|
|
* Parameters : 'protectionType' - return the protection type as a
|
|
* combination of the following flags:
|
|
*
|
|
* PROTECTABLE - A protection area is allocated for this volume
|
|
* LOCK_ENABLED - HW Lock signal is enabled.
|
|
* LOCK_ASSERTED - HW Lock signal is asserted.
|
|
* KEY_INSERTED - Key is currently inserted (protection is down).
|
|
* READ_PROTECTED - Area is protected against read operations.
|
|
* WRITE_PROTECTED - Area is protected against write operations.
|
|
* CHANGEABLE_PROTECTION - The area is protected against write operations.
|
|
*
|
|
* global variable input :
|
|
* bdkGlobalStatus - was this device found before
|
|
* bdkVol - current binary partition record
|
|
* bdkDocWindow - if > 0 only this address will be checked
|
|
*
|
|
* global variable output :
|
|
* bdkVol - current binary partition record
|
|
* bdkGlobalStatus - both BDK_S_DOC_FOUND and BDK_S_HEADER_FOUND
|
|
* flash - identify flash media and its socket
|
|
* bdkDocWindow - DiskOnChip window physical address
|
|
*
|
|
* Return:
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - fail in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW read protection was triggerd
|
|
* flFeatureNotSupported - The HW protection feature is not supported
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*------------------------------------------------------------------------*/
|
|
FLStatus bdkGetProtectionType (word * protectionType)
|
|
{
|
|
FLStatus status;
|
|
status = protectionInit();
|
|
|
|
switch (status)
|
|
{
|
|
case flOK:
|
|
if (bdkVol->flash->protectionType==NULL)
|
|
return flFeatureNotSupported;
|
|
checkStatus (bdkVol->flash->protectionType(bdkVol->flash,
|
|
bdkVol->protectionArea, (word *)protectionType));
|
|
|
|
*protectionType &= ~((word)(PROTECTABLE | CHANGEABLE_PROTECTION));
|
|
*protectionType |= (word)(bdkVol->protectionType & (word)(PROTECTABLE | CHANGEABLE_PROTECTION));
|
|
return status;
|
|
case flNotProtected:
|
|
*protectionType = 0;
|
|
default:
|
|
return status;
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* b d k I n s e r t K e y
|
|
*
|
|
* Insert the protection key to disable the HW protection.
|
|
*
|
|
* Parameters : 'key' - The key to send
|
|
*
|
|
* global variable input :
|
|
* bdkGlobalStatus - was this device found before
|
|
* bdkVol - current binary partition record
|
|
* bdkDocWindow - if > 0 only this address will be checked
|
|
*
|
|
* global variable output :
|
|
* bdkVol - current binary partition record
|
|
* bdkGlobalStatus - both BDK_S_DOC_FOUND and BDK_S_HEADER_FOUND
|
|
* flash - identify flash media and its socket
|
|
* bdkDocWindow - DiskOnChip window physical address
|
|
*
|
|
* Return:
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - fail in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW read protection was triggerd
|
|
* flFeatureNotSupported - The HW protection feature is not supported
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*------------------------------------------------------------------------*/
|
|
FLStatus bdkInsertKey (byte FAR1* key)
|
|
{
|
|
checkStatus(protectionInit());
|
|
|
|
if (bdkVol->flash->protectionKeyInsert==NULL)
|
|
return flFeatureNotSupported;
|
|
return (bdkVol->flash->protectionKeyInsert(bdkVol->flash,
|
|
bdkVol->protectionArea, key));
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* b d k R e m o v e K e y
|
|
*
|
|
* Return the current partition protection type.
|
|
*
|
|
* Parameters : None
|
|
*
|
|
* global variable input :
|
|
* bdkGlobalStatus - was this device found before
|
|
* bdkVol - current binary partition record
|
|
* bdkDocWindow - if > 0 only this address will be checked
|
|
*
|
|
* global variable output :
|
|
* bdkVol - current binary partition record
|
|
* bdkGlobalStatus - both BDK_S_DOC_FOUND and BDK_S_HEADER_FOUND
|
|
* flash - identify flash media and its socket
|
|
* bdkDocWindow - DiskOnChip window physical address
|
|
*
|
|
* Return:
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - fail in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW read protection was triggerd
|
|
* flFeatureNotSupported - The HW protection feature is not supported
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*------------------------------------------------------------------------*/
|
|
FLStatus bdkRemoveKey (void)
|
|
{
|
|
checkStatus(protectionInit());
|
|
|
|
if ((bdkVol->flash->flags & NFTL_ENABLED) ||
|
|
(bdkVol->flash->protectionKeyRemove==NULL))
|
|
return flFeatureNotSupported;
|
|
return (bdkVol->flash->protectionKeyRemove(bdkVol->flash,
|
|
bdkVol->protectionArea));
|
|
|
|
}
|
|
/*--------------------------------------------------------------------------
|
|
* b d k L o c k E n a b l e
|
|
*
|
|
* Enable or disable the HW LOCK signal.
|
|
*
|
|
* Note : The protction key must be off before calling this routine.
|
|
* While asserted the HW LOCK signal can not be disabled.
|
|
*
|
|
* Parameters : 'enabled' - LOCK_ENABLED - enables the HW LOCK
|
|
* otherwise disabled
|
|
*
|
|
* global variable input :
|
|
* bdkGlobalStatus - was this device found before
|
|
* bdkVol - current binary partition record
|
|
* bdkDocWindow - if > 0 only this address will be checked
|
|
*
|
|
* global variable output :
|
|
* bdkVol - current binary partition record
|
|
* bdkGlobalStatus - both BDK_S_DOC_FOUND and BDK_S_HEADER_FOUND
|
|
* flash - identify flash media and its socket
|
|
* bdkDocWindow - DiskOnChip window physical address
|
|
*
|
|
* Return:
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - fail in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW protection was triggerd
|
|
* flWriteFault - MTD write fault
|
|
* flFeatureNotSupported - The HW protection feature is not supported
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*------------------------------------------------------------------------*/
|
|
FLStatus bdkLockEnable (byte enabled)
|
|
{
|
|
CardAddress low,high;
|
|
word type;
|
|
byte floorNo;
|
|
|
|
checkStatus(protectionChangeInit(&type));
|
|
|
|
if (enabled == LOCK_ENABLED)
|
|
{
|
|
type |= LOCK_ENABLED;
|
|
}
|
|
else
|
|
{
|
|
type &= ~LOCK_ENABLED;
|
|
}
|
|
|
|
for (floorNo=0;floorNo<bdkVol->flash->noOfFloors;floorNo++)
|
|
{
|
|
/* Find boundries */
|
|
checkStatus(bdkVol->flash->protectionBoundries(bdkVol->flash,
|
|
bdkVol->protectionArea,&low,&high,floorNo));
|
|
|
|
/* Set new protection values */
|
|
checkStatus(bdkVol->flash->protectionSet(bdkVol->flash,
|
|
bdkVol->protectionArea,(word)((high == 0) ? PROTECTABLE : type),low,high,
|
|
NULL,(byte)((floorNo == bdkVol->flash->noOfFloors - 1) ?
|
|
COMMIT_PROTECTION : DO_NOT_COMMIT_PROTECTION),floorNo));
|
|
}
|
|
return flOK;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* b d k C h a n g e K e y
|
|
*
|
|
* Change the protection key of a protected binary partition..
|
|
*
|
|
* Note : The protction key must be off before calling this routine.
|
|
*
|
|
* Parameters : 'key' - The new protection key.
|
|
*
|
|
* global variable input :
|
|
* bdkGlobalStatus - was this device found before
|
|
* bdkVol - current binary partition record
|
|
* bdkDocWindow - if > 0 only this address will be checked
|
|
*
|
|
* global variable output :
|
|
* bdkVol - current binary partition record
|
|
* bdkGlobalStatus - both BDK_S_DOC_FOUND and BDK_S_HEADER_FOUND
|
|
* flash - identify flash media and its socket
|
|
* bdkDocWindow - DiskOnChip window physical address
|
|
*
|
|
* Return:
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - fail in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW protection was triggerd
|
|
* flWriteFault - MTD write fault
|
|
* flFeatureNotSupported - The HW protection feature is not supported
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*------------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkChangeKey(byte FAR1 * key)
|
|
{
|
|
CardAddress low,high;
|
|
word type;
|
|
byte floorNo;
|
|
|
|
checkStatus(protectionChangeInit(&type));
|
|
|
|
for (floorNo=0;floorNo<bdkVol->flash->noOfFloors;floorNo++)
|
|
{
|
|
/* Find boundries */
|
|
checkStatus(bdkVol->flash->protectionBoundries(bdkVol->flash,
|
|
bdkVol->protectionArea,&low,&high,floorNo));
|
|
|
|
/* Set new protection values */
|
|
checkStatus(bdkVol->flash->protectionSet(bdkVol->flash,
|
|
bdkVol->protectionArea,(word)((high == 0) ? PROTECTABLE : type),
|
|
low,high,key,(byte)((floorNo == bdkVol->flash->noOfFloors - 1)
|
|
? COMMIT_PROTECTION : DO_NOT_COMMIT_PROTECTION),floorNo));
|
|
}
|
|
return flOK;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* b d k S e t P r o t e c t i o n T y p e
|
|
*
|
|
* Change the current partition protection type.
|
|
*
|
|
*
|
|
* Parameters : 'protectionType' - change the protection type as a
|
|
* combination of the following flags:
|
|
*
|
|
* PROTECTABLE - Must be added for the routine to work.
|
|
* READ_PROTECTED - Area is protected against read operations.
|
|
* WRITE_PROTECTED - Area is protected against write operations.
|
|
*
|
|
* Note - To add extra protection only a combination of the above 3 flags is
|
|
* aceptable and the PROTECTABLE flag must be on.
|
|
*
|
|
* global variable input :
|
|
* bdkGlobalStatus - was this device found before
|
|
* bdkVol - current binary partition record
|
|
* bdkDocWindow - if > 0 only this address will be checked
|
|
*
|
|
* global variable output :
|
|
* bdkVol - current binary partition record
|
|
* bdkGlobalStatus - both BDK_S_DOC_FOUND and BDK_S_HEADER_FOUND
|
|
* flash - identify flash media and its socket
|
|
* bdkDocWindow - DiskOnChip window physical address
|
|
*
|
|
* Return:
|
|
* flOK - success
|
|
* flDriveNotAvailable - DiskOnChip ASIC was not found
|
|
* flUnknownMedia - fail in Flash chips recognition
|
|
* flBadDownload - DiskOnChip Millennium Plus reported an uncorrectable
|
|
* protection violation. This device is unusable.
|
|
* flBadFormat - TL format does not exists
|
|
* flDataError - MTD read fault.
|
|
* flHWProtect - HW protection was triggerd
|
|
* flWriteFault - MTD write fault
|
|
* flFeatureNotSupported - The HW protection feature is not supported
|
|
*
|
|
* Routine for both OSAK and the BDK stand alone package.
|
|
*------------------------------------------------------------------------*/
|
|
FLStatus bdkSetProtectionType (word newType)
|
|
{
|
|
CardAddress low,high;
|
|
word type;
|
|
byte floorNo;
|
|
|
|
checkStatus(protectionChangeInit(&type));
|
|
|
|
if (((newType & (READ_PROTECTED | WRITE_PROTECTED | PROTECTABLE)) != newType) ||
|
|
((newType & PROTECTABLE) == 0))
|
|
return flBadParameter;
|
|
|
|
newType |= type & ~(READ_PROTECTED | WRITE_PROTECTED);
|
|
|
|
for (floorNo=0;floorNo<bdkVol->flash->noOfFloors;floorNo++)
|
|
{
|
|
/* Find boundries */
|
|
checkStatus(bdkVol->flash->protectionBoundries(bdkVol->flash,
|
|
bdkVol->protectionArea,&low,&high,floorNo));
|
|
|
|
/* Set new protection values */
|
|
checkStatus(bdkVol->flash->protectionSet(bdkVol->flash,
|
|
bdkVol->protectionArea,(word)((high == 0) ? PROTECTABLE : newType),
|
|
low,high,NULL,(byte)((floorNo == bdkVol->flash->noOfFloors - 1)
|
|
? COMMIT_PROTECTION : DO_NOT_COMMIT_PROTECTION),floorNo));
|
|
}
|
|
return flOK;
|
|
}
|
|
|
|
#endif /* PROTECT_BDK_IMAGE */
|
|
|
|
#if (defined(HW_OTP) && defined (MTD_STANDALONE))
|
|
/*----------------------------------------------------------------------*/
|
|
/* b d k G e t U n i q u e I d */
|
|
/* */
|
|
/* Retreave the device 16 bytes unique ID. */
|
|
/* */
|
|
/* Parameters: */
|
|
/* buffer : buffer to read into. */
|
|
/* */
|
|
/* Returns: */
|
|
/* flOK - success */
|
|
/* flDriveNotAvailable - DiskOnChip ASIC was not found */
|
|
/* flUnknownMedia - Failed in Flash chips recognition */
|
|
/* flBadDownload - MdocPlus device has unrecoverable */
|
|
/* protection violation. */
|
|
/* flHWProtection - HW read protection violation. */
|
|
/* flTimedOut - Flash delay not long enough. */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkGetUniqueID(byte FAR1* buf)
|
|
{
|
|
dword temp;
|
|
|
|
checkStatus(bdkFindDiskOnChip((dword FAR2 *)&temp,(dword FAR2 *)&temp));
|
|
if (bdkVol->flash->getUniqueId == NULL)
|
|
return flFeatureNotSupported;
|
|
return(bdkVol->flash->getUniqueId(bdkVol->flash,buf));
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* b d k R e a d O T P */
|
|
/* */
|
|
/* Read data from the customer OTP. */
|
|
/* */
|
|
/* Parameters: */
|
|
/* offset : Offset from the beginning of OTP area to read from. */
|
|
/* buffer : buffer to read into. */
|
|
/* length : number of bytes to read. */
|
|
/* */
|
|
/* Returns: */
|
|
/* flOK - success */
|
|
/* flDriveNotAvailable - DiskOnChip ASIC was not found */
|
|
/* flUnknownMedia - Failed in Flash chips recognition */
|
|
/* flBadDownload - MdocPlus device has unrecoverable */
|
|
/* protection violation. */
|
|
/* flHWProtection - HW read protection violation. */
|
|
/* flTimedOut - Flash delay not long enough. */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkReadOtp(word offset,byte FAR1 * buffer,word length)
|
|
{
|
|
dword temp;
|
|
|
|
checkStatus(bdkFindDiskOnChip((dword FAR2 *)&temp,(dword FAR2 *)&temp));
|
|
if (bdkVol->flash->readOTP == NULL)
|
|
return flFeatureNotSupported;
|
|
return(bdkVol->flash->readOTP(bdkVol->flash,offset,buffer,length));
|
|
}
|
|
|
|
#ifndef FL_READ_ONLY
|
|
/*----------------------------------------------------------------------*/
|
|
/* b d k W r i t e A n d L o c k O T P */
|
|
/* */
|
|
/* Write and lock the customer OTP. */
|
|
/* */
|
|
/* Parameters: */
|
|
/* buffer : buffer to write from. */
|
|
/* length : number of bytes to write. */
|
|
/* */
|
|
/* Note - Once writen (even a single byte) the entire section is */
|
|
/* locked forever. The data is written with EDC. */
|
|
/* */
|
|
/* Returns: */
|
|
/* flOK - success */
|
|
/* flDriveNotAvailable - DiskOnChip ASIC was not found */
|
|
/* flUnknownMedia - Failed in Flash chips recognition */
|
|
/* flBadDownload - MdocPlus device has unrecoverable */
|
|
/* protection violation. */
|
|
/* flHWProtection - HW protection violation. */
|
|
/* flTimedOut - Flash delay not long enough. */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkWriteAndLockOtp(const byte FAR1 * buffer,word length)
|
|
{
|
|
dword temp;
|
|
|
|
checkStatus(bdkFindDiskOnChip((dword FAR2 *)&temp,(dword FAR2 *)&temp));
|
|
if (bdkVol->flash->writeOTP == NULL)
|
|
return flFeatureNotSupported;
|
|
return(bdkVol->flash->writeOTP(bdkVol->flash,buffer,length));
|
|
}
|
|
#endif /* FL_READ_ONLY */
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* b d k G e t O t p S i z e */
|
|
/* */
|
|
/* Returns the size and state of the OTP area. */
|
|
/* */
|
|
/* Parameters: */
|
|
/* sectionSize : Total OTP size. */
|
|
/* usedSize : Used OTP size. */
|
|
/* locked : Lock state (LOCKED_OTP for locked). */
|
|
/* */
|
|
/* Returns: */
|
|
/* flOK - success */
|
|
/* flDriveNotAvailable - DiskOnChip ASIC was not found */
|
|
/* flUnknownMedia - Failed in Flash chips recognition */
|
|
/* flBadDownload - MdocPlus device has unrecoverable */
|
|
/* protection violation. */
|
|
/* flHWProtection - HW read protection violation. */
|
|
/* flTimedOut - Flash delay not long enough. */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkGetOtpSize(dword FAR2* sectionSize, dword FAR2* usedSize, word FAR2* locked)
|
|
{
|
|
dword temp;
|
|
|
|
checkStatus(bdkFindDiskOnChip((dword FAR2 *)&temp,(dword FAR2 *)&temp));
|
|
if (bdkVol->flash->otpSize == NULL)
|
|
return flFeatureNotSupported;
|
|
return(bdkVol->flash->otpSize(bdkVol->flash,sectionSize,usedSize,locked));
|
|
}
|
|
#endif /* HW_OTP */
|
|
#ifdef BDK_ACCESS
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* b d k C a l l */
|
|
/* */
|
|
/* Common entry-point to all binary partition functions. */
|
|
/* */
|
|
/* Note : the error codes and global variable changed by this routin */
|
|
/* depened on the functionNo parameter and can be deduced from the */
|
|
/* coresponding routine in the BDK package or from the OSAK manual */
|
|
/* */
|
|
/* Parameters: */
|
|
/* functionNo : file-system function code (listed below) */
|
|
/* ioreq : IOreq structure */
|
|
/* flash : flash record supplied hardware information and */
|
|
/* flash access routines */
|
|
/* Returns: */
|
|
/* FLStatus : 0 on success, otherwise failed */
|
|
/* */
|
|
/* Routine for OSAK package. */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FLStatus bdkCall(FLFunctionNo functionNo, IOreq FAR2 *ioreq, FLFlash* flash)
|
|
{
|
|
FLStatus status;
|
|
BDKStruct* bdkParam = (BDKStruct*)ioreq->irData;
|
|
byte volNo;
|
|
|
|
globalSocketNo = FL_GET_SOCKET_FROM_HANDLE(ioreq);
|
|
globalPartitionNo = FL_GET_PARTITION_FROM_HANDLE(ioreq);
|
|
|
|
/* convert drive handle to the appropriate binary partition record */
|
|
|
|
if (globalSocketNo>SOCKETS)
|
|
return flBadDriveHandle;
|
|
if (globalPartitionNo>MAX_BINARY_PARTITIONS_PER_DRIVE)
|
|
return flBadDriveHandle;
|
|
|
|
volNo = handleTable[globalSocketNo][globalPartitionNo];
|
|
|
|
if (volNo!=BDK_INVALID_VOLUME_HANDLE) /* not first access to this device */
|
|
{
|
|
bdkVol = &bdkVols[volNo];
|
|
}
|
|
else /* first access to this device */
|
|
{
|
|
bdkVol = &bdkVols[noOfPartitions];
|
|
bdkVol->flash = flash;
|
|
bdkVol->bdkGlobalStatus = BDK_S_DOC_FOUND;
|
|
}
|
|
|
|
#ifdef VERIFY_WRITE
|
|
/* Set binary partition verify write state */
|
|
flash->socket->verifyWrite = flVerifyWrite[globalSocketNo][globalPartitionNo+MAX_TL_PARTITIONS];
|
|
#endif /* VERIFY_WRITE */
|
|
|
|
/* Call the proper binary partition function */
|
|
|
|
switch (functionNo)
|
|
{
|
|
case FL_BINARY_READ_INIT:
|
|
|
|
bdkVol->bdkEDC = bdkParam->flags & EDC;
|
|
bdkVol->bdkSignOffset = bdkParam->signOffset;
|
|
return bdkCopyBootAreaInit((word)bdkParam->startingBlock,
|
|
bdkParam->length,bdkParam->oldSign);
|
|
case FL_BINARY_READ_BLOCK:
|
|
|
|
return bdkCopyBootAreaBlock(bdkParam->bdkBuffer,
|
|
(word)bdkParam->length,NULL);
|
|
|
|
case FL_BINARY_PARTITION_INFO:
|
|
{
|
|
dword unitSize;
|
|
|
|
#ifndef NT5PORT
|
|
int volNo;
|
|
#else /*NT5PORT*/
|
|
int nIndex;
|
|
#endif /*NT5PORT*/
|
|
|
|
status = bdkGetBootPartitionInfo((word)bdkParam->startingBlock,
|
|
&(bdkParam->startingBlock), &(bdkParam->length),&unitSize,
|
|
bdkParam->oldSign);
|
|
ioreq->irLength = (long)(bdkVol->endPartitionBlock -
|
|
bdkVol->startPartitionBlock + 1)<<(long)bdkVol->flash->erasableBlockSizeBits;
|
|
bdkParam->flags = 0;
|
|
|
|
#ifndef NT5PORT
|
|
for (volNo = 0;volNo < MAX_BINARY_PARTITIONS_PER_DRIVE;volNo++)
|
|
{
|
|
if (handleTable[globalSocketNo][volNo]!=
|
|
BDK_INVALID_VOLUME_HANDLE)
|
|
bdkParam->flags++;
|
|
}
|
|
#else /*NT5PORT*/
|
|
for (nIndex = 0;nIndex < MAX_BINARY_PARTITIONS_PER_DRIVE; nIndex++)
|
|
{
|
|
if (handleTable[globalSocketNo][nIndex]!=
|
|
BDK_INVALID_VOLUME_HANDLE)
|
|
bdkParam->flags++;
|
|
}
|
|
#endif /*NT5PORT*/
|
|
|
|
return status;
|
|
}
|
|
#ifdef UPDATE_BDK_IMAGE
|
|
|
|
case FL_BINARY_WRITE_INIT:
|
|
bdkVol->bdkEDC = bdkParam->flags & EDC;
|
|
bdkVol->bdkSignOffset = bdkParam->signOffset;
|
|
return bdkUpdateBootAreaInit((word)bdkParam->startingBlock, bdkParam->length,
|
|
bdkParam->flags , bdkParam->oldSign);
|
|
case FL_BINARY_WRITE_BLOCK:
|
|
if (bdkParam->flags & ERASE_BEFORE_WRITE)
|
|
{
|
|
bdkVol->updateImageFlag |= ERASE_BEFORE_WRITE;
|
|
}
|
|
else
|
|
{
|
|
bdkVol->updateImageFlag &= ~ ERASE_BEFORE_WRITE;
|
|
}
|
|
return bdkUpdateBootAreaBlock(bdkParam->bdkBuffer, (word)bdkParam->length);
|
|
|
|
#ifdef CREATE_BDK_IMAGE
|
|
case FL_BINARY_CREATE:
|
|
|
|
bdkVol->bdkSignOffset = bdkParam->signOffset;
|
|
return bdkCreateBootArea((word)bdkParam->length,bdkParam->oldSign,
|
|
bdkParam->newSign);
|
|
#endif /* CREATE_BDK_IMAGE */
|
|
#ifdef ERASE_BDK_IMAGE
|
|
|
|
case FL_BINARY_ERASE:
|
|
|
|
bdkVol->bdkSignOffset = bdkParam->signOffset;
|
|
return bdkEraseBootArea((word)bdkParam->startingBlock,(word)bdkParam->length,
|
|
bdkParam->oldSign);
|
|
#endif /* ERASE_BDK_IMAGE */
|
|
#endif /* UPDATE_BDK_IMAGE */
|
|
#ifdef PROTECT_BDK_IMAGE
|
|
case FL_BINARY_PROTECTION_GET_TYPE:
|
|
{
|
|
word tmpFlags;
|
|
checkStatus ( bdkGetProtectionType (&tmpFlags));
|
|
ioreq->irFlags = (unsigned) tmpFlags;
|
|
return flOK;
|
|
}
|
|
|
|
case FL_BINARY_PROTECTION_SET_TYPE:
|
|
return bdkSetProtectionType ((word)ioreq->irFlags);
|
|
|
|
case FL_BINARY_PROTECTION_INSERT_KEY:
|
|
return bdkInsertKey ((byte FAR1*)ioreq->irData);
|
|
|
|
case FL_BINARY_PROTECTION_REMOVE_KEY:
|
|
return bdkRemoveKey ();
|
|
|
|
case FL_BINARY_PROTECTION_CHANGE_KEY:
|
|
return bdkChangeKey ((byte FAR1*)ioreq->irData);
|
|
|
|
case FL_BINARY_PROTECTION_CHANGE_LOCK:
|
|
return bdkLockEnable ((byte)ioreq->irFlags);
|
|
#endif /* PROTECT_BDK_IMAGE */
|
|
default: /* not a binary partition routine */
|
|
return flBadFunction;
|
|
}
|
|
}
|
|
#endif /* BDK_ACCESS */
|
|
|
|
#endif /* BDK_ACCESS || MTD_STANDALONE || ACCESS_BDK_IMAGE */
|