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

📄 flash.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 3 页
字号:
//=============================================================================
//
//      flash.c - Cyclone Diagnostics
//
//=============================================================================
//####COPYRIGHTBEGIN####
//                                                                          
// -------------------------------------------                              
// The contents of this file are subject to the Red Hat eCos Public License 
// Version 1.1 (the "License"); you may not use this file except in         
// compliance with the License.  You may obtain a copy of the License at    
// http://www.redhat.com/                                                   
//                                                                          
// Software distributed under the License is distributed on an "AS IS"      
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
// License for the specific language governing rights and limitations under 
// the License.                                                             
//                                                                          
// The Original Code is eCos - Embedded Configurable Operating System,      
// released September 30, 1998.                                             
//                                                                          
// The Initial Developer of the Original Code is Red Hat.                   
// Portions created by Red Hat are                                          
// Copyright (C) 2001 Red Hat, Inc.                             
// All Rights Reserved.                                                     
// -------------------------------------------                              
//                                                                          
//####COPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden
// Contributors:
// Date:        2001-01-25
// Purpose:     
// Description: 
//
//####DESCRIPTIONEND####
//
//===========================================================================*/

#include <redboot.h>
#ifdef CYGPKG_IO_FLASH
#include <cyg/io/flash.h>

#include "iq80310.h"	/* 80310 chip set specific */
#include "7_segment_displays.h"

typedef unsigned char FLASH_TYPE;
#define MASK 0xff  /* for 1 bank */

/* 28F016S5/28F640J3A Command Definitions  - First Bus Cycle */
#define RESET_CMD				(0xffffffff & MASK)
#define WRITE_TO_BUF_CMD		(0xe8e8e8e8 & MASK)
#define WRITE_CONFIRM_CMD		(0xd0d0d0d0 & MASK)
#define READ_ID_CMD				(0x90909090 & MASK)
#define READ_STAT_REG			(0x70707070 & MASK)
#define CLEAR_STAT_REG			(0x50505050 & MASK)
#define ERASE_CMD				(0x20202020 & MASK)
#define PROGRAM_CMD				(0x40404040 & MASK)
#define BEP_SUSPEND				(0xb0b0b0b0 & MASK)
#define BEP_RESUME				(0xd0d0d0d0 & MASK)
#define LOCK_CMD				(0x60606060 & MASK)
#define CLEAR_LOCK_BIT_SETUP	(0x60606060 & MASK)	/* 10/06/00 */

/* 28F016S5/28F640J3A Command Definitions  - Second Bus Cycle */
#define ERASE_CONFIRM			(0xd0d0d0d0 & MASK)
#define LOCK_BLOCK_CONFIRM		(0x01010101 & MASK)
#define MASTER_LOCK_CONFIRM		(0xf1f1f1f1 & MASK)  /* DO NOT EVER set master enable bit!!! */
#define UNLOCK_BLOCK_CONFIRM	(0xd0d0d0d0 & MASK)
#define CLEAR_LOCK_BIT_CONFIRM	(0xd0d0d0d0 & MASK)	/* 10/06/00 */

/* Flash category definitions */
#define SECTOR_PROG	0
#define BLOCK_PROG	1

/* status register bits */
#define WSM_READY				(FLASH_TYPE) (1 << 7)
#define WSM_BUSY				(FLASH_TYPE) (0 << 7)
#define BE_SUSPENDED			(FLASH_TYPE) (1 << 6)
#define BE_COMPLETED			(FLASH_TYPE) (0 << 6)
#define ERASE_UNLOCK_ERROR		(FLASH_TYPE) (1 << 5)
#define ERASE_UNLOCK_SUCCESS	(FLASH_TYPE) (0 << 5)
#define CLEAR_LOCK_BIT_ERROR	(FLASH_TYPE) (1 << 5)	/* 10/06/00 */
#define CLEAR_LOCK_BIT_SUCCESS	(FLASH_TYPE) (0 << 5)	/* 10/06/00 */
#define PROGRAM_LOCK_ERROR		(FLASH_TYPE) (1 << 4)
#define PROGRAM_LOCK_SUCCESS	(FLASH_TYPE) (0 << 4)
#define SET_LOCK_BIT_ERROR		(FLASH_TYPE) (1 << 4)	/* 10/17/00 */
#define SET_LOCK_BIT_SUCCESS	(FLASH_TYPE) (0 << 4)	/* 10/17/00 */
#define VPP_LOW_DETECT			(FLASH_TYPE) (1 << 3)
#define VPP_OK					(FLASH_TYPE) (0 << 3)
#define PROGRAM_SUSPENDED		(FLASH_TYPE) (1 << 2)
#define PROGRAM_COMPLETED		(FLASH_TYPE) (0 << 2)
#define DEVICE_PROTECTED		(FLASH_TYPE) (1 << 1)
#define DEVICE_UNLOCKED			(FLASH_TYPE) (0 << 1)


