📄 flash_amd.c
字号:
}
/* device not known */
return(FLASH_UNKNOWN_DEVICE) ;
}
/************************************************************************
*
* FLASH_AMD_program_systemram
* Description :
* -------------
* Programs (store data) in the system RAM device.
*
*
* Parameters :
* ------------
*
* 'p_param', IN, variable of type, t_FLASH_write_descriptor.
*
*
* Return values :
* ---------------
*
* 'OK' = 0x00: Data stored in system RAM
*
*
************************************************************************/
static
INT32 FLASH_AMD_program_systemram( t_FLASH_write_descriptor *p_param )
{
int i, len ;
UINT8 *psrc ;
UINT8 *pdst ;
/* set addresses */
psrc = (UINT8*) p_param->buffer ;
pdst = (UINT8*) KSEG1(p_param->adr) ;
len = p_param->length ;
/* call our speedy memcpy */
memcpy( pdst, psrc, len ) ;
return(OK) ;
}
/************************************************************************
*
* FLASH_AMD_program_flash
* Description :
* -------------
* Programs a Intel 28Fxxx-compliant flash device.
*
*
* Parameters :
* ------------
*
* 'p_param', IN, variable of type, t_FLASH_write_descriptor.
*
*
* Return values :
* ---------------
*
* 'OK' = 0x00: FLASH programmed succesfully
* ERROR_FLASH_PROGRAM_ERROR Flash device failure
*
*
************************************************************************/
#ifndef FLASH_16BIT
static
INT32 FLASH_AMD_program_flash( t_FLASH_write_descriptor *p_param )
{
int rcode = OK ;
t_flash_access dw ; /* destination words */
int i, j, wc, len, rest ;
void volatile *psrc ;
void volatile *pdst;
/* convert addresses to kseg1 */
psrc = p_param->buffer ;
pdst = (void*)KSEG1((UINT32)p_param->adr) ;
len = p_param->length ;
/* check any special case */
if (len <= 0)
{
return(OK) ;
}
/* test for initial alignment */
rest = (UINT32)pdst & 0x3 ;
if (rest)
{
/* Need for initial word alignment */
/* read destination word */
(UINT32)pdst = ((UINT32)pdst & 0xfffffffc) ;
dw.d32 = REG32(pdst) ;
/* calculate upper byte boundary inside word */
j = 4 ;
if (len < (4-rest))
{
j = rest + len ;
}
/* merge rest into last dest. word */
for (i=rest; i<j; i++)
{
/* copy source bytes into last word */
dw.d8[i] = REG8(psrc) ;
(UINT32)psrc += 1 ;
len-- ;
}
/* These are the commands to write word into AMD flash */
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x555) = (UINT32) 0x00AA00AA;
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x2AA) = (UINT32) 0x00550055;
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x555) = (UINT32) 0x00A000A0;
REG32(pdst) = dw.d32 ;
/* await completion */
rcode = FLASH_AMD_wait_ready(pdst, dw.d32);
if (rcode)
{
return(rcode) ;
}
/* Verify programmed word */
if ( REG32(pdst) != dw.d32 )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Data check read: (0x%08x)=0x%08x, Data written: 0x%08x", (UINT32)pdst, REG32(pdst), dw.d32) ;
return(ERROR_FLASH_VERIFY_ERROR) ;
}
/* adjust destination pointer */
(UINT32)pdst += 4 ;
}
/* calculate words to program and some rest of bytes */
wc = len / 4 ;
rest = len % 4 ;
/* now, destination is word aligned, check source */
if ((UINT32)psrc & 0x3)
{
/* destination only is word aligned */
/* program word by word */
for (i=0; i<wc; i++)
{
/* copy source bytes into dest. word */
for (j=0; j<4; j++)
{
dw.d8[j] = REG8(psrc) ;
(UINT32)psrc += 1 ;
}
/* program this word */
/* These are the commands to write word into AMD flash */
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x555) = (UINT32) 0x00AA00AA;
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x2AA) = (UINT32) 0x00550055;
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x555) = (UINT32) 0x00A000A0;
REG32(pdst) = dw.d32 ;
/* await completion */
rcode = FLASH_AMD_wait_ready( pdst, dw.d32);
if (rcode)
{
return(rcode) ;
}
/* Verify programmed word */
if ( REG32(pdst) != dw.d32 )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Data check read: (0x%08x)=0x%08x, Data written: 0x%08x", (UINT32)pdst, REG32(pdst), dw.d32) ;
return(ERROR_FLASH_VERIFY_ERROR) ;
}
/* next destination word */
(UINT32)pdst += 4 ;
}
}
else
{
/* both source and destination is word aligned */
/* program word by word */
for (i=0; i<wc; i++)
{
/* program this word */
/* These are the commands to write word into AMD flash */
dw.d32 = REG32(psrc);
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x555) = (UINT32) 0x00AA00AA;
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x2AA) = (UINT32) 0x00550055;
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x555) = (UINT32) 0x00A000A0;
REG32(pdst) = dw.d32 ;
/* await completion */
rcode = FLASH_AMD_wait_ready( pdst, dw.d32);
if (rcode)
{
return(rcode) ;
}
/* Verify programmed word */
if ( REG32(pdst) != dw.d32 )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Data check read: (0x%08x)=0x%08x, Data written: 0x%08x", (UINT32)pdst, REG32(pdst), dw.d32) ;
return(ERROR_FLASH_VERIFY_ERROR) ;
}
/* next destination and source word */
(UINT32)pdst += 4 ;
(UINT32)psrc += 4 ;
}
}
if (rest)
{
/* we still have some bytes left */
/* read destination word */
dw.d32 = REG32(pdst) ;
/* merge rest into last dest. word */
for (i=0; i<rest; i++)
{
/* copy source bytes into last word */
dw.d8[i] = REG8(psrc) ;
(UINT32)psrc += 1 ;
}
/* program this word */
/* These are the commands to write word into AMD flash */
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x555) = (UINT32) 0x00AA00AA;
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x2AA) = (UINT32) 0x00550055;
REG32((UINT32*)((UINT32) pdst & 0xffc00000) + 0x555) = (UINT32) 0x00A000A0;
REG32(pdst) = dw.d32 ;
/* await completion */
rcode = FLASH_AMD_wait_ready( pdst, dw.d32);
if (rcode)
{
return(rcode) ;
}
/* Verify programmed word */
if ( REG32(pdst) != dw.d32 )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Data check read: (0x%08x)=0x%08x, Data written: 0x%08x", (UINT32)pdst, REG32(pdst), dw.d32) ;
return(ERROR_FLASH_VERIFY_ERROR) ;
}
}
return( rcode ) ;
}
#else // 16 bit wide flash
void dumphex(short *p, int len)
{
int i;
i = 0;
while( i < len )
{
if( (i % 16) == 0 )
printf("\n%08x: ",(UINT32)&p[i/2]);
printf("%04x ",p[i/2] & 0x00ffff);
i += 2;
}
printf("\n");
}
static
INT32 FLASH_AMD_program_flash( t_FLASH_write_descriptor *p_param )
{
int rcode = OK;
int i, len;
volatile short *psrc;
volatile short *pdst;
volatile short *flash;
short data;
/* convert addresses to kseg1 */
psrc = (short *)p_param->buffer;
pdst = (short *)KSEG1((UINT32)p_param->adr);
len = p_param->length;
flash = (short *)((long)pdst & 0xffff8000); // command base address
// printf(" AMD program Flash: base %08x, start %08x, len = %d\n",(UINT32)flash,(UINT32)pdst,len);
// dumphex(psrc,len);
/* check any special case */
if (len <= 0)
{
printf("len <= 0\n");
return(OK);
}
if( ((UINT32)psrc & 0x00000001) || ((UINT32)pdst & 0x00000001))
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) );
sprintf(flash_diag_msg, " alignment error (halfword) src = %08x, dst = %08x",(UINT32)psrc,(UINT32)pdst);
return(ERROR_FLASH_VERIFY_ERROR);
}
/* both source and destination must be halfword aligned */
/* program word by word */
for ( i = 0; i < len; i += 2)
{
data = *psrc; /* capture data before programming sequence initiated in case source is in same device */
/* program one halfword */
/* These are the commands to write a halfword into AMD flash */
flash[0x555] = 0x00AA;
flash[0x2AA] = 0x0055;
flash[0x555] = 0x00A0;
*pdst = data;
/* await completion */
rcode = FLASH_AMD_wait_ready( (void *)pdst, data);
if (rcode)
{
printf(" programming error.\n");
return(rcode);
}
/* Verify programmed word */
if ( *pdst != *psrc )
{
memset( flash_diag_msg, 0, sizeof(flash_diag_msg) ) ;
sprintf( flash_diag_msg, "Data check read: (0x%08x)=0x%04x, Data written: 0x%04x",
(UINT32)pdst, *pdst & 0x0ffff, *psrc & 0x0ffff) ;
return(ERROR_FLASH_VERIFY_ERROR) ;
}
/* next destination and source word */
++pdst;
++psrc;
}
// printf("programming done, status = %d\n",rcode);
return( rcode ) ;
}
#endif // 16 bit version
/************************************************************************
*
* FLASH_AMD_set_systemflash_read
* Description :
* -------------
* Set system flash device in read mode.
*
*
* Parameters :
* ------------
*
* -
*
*
* Return values :
* ---------------
*
* 'OK' = 0x00: System FLASH set to read mode
* ERROR_FLASH_PROGRAM_ERROR Flash device failure
*
*
************************************************************************/
static
INT32 FLASH_AMD_set_systemflash_read( void )
{
int rcode ;
UINT32 bank ;
volatile UINT32 *pw ;
/* The address is actually a don't care but you need to put something */
pw = (UINT32*) KSEG1(systemflash_phys_start) ;
/* The first reset will take us out of any command modes */
REG32(pw) = 0x00f000f0;
/* The second reset will reset all banks in flash to read mode */
REG32(pw) = 0x00f000f0;
return( OK ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -