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

📄 flash.c.orig

📁 bootloader源代码
💻 ORIG
📖 第 1 页 / 共 2 页
字号:
/***************************************** Copyright (c) 2001-2002  Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the boot loader *//* * flash.c * * flash driver from scratch * following CFI (Common Flash Memory Interface) Specification 2.0 * support multiple flashes * * first revision by Ho Lee 10/31/2002 * code cleanup by Ho Lee 11/08/2002 */#include "config.h"#include "uart.h"#include "util.h"#include "specific.h"#include "io.h"#include "flash.h"#ifdef SUPPORT_FLASH/* * AM29LV160DB : 16 Mbit (0x200000) * buswidth : 2 (16 bits) * interleave : 1 * device type : 2 */#define CFIDEV_BUSWIDTH			2#define CFIDEV_INTERLEAVE		1#define CFIDEV_DEVTYPE			2//// for matching endian between CPU and CFI interface// CFI and HOST use same endian//#define cpu_to_cfi8(x) 			(x)#define cfi8_to_cpu(x) 			(x)#define cpu_to_cfi16(x) 		(x)#define cfi16_to_cpu(x) 		(x)#define cpu_to_cfi32(x) 		(x)#define cfi32_to_cpu(x) 		(x)//// address remapping// for JASPER, after remapping, 0x0000 - 0x2000 area of flash is mapped to 0x400000 - 0x402000//#define REMAPPED				0#if REMAPPED#define JFTL(x)					(((x) < 0x2000) ? ((x) + 0x400000) : (x))	// after remapping#else#define JFTL(x)					(x)											// before remapping#endif//// CFI information type definitions//#define P_ID_NONE 						0#define P_ID_INTEL_EXT 					1#define P_ID_AMD_STD 					2#define P_ID_INTEL_STD 					3#define P_ID_AMD_EXT 					4#define P_ID_MITSUBISHI_STD 			256#define P_ID_MITSUBISHI_EXT 			257#define P_ID_RESERVED 					65535struct cfi_ident {	unsigned char  qry[3];	unsigned short P_ID;	unsigned short P_ADR;	unsigned short A_ID;	unsigned short A_ADR;	unsigned char  VccMin;	unsigned char  VccMax;	unsigned char  VppMin;	unsigned char  VppMax;	unsigned char  WordWriteTimeoutTyp;	unsigned char  BufWriteTimeoutTyp;	unsigned char  BlockEraseTimeoutTyp;	unsigned char  ChipEraseTimeoutTyp;	unsigned char  WordWriteTimeoutMax;	unsigned char  BufWriteTimeoutMax;	unsigned char  BlockEraseTimeoutMax;	unsigned char  ChipEraseTimeoutMax;	unsigned char  DevSize;	unsigned short InterfaceDesc;	unsigned short MaxBufWriteSize;	unsigned char  NumEraseRegions;	unsigned int   EraseRegionInfo[FLASH_MAX_ERASE_REGIONS]; /* Not host ordered */} __attribute__((packed));struct cfi_eraseregions {	unsigned int start;	unsigned int size;	unsigned int blocks;};typedef enum { 	FL_READY,	FL_STATUS,	FL_CFI_QUERY,	FL_JEDEC_QUERY,	FL_ERASING,	FL_ERASE_SUSPENDING,	FL_ERASE_SUSPENDED,	FL_WRITING,	FL_WRITING_TO_BUFFER,	FL_WRITE_SUSPENDING,	FL_WRITE_SUSPENDED,	FL_PM_SUSPENDED,	FL_SYNCING,	FL_UNLOADING,	FL_LOCKING,	FL_UNLOCKING,	FL_UNKNOWN} flstate_t;struct cfi_private {	int exist;	int chip_state;	unsigned int base, size;	struct cfi_ident ident;	struct cfi_eraseregions erase_regions[FLASH_MAX_ERASE_REGIONS];	unsigned int addr_unlock1, addr_unlock2;};//// global variables//static int g_flash_inited = 0;static int g_flash_chips = 0;static struct cfi_private g_cfi[FLASH_MAX_CHIPSET];//// function prototypes//// data structure managementstatic struct cfi_private *get_free_cfi(void);static struct cfi_private *find_cfi(unsigned int addr);// CFI basic I/Ostatic __inline__ unsigned char cfi_read8(unsigned int addr) { return __raw_readb(JFTL(addr)); }static __inline__ unsigned short cfi_read16(unsigned int addr) { return __raw_readw(JFTL(addr)); }static __inline__ unsigned long cfi_read32(unsigned int addr) { return __raw_readl(JFTL(addr)); }static __inline__ void cfi_write8(unsigned int val, unsigned int addr) { __raw_writeb(val, addr); mb(); }static __inline__ void cfi_write16(unsigned int val, unsigned int addr) { __raw_writew(val, addr); mb(); }static __inline__ void cfi_write32(unsigned int val, unsigned int addr) { __raw_writel(val, addr); mb(); }// CFI advanced I/Ostatic __inline__ unsigned int cfi_build_cmd_addr(unsigned int cmd_ofs);static __inline__ unsigned int cfi_build_cmd(unsigned int cmd);static __inline__ void cfi_send_gen_cmd(unsigned int cmd, unsigned int cmd_addr, unsigned int base);// probing & setupstatic int cfi_probe_chip(struct cfi_private *pcfi);static int qry_present(unsigned int base);static int cfi_chip_setup(struct cfi_private *pcfi);static void cfi_cmdset_0002(struct cfi_private *pcfi);// init & basicint flash_found(void);int flash_init(unsigned int base, int force);// eraseint flash_erase_all(void);int flash_erase_oneblock(unsigned int addr);int flash_erase_region(unsigned int addr, unsigned int len);// writeint flash_write_onebyte(unsigned int addr, unsigned int data);int flash_write_oneword(unsigned int addr, unsigned int data);static int flash_write_data_internal(unsigned int addr, unsigned short *data, int nwords, struct cfi_private *pcfi);int flash_write_data(unsigned int addr, unsigned char *data, int len);// miscellaneousstatic char *cfi_vendorname(unsigned int vendor);void flash_list(void *vpcfi);int flash_calcblock(unsigned int addr, unsigned int *pstart, unsigned int *plen);//// data structure management// struct cfi_private *get_free_cfi(void){	int i;	for (i = 0; i < FLASH_MAX_CHIPSET; ++i)		if (!g_cfi[i].exist)			return &g_cfi[i];	return NULL;}struct cfi_private *find_cfi(unsigned int addr){	int i;	for (i = 0; i < FLASH_MAX_CHIPSET; ++i)		if (g_cfi[i].exist) 			if (addr >= g_cfi[i].base && addr < g_cfi[i].base + g_cfi[i].size)				return &g_cfi[i];	return NULL;}//// CFI basic I/O//__inline__ unsigned int cfi_read(addr){	switch (CFIDEV_BUSWIDTH) {	case 1 : 		return cfi_read8(addr);	case 2 : 		return cfi_read16(addr);	case 4 :		return cfi_read32(addr);	default :		return 0;	}}__inline__ void cfi_write(unsigned val, unsigned int addr){	switch (CFIDEV_BUSWIDTH) {	case 1 : 		cfi_write8(val, addr);		break;	case 2 : 		cfi_write16(val, addr);		break;	case 4 :		cfi_write32(val, addr);		break;	default :		break;	}}// // CFI advanced I/O//__inline__ unsigned int cfi_build_cmd_addr(unsigned int cmd_ofs){	return cmd_ofs * CFIDEV_DEVTYPE * CFIDEV_INTERLEAVE;}__inline__ unsigned int cfi_build_cmd(unsigned int cmd){	unsigned int val = 0;	switch (CFIDEV_BUSWIDTH) {	case 1 : 		val = cmd;		break;	case 2 : 		if (CFIDEV_INTERLEAVE == 1)			val = cpu_to_cfi16(cmd);		else if (CFIDEV_INTERLEAVE == 2)			val = cpu_to_cfi16((cmd << 8) | cmd);		break;	case 4 : 		if (CFIDEV_INTERLEAVE == 1)			val = cpu_to_cfi32(cmd);		else if (CFIDEV_INTERLEAVE == 2)			val = cpu_to_cfi32((cmd << 16) | cmd);		else if (CFIDEV_INTERLEAVE == 4) {			val = (cmd << 16) | cmd;			val = cpu_to_cfi32((val << 8) | val);		}		break;	default :		break;	}	return val;}__inline__ void cfi_send_gen_cmd(unsigned int cmd, unsigned int cmd_addr, unsigned int base){	cfi_write(cfi_build_cmd(cmd), base + cfi_build_cmd_addr(cmd_addr));}__inline__ void cfi_send_cmd(unsigned int cmd, unsigned int cmd_addr, unsigned int base){	cfi_write(cfi_build_cmd(cmd), base + cmd_addr);}//// probing & setup// int cfi_probe_chip(struct cfi_private *pcfi){	int ret;	if (pcfi->exist)		--g_flash_chips;	pcfi->exist = 0;	// Reset	cfi_send_gen_cmd(0xf0, 0, pcfi->base);	// Enter CFI Query mode	cfi_send_gen_cmd(0x98, 0x55, pcfi->base);	if ((ret = qry_present(pcfi->base)) != 0)		return ret;	pcfi->exist = 1;	++g_flash_chips;	if ((ret = cfi_chip_setup(pcfi)) != 0)		return ret;	// Reset	cfi_send_gen_cmd(0xf0, 0, pcfi->base);	// internal settings	cfi_cmdset_0002(pcfi);	return FLASH_OK;}int qry_present(unsigned int base){	return (cfi_read(base + cfi_build_cmd_addr(0x10)) == cfi_build_cmd('Q') &&		cfi_read(base + cfi_build_cmd_addr(0x11)) == cfi_build_cmd('R') &&		cfi_read(base + cfi_build_cmd_addr(0x12)) == cfi_build_cmd('Y')) ? FLASH_OK : FLASH_NOTEXIST;}int cfi_chip_setup(struct cfi_private *pcfi){	int i;	int num_erase_regions = cfi_read(pcfi->base + cfi_build_cmd_addr(0x2c));	unsigned int start;	if (num_erase_regions == 0)		return FLASH_NOREGION;	for (i = 0; i < (sizeof pcfi->ident) - (sizeof pcfi->ident.EraseRegionInfo) + (num_erase_regions * 4); ++i)		((unsigned char *) &pcfi->ident)[i] = cfi_read(pcfi->base + cfi_build_cmd_addr(0x10 + i));	for (i = 0, start = 0; i < num_erase_regions; ++i) {		pcfi->erase_regions[i].start = start;		pcfi->erase_regions[i].size = 0x100 * ((pcfi->ident.EraseRegionInfo[i] >> 16) & 0xffff);		pcfi->erase_regions[i].blocks = (pcfi->ident.EraseRegionInfo[i] & 0xffff) + 1;		start += pcfi->erase_regions[i].size * pcfi->erase_regions[i].blocks;	}	pcfi->size = 1 << pcfi->ident.DevSize;	return FLASH_OK;}void cfi_cmdset_0002(struct cfi_private *pcfi){	switch (CFIDEV_DEVTYPE) {	case 1 : 		pcfi->addr_unlock1 = 0x555;		pcfi->addr_unlock2 = 0x2aa;		break;	case 2 : 		pcfi->addr_unlock1 = 0xaaa;		pcfi->addr_unlock2 = (CFIDEV_BUSWIDTH == CFIDEV_INTERLEAVE) ? 0x555 : 0x554;		break;	case 4 :		pcfi->addr_unlock1 = 0x1555;		pcfi->addr_unlock2 = 0xaaa;		break;	}}//// init & basic//int flash_found(void)

⌨️ 快捷键说明

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