?? flash.c
字號:
//=============================================================================//// 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>#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 0xa0000000.#define FLASH_P2V(x) ((volatile FLASH_TYPE *)(((unsigned)(x) < 0x1000) ? \ ((unsigned)(x) | 0xa0000000) : \ (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 *)0xfe850000void 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 + -