/* Other Intel 28F016S5/28F640J3A definitions */
#define CMD_SEQ_ERR			(FLASH_TYPE) (ERASE_UNLOCK_ERROR | PROGRAM_LOCK_ERROR)
#define ALL_FLASH_STATUS	(FLASH_TYPE) (0xfe)
#define UNKNOWN_ERR			(FLASH_TYPE) (0xff)

#define TEST_BUF_LONGS		16384
#define TEST_BUF_CHARS		65536

#define MADE_BY_INTEL		(0x89898989 & MASK)		/* Manufacturer Code, read at address 0, note that address bit A0 is not used in x8 or x16 mode when obtaining identifier code */

/*#define I28F016S5			(0xAAAAAAAA & MASK)*/	/* 28F016S5 */
#define I28F640J3A			(0x17171717 & MASK)		/* Device Code, read at address 1, note that bit address A0 is not used in x8 or x16 mode when obtaining identifier code */

/*#define FLASH_BLOCK_SIZE	0x10000*/	/* 28F016S5 */
#define FLASH_BLOCK_SIZE	0x20000		/* 28F640J3A */

#define BLOCK_LOCKED		1
#define BLOCK_UNLOCKED		0

// First 4K page of flash at physical address zero is
// virtually mapped at address 0xd0000000.
#define FLASH_P2V(x) ((volatile FLASH_TYPE *)(((unsigned)(x) < 0x1000) ?  \
                           ((unsigned)(x) | 0xd0000000) :  \
                           (unsigned)(x)))


unsigned long *flash_buffer = (unsigned long *)0xa1000000;


extern void _flushICache();
extern void _enableICache();
extern void _disableICache();
extern void _switchMMUpageTables();


extern void _usec_delay();
extern void _msec_delay();

unsigned long eeprom_size;
unsigned long flash_base;

ADDR flash_addr=FLASH_ADDR, eeprom_prog_first, eeprom_prog_last;

extern long hexIn();
extern char * sgets();

/* forward declarations */
void init_eeprom() RAM_FUNC_SECT;
int reserved_check(ADDR addr, unsigned long length) RAM_FUNC_SECT;
int is_eeprom(ADDR addr, unsigned long length) RAM_FUNC_SECT;
int check_eeprom(ADDR addr, unsigned long length) RAM_FUNC_SECT;
int lock_breeze() RAM_FUNC_SECT;
int check_bstat(int block_num) RAM_FUNC_SECT;
int set_all_lock_bits(void) RAM_FUNC_SECT;		/* 10/11/00 added */
int clear_all_lock_bits(ADDR addr) RAM_FUNC_SECT;	/* 10/06/00 added */
int check_erase_unlock(volatile FLASH_TYPE *flash) RAM_FUNC_SECT;
int check_op_status(int cmd, volatile FLASH_TYPE *flash) RAM_FUNC_SECT;
int erase_eeprom(ADDR addr, unsigned long length) RAM_FUNC_SECT;
int check_program_lock(volatile FLASH_TYPE *flash) RAM_FUNC_SECT;
int write_eeprom(ADDR start_addr, const void *data_arg, int data_size) RAM_FUNC_SECT;
void flash_test(void) RAM_FUNC_SECT;
void delay_and_flush(void) RAM_FUNC_SECT;
void do_nothing(void) RAM_FUNC_SECT;
void display_val(int num) RAM_FUNC_SECT;
void display_out (int msb_flag, unsigned char val) RAM_FUNC_SECT;
void check_lock_bit_status(void) RAM_FUNC_SECT;

#define MSB_DISPLAY_REG		(volatile unsigned char *)0xfe840000
#define LSB_DISPLAY_REG		(volatile unsigned char *)0xfe850000

void display_out (int msb_flag, unsigned char val)
{
/*	unsigned char *ledPtr; */
	volatile unsigned char *ledPtr;
	unsigned char  SevSegDecode;

	if (msb_flag) ledPtr = MSB_DISPLAY_REG;
	else          ledPtr = LSB_DISPLAY_REG;

	switch (val)
	{
		case 0:
			SevSegDecode = ZERO;	
			break;

		case 1:
			SevSegDecode = ONE;
			break;

		case 2:
			SevSegDecode = TWO;
			break;

		case 3:
			SevSegDecode = THREE;
			break;

		case 4:
			SevSegDecode = FOUR;
			break;

		case 5:
			SevSegDecode = FIVE;
			break;

		case 6:
			SevSegDecode = SIX;
			break;

		case 7:
			SevSegDecode = SEVEN;
			break;

		case 8:
			SevSegDecode = EIGHT;
			break;

		case 9:
			SevSegDecode = NINE;
			break;
		
		case 10:
			SevSegDecode = LETTER_A;
			break;

		case 11:
			SevSegDecode = LETTER_B;
			break;

		case 12:
			SevSegDecode = LETTER_C;
			break;
		
		case 13:
			SevSegDecode = LETTER_D;
			break;
		
		case 14:
			SevSegDecode = LETTER_E;
			break;

		case 15:
			SevSegDecode = LETTER_F;
			break;

		default:
			SevSegDecode = DECIMAL_POINT;

	}
	*ledPtr = SevSegDecode;
}

