|
|
/*
* $Log: V:/Flite/archives/TrueFFS5/Src/PROTECTP.C_V $ * * Rev 1.18 Apr 15 2002 07:38:44 oris * Added static qualifier for private functions (findChecksum and makeDPS). * Removed readDPS and writeDPS routine prototypes (no longer exist). * Added setStickyBit routine for DiskOnChip Plus 128Mbit. * * Rev 1.17 Jan 28 2002 21:26:24 oris * Removed the use of back-slashes in macro definitions. * * Rev 1.16 Jan 17 2002 23:04:54 oris * Replaced docsysp include directive with docsys. * Changed the use of vol (macro *pVol) to *flash. * Add support for DiskOnChip Millennium Plus 16MB : * - Copy extra area of IPL independently of the EDC to copy Strong arm mark. * - DPS 0 and 1 location where changed - affects protectionSet routine. * Bug fix - Wrong usage of findChecksum, caused the use of the second copy of the DPS instead of the first. * * Rev 1.15 Sep 24 2001 18:24:18 oris * removed ifdef and forced using flRead8bitRegPlus instead of reading with flRead16bitRegPlus. * * Rev 1.14 Sep 15 2001 23:47:56 oris * Remove all 8-bit access to uneven addresses. * * Rev 1.13 Jul 16 2001 17:41:54 oris * Ignore write protection of the DPSs. * * Rev 1.12 Jul 13 2001 01:09:26 oris * Bug fix for protection boundaries when using Millennium Plus devices that can not access a single byte. * Added send default key before trying a protection violation command. * Bug fix - bad IPL second copy offset. * * Rev 1.11 May 16 2001 21:21:42 oris * Removed warnings. * * Rev 1.10 May 09 2001 00:35:48 oris * Bug fix - Lock asserted was reported opposite of the real state. * Bug fix - Make sure to return "key inserted" if the partition is not read\write protected. * This is to enable a partition that does not span over all of the media floors to return "key inserted". * * Rev 1.9 May 06 2001 22:42:18 oris * Bug fix - insert key does not try to insert key to a floor that is not read\write protected. * Bug fix - protection type does not return key inserted is one of the floors key is not inserted. * Bug fix - set protection no longer clears the IPL. * redundant was misspelled. * * Rev 1.8 May 01 2001 14:24:56 oris * Bug fix - CHANGEABLE_PRTOECTION was never reported. * * Rev 1.7 Apr 18 2001 17:19:02 oris * Bug fix - bad status code returned by protection set routine du to calling changaInterleave while in access error. * * Rev 1.6 Apr 18 2001 09:29:32 oris * Bug fix - remove key routine always return bad status code. * * Rev 1.5 Apr 16 2001 13:58:28 oris * Removed warrnings. * * Rev 1.4 Apr 12 2001 06:52:32 oris * Changed protectionBounries and protectionSet routine to be floor specific. * * Rev 1.3 Apr 10 2001 23:56:30 oris * Bug fix - protectionBounries routine - floor did not change. * Bug fix - protectionSet routine - floors with no protected areas were not updated. * Bug fix - protectionBounries routine - bad paranthesis in MAX calculation. * * Rev 1.2 Apr 09 2001 19:04:24 oris * Removed warrnings. * */
/*******************************************************************
* * DESCRIPTION: MTD protection mechanism routines for the MDOC32 * * AUTHOR: arie tamam * * HISTORY: created november 14, 2000 * *******************************************************************/
/** include files **/ #include "mdocplus.h"
#include "protectp.h"
#include "docsys.h"
/** local definitions **/
/* default settings */
/** external functions **/
/** external data **/
/** internal functions **/ static byte findChecksum(byte * buffer, word size); static void makeDPS(CardAddress addressLow, CardAddress addressHigh, byte FAR1* key , word flag, byte* buffer);
#define MINUS_FLOORSIZE(arg) ((arg > NFDC21thisVars->floorSize) ? arg - NFDC21thisVars->floorSize : 0)
/** public data **/
/** private data **/
/** public functions **/
#ifdef HW_PROTECTION
/**********/ /* Macros */ /**********/
/* check if key is correct */ #define isArea0Protected(flash) (((flRead8bitRegPlus(flash,NdataProtect0Status) & PROTECT_STAT_KEY_OK_MASK) != PROTECT_STAT_KEY_OK_MASK) ? TRUE : FALSE)
#define isArea1Protected(flash) (((flRead8bitRegPlus(flash,NdataProtect1Status) & PROTECT_STAT_KEY_OK_MASK) != PROTECT_STAT_KEY_OK_MASK) ? TRUE : FALSE)
/*----------------------------------------------------------------------*/ /* s e t S t i c k y B i t */ /* */ /* Set the sticky bit to prevent the insertion of the protection key. */ /* */ /* Parameters: */ /* flash : Pointer identifying drive. */ /* */ /* Returns: */ /* flOK on success, none zero otherwise. */ /*----------------------------------------------------------------------*/
FLStatus setStickyBit(FLFlash * flash) { volatile Reg8bitType val; register int i;
/* Raise the sticky bit, while keeping the other bits of the register */ for(i=0;i<flash->noOfFloors;i++) { /* Remove last bit */ val = flRead8bitRegPlus(flash, NoutputControl) | OUT_CNTRL_STICKY_BIT_ENABLE; flWrite8bitRegPlus(flash, NoutputControl, val); } return flOK; }
/*
** protectBoundries * * * PARAMETERS: * flash : Pointer identifying drive * area : indicated which protection area to work on. 0 or 1. * AddressLow : address of lower boundary of protected area * AddressHigh : address of upper boundary of protected area * * DESCRIPTION: Gets protection boundaries from registers * * NOTE : protection areas are assumed to be consequtive although they * may skip DPS , OTP and header units. * * RETURNS: * flOK on success * */
FLStatus protectionBoundries(FLFlash * flash, byte area,CardAddress* addressLow, CardAddress* addressHigh, byte floorNo) { /* Check mode of ASIC and set to NORMAL.*/ FLStatus status = chkASICmode(flash);
if(status != flOK) return status;
setFloor(flash,floorNo); switch (area) { case 0: /* data protect structure 0 */
/* read the data protect 0 addresses */
*addressLow = ((dword)flRead8bitRegPlus(flash,NdataProtect0LowAddr) << 10)| /* ADDR_1 */ ((dword)flRead8bitRegPlus(flash,NdataProtect0LowAddr+1) << 18); /* ADDR_2 */ *addressHigh = ((dword)flRead8bitRegPlus(flash,NdataProtect0UpAddr) << 10)| /* ADDR_1 */ ((dword)flRead8bitRegPlus(flash,NdataProtect0UpAddr+1) << 18); /* ADDR_2 */ break;
case 1: /* data protect structure 1 */
/* read the data protect 1 addresses */ *addressLow = ((dword)flRead8bitRegPlus(flash,NdataProtect1LowAddr) << 10)| /* ADDR_1 */ ((dword)flRead8bitRegPlus(flash,NdataProtect1LowAddr+1) << 18); /* ADDR_2 */ *addressHigh = ((dword)flRead8bitRegPlus(flash,NdataProtect1UpAddr) << 10)| /* ADDR_1 */ ((dword)flRead8bitRegPlus(flash,NdataProtect1UpAddr+1) << 18); /* ADDR_2 */ break;
default: /* No such protection area */
return flGeneralFailure; }
return(flOK); }
/*
** tryKey * * * PARAMETERS: * flash : Pointer identifying drive * area : indicated which protection area to work on. 0 or 1. * Key : an 8 byte long array containing the protection password. * unsigned char * is an 8 bytes unsigned char array * * DESCRIPTION: Sends protection key * * RETURNS: * flOK on success otherwise flWrongKey * */
FLStatus tryKey(FLFlash * flash, byte area, unsigned char FAR1* key) { int i;
switch (area) { case 0: /* data protect structure 0 */
for(i=0; i<PROTECTION_KEY_LENGTH; i++) /* Send key */ flWrite8bitRegPlus(flash,NdataProtect0Key, key[i]);
/* check if key is valid */ if (isArea0Protected(flash) == TRUE) { return flWrongKey; } else { return flOK; }
case 1: /* data protect structure 0 */
for(i=0; i<PROTECTION_KEY_LENGTH; i++) /* Send key */ flWrite8bitRegPlus(flash,NdataProtect1Key, key[i]);
/* check if key is valid */ if (isArea1Protected(flash) == TRUE) { return flWrongKey; } else { return flOK; }
default: /* No such protection area */
return flGeneralFailure; } }
/*
** protectKeyInsert * * * PARAMETERS: * flash : Pointer identifying drive * area : indicated which protection area to work on. 0 or 1. * Key : an 8 byte long array containing the protection password. * unsigned char * is an 8 bytes unsigned char array * * DESCRIPTION: Sends protection key only to protected areas. * * NOTE : If key is already inserted the given key will not be sent. * NOTE : The key will be sent to all the devices floors even if a key * did not fit one of them. * NOTE : This 2 notes above allow inserting diffrent key to * diffrent floors in the case of power failure while formmating * the device. * * RETURNS: * flOK on success otherwise flWrongKey * */
FLStatus protectionKeyInsert(FLFlash * flash, byte area, unsigned char FAR1* key) { byte floor; FLStatus status; FLStatus tmpStatus;
/* Check mode of ASIC and set to NORMAL.*/ status = chkASICmode(flash); if(status != flOK) return status;
/* Send key to all floors */ for (floor = 0;floor<flash->noOfFloors;floor++) { setFloor(flash,floor);
switch (area) { case 0: /* data protect structure 0 */
/* check if key is already inserted */ if ((isArea0Protected(flash) == FALSE) || /* Key is in */ ((flRead8bitRegPlus(flash,NdataProtect0Status) & /* Or not protected */ (PROTECT_STAT_WP_MASK | PROTECT_STAT_RP_MASK)) == 0)) continue;
break;
case 1: /* data protect structure 1 */
/* check if key is already inserted */ if ((isArea1Protected(flash) == FALSE) || /* Key is in */ ((flRead8bitRegPlus(flash,NdataProtect1Status) & /* Or not protected */ (PROTECT_STAT_WP_MASK | PROTECT_STAT_RP_MASK)) == 0)) continue; break;
default: /* No such protection area */
return flGeneralFailure; } tmpStatus = tryKey(flash,area,key); if (tmpStatus == flOK) continue;
/* Try default key */ tmpStatus = tryKey(flash,area,(byte *)DEFAULT_KEY); if (tmpStatus != flOK) status = tmpStatus; } return(status); }
/*
** protectKeyRemove * * * PARAMETERS: * flash : Pointer identifying drive * area : indicated which protection area to work on. 0 or 1. * * DESCRIPTION: Removes protection key * * RETURNS: * Return flOK * */
FLStatus protectionKeyRemove(FLFlash * flash, byte area) { byte tmpKey[8]; byte floor; FLStatus status;
for (floor = 0;floor < flash->noOfFloors;floor++) { setFloor(flash,floor); status = tryKey(flash,area,tmpKey); if (status == flOK) /* Unfortunatly the key was fine */ { tmpKey[0]++; status = tryKey(flash,area,tmpKey); } } return flOK; }
/*
** protectType * * * PARAMETERS: * flash : Pointer identifying drive. * area : indicated which protection area to work on. 0 or 1. * flag : returns any combination of * LOCK_ENABLED - The LOCK signal is enabled. * LOCK_ASSERTED - The LOCK signal input pin is asserted. * KEY_INSERTED - The key has been correctly written * READ_PROTECTED - The area is protected against read operations * WRITE_PROTECTED - The area is protected against write operations * * DESCRIPTION: Gets protection type * * NOTE: The type is checked for all floors. The attributes are ored * giving the harshest protection attributes. * * RETURNS: * flOK on success */
FLStatus protectionType(FLFlash * flash, byte area, word* flag) { volatile Reg8bitType protectData; byte floor; FLBoolean curFlag; /* Indicated if the floor has r/w protection */ CardAddress addressLow,addressHigh; FLStatus status;
status = chkASICmode(flash); if(status != flOK) return status;
*flag = KEY_INSERTED | LOCK_ASSERTED; /* initiate the flags */
for (floor = 0;floor < flash->noOfFloors;floor++) { setFloor(flash,floor);
/* read data protect structure status */
switch (area) { case 0: /* data protect structure 0 */
protectData = flRead8bitRegPlus(flash,NdataProtect0Status) ; break;
case 1: /* data protect structure 1 */
protectData = flRead8bitRegPlus(flash,NdataProtect1Status) ; *flag |= CHANGEABLE_PROTECTION; break;
default: /* No such protection area */
return flGeneralFailure; } curFlag = FALSE; /* Check if area is write protected */ if((protectData & PROTECT_STAT_WP_MASK) ==PROTECT_STAT_WP_MASK) { status = protectionBoundries(flash, area, &addressLow, &addressHigh, floor); if(status != flOK) return status;
if ((addressLow != addressHigh) || (addressLow != ((CardAddress)(area + 1)<<flash->erasableBlockSizeBits))) { *flag |= WRITE_PROTECTED; curFlag = TRUE; } } /* Check if area is read protected */ if((protectData & PROTECT_STAT_RP_MASK) ==PROTECT_STAT_RP_MASK) { *flag |= READ_PROTECTED; curFlag = TRUE; } /* Check if key is corrently inserted */ if(((protectData & PROTECT_STAT_KEY_OK_MASK) != PROTECT_STAT_KEY_OK_MASK) && (curFlag == TRUE)) *flag &= ~KEY_INSERTED; /* Check if HW signal is enabled */ if((protectData & PROTECT_STAT_LOCK_MASK) == PROTECT_STAT_LOCK_MASK) *flag |=LOCK_ENABLED ; /* Check if HW signal is asserted */ if((flRead8bitRegPlus(flash,NprotectionStatus) & PROTECT_STAT_LOCK_INPUT_MASK) == PROTECT_STAT_LOCK_INPUT_MASK) *flag &= ~LOCK_ASSERTED; } return(flOK); }
#ifndef FL_READ_ONLY
static byte findChecksum(byte * buffer, word size) { register int i; byte answer;
answer = 0xff; for(i=0 ; i<size ; i++) answer -= buffer[i]; return answer; }
/*
** SetProtection * * * PARAMETERS: * flash : Pointer identifying drive * area : indicated which protection area to work on. 0 or 1. * AddressLow : sets address of lower boundary of protected area. 0 - floor size. * AddressHigh : sets address of upper boundary of protected area. AddressLow - floor size. * Key : an 8 byte long array containing the protection password. * flag : any combination of the following flags: * LOCK_ENABLED - The LOCK signal is enabled. * READ_PROTECTED - The area is protected against read operations * WRITE_PROTECTED - The area is protected against write operations * modes : Either COMMIT_PROTECTION will cause the new values to * take affect immidiatly or DO_NOT_COMMIT_PROTECTION for * delaying the new values to take affect only after the * next reset. * * DESCRIPTION: Sets the definitions of a protected area: location, key and protection type * * RETURNS: * flOK - success * FlWriteProtect - protection violetion, * FlReadProtect - protection violetion. * FlDataError - any other read failure. * FlWriteFault - any other write error. * flBadLength - if the length of the protected area exceeds * allowed length */
FLStatus protectionSet ( FLFlash * flash, byte area, word flag, CardAddress addressLow, CardAddress addressHigh, byte FAR1* key , byte modes, byte floorNo) { FLBoolean restoreInterleave = FALSE; byte downloadStatus; DPSStruct dps; dword floorInc = floorNo * NFDC21thisVars->floorSize; word goodUnit,redundantUnit; dword goodDPS,redundantDPS; FLStatus status; dword goodIPL = 0; /* Initialized to remove warrnings */ dword redundantIPL = 0; /* Initialized to remove warrnings */ dword copyOffset; /* Offset to redundant DPS unit */ dword ipl0Copy0; /* Offset to IPL second 512 bytes copy 0 */ dword dps1Copy0; /* Offset to DPS1 copy 0 */ word dps1UnitNo; /* Offset to redundant DPS unit */
status = chkASICmode(flash); if(status != flOK) return status;
/* check if exceeds the size */ if( (addressLow > addressHigh) || (addressHigh - addressLow >= (dword)NFDC21thisVars->floorSize)) return( flBadLength );
/* change to interleave 1 */ if ( flash->interleaving == 2) { restoreInterleave = TRUE; status = changeInterleave(flash,1); if(status != flOK) return status; }
if(flash->mediaType == MDOCP_TYPE) /* DiskOnChip Millennium Plus 32MB */ { copyOffset = flash->chipSize>>1; /* The chips are consequtive */ dps1Copy0 = DPS1_COPY0_32; dps1UnitNo = DPS1_UNIT_NO_32; ipl0Copy0 = IPL0_COPY0_32; } else { copyOffset = flash->chipSize>>1; /* The chips are consequtive */ dps1Copy0 = DPS1_COPY0_16; dps1UnitNo = DPS1_UNIT_NO_16; ipl0Copy0 = IPL0_COPY0_16; }
/* find if previous download */ downloadStatus = flRead8bitRegPlus(flash,NdownloadStatus);
/* prepare buffer */
switch (area) { case 0: /* data protect structure 0 */
switch (downloadStatus & DWN_STAT_DPS0_ERR) { case DWN_STAT_DPS01_ERR: /* Both are bad */ return flBadDownload;
case DWN_STAT_DPS00_ERR: /* First is bad */ redundantUnit = (word)(DPS0_UNIT_NO + floorNo * (NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits)); goodUnit = (word)(redundantUnit + (copyOffset>>flash->erasableBlockSizeBits)); goodDPS = DPS0_COPY0+floorInc + copyOffset; redundantDPS = DPS0_COPY0+floorInc; break;
default: /* Both copies are good */ goodUnit = (word)(DPS0_UNIT_NO + floorNo*(NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits)); redundantUnit = (word)(goodUnit + (copyOffset>>flash->erasableBlockSizeBits)); goodDPS = DPS0_COPY0+floorInc; redundantDPS = DPS0_COPY0+floorInc + copyOffset; } break;
case 1: /* data protect structure 0 */
switch (downloadStatus & DWN_STAT_DPS1_ERR) { case DWN_STAT_DPS11_ERR: /* Both are bad */ return flBadDownload;
case DWN_STAT_DPS10_ERR: /* First is bad */ redundantUnit = (word)(dps1UnitNo + floorNo*(NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits)); goodUnit = (word)(redundantUnit + (copyOffset>>flash->erasableBlockSizeBits)); goodDPS = dps1Copy0+floorInc + copyOffset; redundantDPS = dps1Copy0+floorInc; redundantIPL = ipl0Copy0 + floorInc; goodIPL = redundantIPL + copyOffset; break;
default : /* First is good */ goodUnit = (word)(dps1UnitNo + floorNo*(NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits)); redundantUnit = (word)(goodUnit + (copyOffset>>flash->erasableBlockSizeBits)); goodDPS = dps1Copy0+floorInc; redundantDPS = dps1Copy0+floorInc + copyOffset; goodIPL = ipl0Copy0 + floorInc; redundantIPL = goodIPL + copyOffset; } break;
default: /* No such protection area */
return flGeneralFailure; }
/* Build new DPS */ if (key==NULL) /* key must be retreaved from previous structure */ { status = flash->read(flash,goodDPS,(void FAR1 *)&dps,SIZE_OF_DPS,0); if(status!=flOK) goto END_WRITE_DPS; if(findChecksum((byte *)&dps,SIZE_OF_DPS)!=0) /* bad copy */ status = flash->read(flash,goodDPS+REDUNDANT_DPS_OFFSET, (void FAR1*)&dps,SIZE_OF_DPS,0); makeDPS(addressLow,addressHigh,(byte FAR1*)(dps.key),flag,(byte *)&dps); } else /* key is given as a parameter */ { makeDPS(addressLow,addressHigh,(byte FAR1*)key,flag,(byte *)&dps); }
/* Erase redundant unit */ status = flash->erase(flash,redundantUnit,1); if(status!=flOK) goto END_WRITE_DPS;
/* Write new DPS */ status = flash->write(flash,redundantDPS,&dps,SIZE_OF_DPS,0); if(status!=flOK) goto END_WRITE_DPS; status = flash->write(flash,redundantDPS + REDUNDANT_DPS_OFFSET, &dps,SIZE_OF_DPS,0); if(status!=flOK) goto END_WRITE_DPS;
if (area == 1) /* copy the IPL */ { #ifndef MTD_STANDALONE
/* Force remapping of internal catched sector */ flash->socket->remapped = TRUE; #endif /* MTD_STANDALONE */
/* Read first 512 bytes IPL */ status = flash->read(flash,goodIPL,NFDC21thisBuffer,SECTOR_SIZE,0); if(status!=flOK) goto END_WRITE_DPS;
/* Write first 512 bytes IPL */ status = flash->write(flash,redundantIPL,NFDC21thisBuffer,SECTOR_SIZE,EDC); if(status!=flOK) goto END_WRITE_DPS; status = flash->write(flash,redundantIPL + SECTOR_SIZE, NFDC21thisBuffer,SECTOR_SIZE,EDC); if(status!=flOK) goto END_WRITE_DPS;
/* Read second 512 bytes IPL */ status = flash->read(flash,goodIPL + IPL_HIGH_SECTOR, NFDC21thisBuffer,SECTOR_SIZE,0); if(status!=flOK) goto END_WRITE_DPS;
/* Write second 512 bytes IPL */ status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR, NFDC21thisBuffer,SECTOR_SIZE,EDC); if(status!=flOK) goto END_WRITE_DPS; status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR + SECTOR_SIZE, NFDC21thisBuffer,SECTOR_SIZE,EDC); if(status!=flOK) goto END_WRITE_DPS; /* Read Srong Arm mark */ status = flash->read(flash,goodIPL + IPL_HIGH_SECTOR + 8, NFDC21thisBuffer,1,EXTRA); if(status!=flOK) goto END_WRITE_DPS; /* Write Srong Arm mark */ status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR + 8 + SECTOR_SIZE, NFDC21thisBuffer,1,EXTRA); if(status!=flOK) goto END_WRITE_DPS; status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR + 8, NFDC21thisBuffer,1,EXTRA); if(status!=flOK) goto END_WRITE_DPS; }
/* Erase good unit */ status = flash->erase(flash,goodUnit,1); if(status!=flOK) goto END_WRITE_DPS;
/* Write over previous DPS */ status = flash->write(flash,goodDPS,&dps,SIZE_OF_DPS,0); if(status!=flOK) goto END_WRITE_DPS; status = flash->write(flash,goodDPS + REDUNDANT_DPS_OFFSET, &dps,SIZE_OF_DPS,0); if(status!=flOK) goto END_WRITE_DPS;
if (area == 1) /* copy the IPL */ { /* Read first 512 bytes IPL */ status = flash->read(flash,redundantIPL,NFDC21thisBuffer,SECTOR_SIZE,0); if(status!=flOK) goto END_WRITE_DPS;
/* Write first 512 bytes IPL */ status = flash->write(flash,goodIPL,NFDC21thisBuffer,SECTOR_SIZE,EDC); if(status!=flOK) goto END_WRITE_DPS; status = flash->write(flash,goodIPL + SECTOR_SIZE, NFDC21thisBuffer,SECTOR_SIZE,EDC); if(status!=flOK) goto END_WRITE_DPS;
/* Read second 512 bytes IPL */ status = flash->read(flash,redundantIPL + IPL_HIGH_SECTOR, NFDC21thisBuffer,SECTOR_SIZE,0); if(status!=flOK) goto END_WRITE_DPS;
/* Write second 512 bytes IPL */ status = flash->write(flash,goodIPL + IPL_HIGH_SECTOR, NFDC21thisBuffer,SECTOR_SIZE,EDC); if(status!=flOK) goto END_WRITE_DPS; status = flash->write(flash,goodIPL + IPL_HIGH_SECTOR + SECTOR_SIZE, NFDC21thisBuffer, SECTOR_SIZE,EDC); if(status!=flOK) goto END_WRITE_DPS; }
END_WRITE_DPS: if ( restoreInterleave == TRUE) { FLStatus status2;
chkASICmode(flash); /* Release posible access error */ status2 = changeInterleave(flash, 2); /* change back to interleave 2 */ if(status2 != flOK) return status2; } if (status == flOK) { if ((modes & COMMIT_PROTECTION) && /* The new values will take affect now */ (flash->download != NULL)) status = flash->download(flash); } return status;
}
/*
** makeDataProtectStruct * * * PARAMETERS: * AddressLow : sets address of lower boundary of protected area * AddressHigh: sets address of upper boundary of protected area * Key : an 8 byte long array containing the protection password. * flag : any combination of the following flags: * LOCK_ENABLED - The LOCK signal is enabled. * READ_PROTECTED - The area is protected against read operations * WRITE_PROTECTED - The area is protected against write operations * buffer - buffer pointer of the returned structure. * * DESCRIPTION: Sets the definitions of a protected structure: location, key and protection type * * RETURNS: * */
static void makeDPS(CardAddress addressLow, CardAddress addressHigh, byte FAR1* key , word flag, byte* buffer) { int i; DPSStruct* dps = (DPSStruct *)buffer;
/* convert to little endien and store */ toLE4(dps->addressLow,addressLow >>10); toLE4(dps->addressHigh,addressHigh >>10);
/*insert protection key */ for(i=0; i<PROTECTION_KEY_LENGTH; i++) dps->key[i] = key[i];
/* insert flags */ dps->protectionType = 0; if((flag & LOCK_ENABLED)==LOCK_ENABLED) dps->protectionType |= DPS_LOCK_ENABLED; if((flag & READ_PROTECTED)==READ_PROTECTED) dps->protectionType |= DPS_READ_PROTECTED; if((flag & WRITE_PROTECTED)==WRITE_PROTECTED) dps->protectionType |= DPS_WRITE_PROTECTED;
/* calculate and store checksum */ dps->checksum = findChecksum(buffer,SIZE_OF_DPS-1); } #endif /* FL_READ_ONLY */
#endif /* HW_PROTECTION */
|