📄 flash_strata.c
字号:
/* calculate committed FLASH area */
start = (KSEG1(p_param->user_physadr)/blocksize) * blocksize ;
end = ((((KSEG1(p_param->user_physadr) +
p_param->user_length)/blocksize)) * blocksize) - 1 ;
if ( ((KSEG1(p_param->user_physadr)+p_param->user_length) % blocksize) != 0)
{
end = end + blocksize ;
}
/* return committed area to user */
p_param->driver_physadr = PHYS(start) ;
p_param->driver_length = (end - start) + 1 ;
return( OK ) ;
}
/************************************************************************
*
* FLASH_STRATA_test_systemflash
* Description :
* -------------
* Test complete file flash (just one block)
*
*
* Parameters :
* ------------
*
* -
*
* Return values :
* ---------------
*
* 'OK' = 0x00: System FLASH OK
* ERROR_FLASH_LOCKED Some sector(s) locked
* ERROR_FLASH_ERASE_ERROR Some sector(s) have erase error
*
*
************************************************************************/
static
INT32 FLASH_STRATA_test_systemflash( void )
{
int rcode = OK ;
UINT32 block, bank ;
volatile UINT32 *pw ;
pw = (UINT32*)KSEG1(systemflash_phys_start) ;
for (bank = 0; bank < systemflash_bank_count; bank++)
{
for (block = 0; block < systemflash_block_count; block++)
{
/* issue 'QUERY' command */
REG32(pw) = FLASH_QUERY_COMMAND ;
#ifdef FLASH_DEBUG
sprintf( msg, "\n\r FLASH_STRATA_test_systemflash: Adr= 0x%08x, Sta= 0x%08x\n\r",
(UINT32)pw, REG32( ((UINT32)pw+FLASH_BLOCKSTATUS_OFS) ) ) ;
PUTS( DEFAULT_PORT, msg ) ;
#endif
/* Verify 'Q' char of the Query-unique ASCII string, part of CFI spec. */
if ( REG32( ((UINT32)pw+FLASH_QUERYQCHAR_OFS) ) != FLASH_QUERYQCHAR )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Adr= %08x, (Adr)= %08x",(UINT32)pw+FLASH_QUERYQCHAR_OFS,
REG32(((UINT32)pw+FLASH_QUERYQCHAR_OFS)) ) ;
rcode = ERROR_FLASH_QRY_NOT_FOUND ;
break ;
}
/* Verify 'R' char of the Query-unique ASCII string, part of CFI spec. */
if ( REG32( ((UINT32)pw+FLASH_QUERYRCHAR_OFS) ) != FLASH_QUERYRCHAR )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Adr= %08x, (Adr)= %08x",(UINT32)pw+FLASH_QUERYRCHAR_OFS,
REG32(((UINT32)pw+FLASH_QUERYRCHAR_OFS)) ) ;
rcode = ERROR_FLASH_QRY_NOT_FOUND ;
break ;
}
/* Verify 'Y' char of the Query-unique ASCII string, part of CFI spec. */
if ( REG32( ((UINT32)pw+FLASH_QUERYYCHAR_OFS) ) != FLASH_QUERYYCHAR )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Adr= %08x, (Adr)= %08x",(UINT32)pw+FLASH_QUERYYCHAR_OFS,
REG32(((UINT32)pw+FLASH_QUERYYCHAR_OFS)) ) ;
rcode = ERROR_FLASH_QRY_NOT_FOUND ;
break ;
}
/* next block */
pw = (UINT32*)((UINT32)pw + systemflash_block_size) ;
}
if (rcode != OK)
{
break ;
}
}
/* reset working pointer to start of system flash */
pw = (UINT32*)KSEG1(systemflash_phys_start) ;
for (bank = 0; bank < systemflash_bank_count; bank++)
{
/* issue 'CLEAR STATUS: SR-5,4,3,1' command */
REG32(pw) = FLASH_CLEAR_STATUS_COMMAND;
/* issue 'READ ARRAY' command */
REG32(pw) = FLASH_READ_COMMAND;
/* next bank: */
pw = (UINT32*)((UINT32)pw + (systemflash_block_count * systemflash_block_size)) ;
}
return( rcode ) ;
}
/************************************************************************
*
* FLASH_STRATA_test_fileflash
* Description :
* -------------
* Test complete file flash.
*
*
* Parameters :
* ------------
*
* -
*
* Return values :
* ---------------
*
* 'OK' = 0x00: System FLASH OK
* ERROR_FLASH_LOCKED Some sector(s) locked
* ERROR_FLASH_ERASE_ERROR Some sector(s) have erase error
*
*
************************************************************************/
static
INT32 FLASH_STRATA_test_fileflash( void )
{
int rcode = OK ;
volatile UINT32 *pw ;
pw = (UINT32*)KSEG1(fileflash_phys_start) ;
/* issue 'QUERY' command */
REG32(pw) = FLASH_QUERY_COMMAND ;
/* Verify 'Q' char of the Query-unique ASCII string, part of CFI spec. */
if ( REG32( ((UINT32)pw+FLASH_QUERYQCHAR_OFS) ) != FLASH_QUERYQCHAR )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Adr= %08x, (Adr)= %08x",(UINT32)pw+FLASH_QUERYQCHAR_OFS,
REG32(((UINT32)pw+FLASH_QUERYQCHAR_OFS)) ) ;
rcode = ERROR_FLASH_QRY_NOT_FOUND ;
}
/* Verify 'R' char of the Query-unique ASCII string, part of CFI spec. */
if ( REG32( ((UINT32)pw+FLASH_QUERYRCHAR_OFS) ) != FLASH_QUERYRCHAR )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Adr= %08x, (Adr)= %08x",(UINT32)pw+FLASH_QUERYRCHAR_OFS,
REG32(((UINT32)pw+FLASH_QUERYRCHAR_OFS)) ) ;
rcode = ERROR_FLASH_QRY_NOT_FOUND ;
}
/* Verify 'Y' char of the Query-unique ASCII string, part of CFI spec. */
if ( REG32( ((UINT32)pw+FLASH_QUERYYCHAR_OFS) ) != FLASH_QUERYYCHAR )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Adr= %08x, (Adr)= %08x",(UINT32)pw+FLASH_QUERYYCHAR_OFS,
REG32(((UINT32)pw+FLASH_QUERYYCHAR_OFS)) ) ;
rcode = ERROR_FLASH_QRY_NOT_FOUND ;
}
/* reset working pointer to start of system flash */
pw = (UINT32*)KSEG1(fileflash_phys_start) ;
/* issue 'CLEAR STATUS: SR-5,4,3,1' command */
REG32(pw) = FLASH_CLEAR_STATUS_COMMAND;
/* issue 'READ ARRAY' command */
REG32(pw) = FLASH_READ_COMMAND;
return( rcode ) ;
}
/************************************************************************
*
* FLASH_STRATA_test_monitorflash
* Description :
* -------------
* Test and set lock bits of complete monitor flash (including file flash)
* The lower 1 Mbytes hold YAMON and are locked (write protected)
* The upper 3 Mbytes are unlocked.
*
*
* Parameters :
* ------------
*
* -
*
* Return values :
* ---------------
*
* 'OK' = 0x00: System FLASH OK
* ERROR_FLASH_LOCKED Some sector(s) locked
* ERROR_FLASH_ERASE_ERROR Some sector(s) have erase error
*
************************************************************************/
static
INT32 FLASH_STRATA_test_monitorflash( void )
{
int rcode = OK ;
volatile UINT32 pw ;
UINT32 pw_lock_end;
UINT32 pw_unlock_end;
pw = KSEG1(monitorflash_phys_start) ;
pw_lock_end = pw + 0x00100000;
pw_unlock_end = KSEG1(fileflash_phys_end) ;
if (monitorflash_phys_start == 0 || pw_lock_end >= pw_unlock_end)
{
return ERROR_FLASH_INVALID_COMMAND ;
}
for (; pw < pw_lock_end; pw += monitorflash_block_size)
{
/* issue 'QUERY' command */
REG32(pw) = FLASH_READ_ID_CODES_COMMAND ;
/* read status and check for LOCKED block */
if ( (REG32( (pw+FLASH_BLOCKSTATUS_OFS) ) & FLASH_BLOCKSTATUS_LOCK_MSK) != FLASH_BLOCKSTATUS_LOCK_MSK)
{
/* Lock */
/* issue 'clear lock-bit' command */
REG32(pw) = FLASH_CLEAR_LOCK_COMMAND ;
/* issue 'set lock-bit' command */
REG32(pw) = FLASH_LOCK_SECTOR ;
/* await completion */
rcode = FLASH_STRATA_wait_ready( (UINT32 *)pw, FLASH_RETRY_10);
if (rcode != OK)
{
rcode |= pw;
goto out ;
}
}
}
for (; pw < pw_unlock_end; pw += monitorflash_block_size)
{
/* issue 'QUERY' command */
REG32(pw) = FLASH_READ_ID_CODES_COMMAND ;
/* read status and check for LOCKED block */
if ( REG32( (pw+FLASH_BLOCKSTATUS_OFS) ) & FLASH_BLOCKSTATUS_LOCK_MSK )
{
/* Unlock */
/* issue 'clear lock-bit' command */
REG32(pw) = FLASH_CLEAR_LOCK_COMMAND ;
/* issue 'confirm' command */
REG32(pw) = FLASH_CONFIRM_COMMAND;
/* await completion */
rcode = FLASH_STRATA_wait_ready( (UINT32 *)pw, FLASH_RETRY_10);
if (rcode != OK)
{
rcode |= pw;
goto out ;
}
}
}
out:
/* reset working pointer to start of monitor flash */
pw = KSEG1(monitorflash_phys_start) ;
/* issue 'CLEAR STATUS: SR-5,4,3,1' command */
REG32(pw) = FLASH_CLEAR_STATUS_COMMAND;
/* issue 'READ ARRAY' command */
REG32(pw) = FLASH_READ_COMMAND;
return( rcode ) ;
}
/************************************************************************
*
* FLASH_STRATA_wait_ready
* Description :
* -------------
*
* Await FLASH operation completes.
*
*
* Parameters :
* ------------
*
* -
*
* Return values :
* ---------------
*
* 'OK' = 0x00: File FLASH erased succesfully
* ERROR_FLASH_PROGRAM_ERROR Flash device failure
*
*
************************************************************************/
static
INT32 FLASH_STRATA_wait_ready(volatile UINT32 *pw, UINT32 retry )
{
UINT32 rc, first, latest, previous, accumulate, millisec ;
accumulate = 0 ;
/* get millisecond count */
rc = SYSCON_read( SYSCON_BOARD_GET_MILLISEC_ID,
&first,
sizeof(first) ) ;
previous = first ;
millisec = FLASH_TMOUT_2_5SEC ;
while ( 1 )
{
/* is flash ready ? */
if ( (REG32(pw) & FLASH_STATUS_READY) == FLASH_STATUS_READY )
{
/* yes, it is ready, read another time, according to errata. */
/* is status OK ? */
if ( (REG32(pw) & FLASH_STATUS_MASK) == FLASH_STATUS_OK )
{
/* yes, it is ok ! */
return( OK ) ;
}
else
{
/* keep diagnose message */
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Flash status: (0x%08x)=0x%08x",(UINT32)pw,REG32(pw)) ;
/* check for lock bit */
if ( (REG32(pw) & FLASH_STATUS_LOCK) )
return( ERROR_FLASH_LOCKED ) ;
/* check for lack of programming voltage */
if ( (REG32(pw) & FLASH_STATUS_LOW_VOLTAGE) )
return( ERROR_FLASH_LOW_VOLTAGE ) ;
/* check for erase error */
if ( (REG32(pw) & FLASH_STATUS_ERASE) )
return( ERROR_FLASH_ERASE_ERROR ) ;
/* some error is indicated */
return( ERROR_FLASH_PROGRAM_ERROR ) ;
}
}
/* get millisecond count */
rc = SYSCON_read( SYSCON_BOARD_GET_MILLISEC_ID,
&latest,
sizeof(latest) ) ;
if ( latest >= previous )
{
/* counter still not wrapped */
if ( (accumulate + (latest - first)) > millisec )
{
break ;
}
}
else
{
/* counter did wrap */
accumulate = accumulate + (previous - first) ;
if ( (accumulate + latest) > millisec )
{
break ;
}
/* reset first */
first = 0 ;
}
/* prepare next delta time */
previous = latest ;
}
/* keep diagnose message */
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Adr=0x%08x",(UINT32)pw) ;
/* we should never end up here
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -