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

📄 flash_strata.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* 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 + -