⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash_amd.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }



    /* 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 + -