void display_val (int number)
{
	unsigned char disp_val = number % 256;
	unsigned char msb, lsb;

	lsb = disp_val & 0x0f;
	msb = (disp_val & 0xf0) >> 4;

	display_out (0, lsb);
	display_out (1, msb);
}

/* Used in write to buffer routine */
void do_nothing (void)
{

	volatile int i;
	for (i = 0; i < 50; i++);		/* Rev 2.0B and Rev 2.0C */
/*	for (i = 0; i < 100; i++); */	/* Rev 2.0A */
}


void delay_and_flush (void)
{

	do_nothing(); 

	_flushICache();

}


/********************************************************/
/* INIT FLASH											*/
/*														*/
/* This routine initializes the variables for timing    */
/* with any board configuration.  This is used to get   */
/* exact timing every time.								*/
/********************************************************/

void init_eeprom()
{
#if 1
	unsigned char MfgCode=MADE_BY_INTEL;
	unsigned char DevCode=I28F640J3A;

	eeprom_size = 0x800000;
#else
	unsigned char MfgCode=0;
	unsigned char DevCode=0;

	flash_addr = FLASH_ADDR;

	flash_base = FLASH_BASE_ADDR;

    /* Set defaults */
    eeprom_size = 0;

    /* Note: the PCI-700 platform has only 1 memory bank */

/*
	*( volatile unsigned char * ) FLASH_BASE_ADDR = RESET_CMD;
	printf( "Wrote 1rst Read Array Command\n");
*/

	*FLASH_P2V(FLASH_BASE_ADDR) = RESET_CMD;	/* issue read array command */	
	delay_and_flush();		  /* wait for Flash to re-enter Read Array mode */

		
	*FLASH_P2V(FLASH_BASE_ADDR) = READ_ID_CMD;	/* issue read id command */	
	
	MfgCode = *FLASH_P2V(FLASH_BASE_ADDR);		/* read a manufacturer code at addr 0, address bit A0 is not used  */
	
	DevCode = *FLASH_P2V(DEV_CODE_ADDR);		/* read a device code at addr 1 */

    if (MfgCode == (MADE_BY_INTEL)) 
    {
		switch ( DevCode )								/* device code stored in addr 1, address bit A0 is not used, must shift 0x00000001<<1=0x00000002 */ 
		{
			case I28F640J3A:
				eeprom_size += 0x800000 * FLASH_WIDTH;		/* I28F640J3A */
				break;
            default:
                break;
        }
	}

	*FLASH_P2V(FLASH_BASE_ADDR) = READ_ID_CMD;	/* issue 2nd read id command */	
	
	*FLASH_P2V(FLASH_BASE_ADDR) = RESET_CMD; /* issue read array command */	
	
	delay_and_flush();	/* wait for Flash to re-enter Read Array mode */
#endif

	printf( "\nManufacturer Code = 0x%x\n", MfgCode);
	printf( "Device Code = %x\n", DevCode);
	printf( "Flash Memory size = 0x%x\n", eeprom_size);

    return;
}

/********************************************************/
/* RESERVED AREA CHECK                         			*/
/*                                   					*/
/* returns TRUE if the address falls into the 			*/
/* 	reserved system area								*/
/* returns FALSE if the address is outside  			*/
/* 	the reserved system area							*/
/********************************************************/
int reserved_check(ADDR addr, unsigned long length)
{

    /* check start address */
    if ( ( addr >= RESERVED_AREA1 ) && ( addr <= ( FLASH_BLK4_BASE_ADDR - 1 ) ) )
		return TRUE;
	

    /* must be outside the area */
	else
		return FALSE;
}

/********************************************************/
/* IS EEPROM											*/
/* Check if memory is Flash								*/
/*														*/
/* returns TRUE if it is; FALSE if not eeprom ;			*/
/* returns ERROR bad addr or partial eeprom				*/
/*														*/
/********************************************************/
int is_eeprom(ADDR addr, unsigned long length)
{
    ADDR eeprom_end = flash_addr + eeprom_size - 1;
    ADDR block_end = addr + length - 1;

    /* Check for wrap: if the address and length given wrap past
     * the end of memory, it is an error. */
    if (block_end < addr)
        return ERR;
    if (addr >= flash_addr && block_end <= eeprom_end)
        return TRUE;
    if (addr > eeprom_end || block_end < flash_addr)
        return FALSE;
    /* If the block was partly within the Flash, it is an error. */
    return ERR;
}


/********************************************************/
/* CHECK EEPROM											*/
/* Check if Flash is Blank								*/
/*														*/
/* returns OK if it is; returns ERROR and sets cmd_stat */
/* to an error code if memory region is not Flash or if */
/* it is not blank.										*/
/*														*/
/********************************************************/
int check_eeprom(ADDR addr, unsigned long length)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -