📄 protectp.c
字号:
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;
/* Ignore default protection - write protect with key */
/* "00000000" on DPS */
addressLow = addressLow >> flash->erasableBlockSizeBits;
addressHigh = addressHigh >> flash->erasableBlockSizeBits;
if(( /* 32MB DiskOnChip and protection is on the DPS */
(flash->mediaType == MDOCP_TYPE ) &&
( (addressLow != (CardAddress)(area + 1) ) ||
(addressLow != addressHigh ) ) ) ||
/* or 16MB DiskOnChip and protection is on the DPS */
( (flash->mediaType == MDOCP_16_TYPE ) &&
( (addressLow != (CardAddress)((area<<1) + 1) ) ||
(addressLow + 1 != addressHigh ) ) ))
{
*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->erasableBlockSize; /* 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,flash->mediaType);
}
else /* key is given as a parameter */
{
makeDPS(addressLow,addressHigh,(byte FAR1*)key,flag,
(byte *)&dps,flash->mediaType);
}
/* 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.
* flashType - The flash->mediaType value (either MDOCP_TYPE/MDOCP_16_TYPE
*
* 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, byte flashType)
{
int i = 10;
DPSStruct* dps = (DPSStruct *)buffer;
if(flashType == MDOCP_16_TYPE)
i--;
/* convert to little endien and store */
toLE4(dps->addressLow,addressLow >> i);
toLE4(dps->addressHigh,addressHigh >> i);
/*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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -