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

📄 nand_read.c

📁 SMDK2440 boot code, base on vivi
💻 C
字号:
/*  * vivi/s3c2410/nand_read.c: Simple NAND read functions for booting from NAND * * Copyright (C) 2002 MIZI Research, Inc. * * Author: Hwang, Chideok <hwang@mizi.com> * Date  : $Date: 2004/03/25 04:42:41 $ * * $Revision: 1.12 $ * $Id: param.c,v 1.9 2002/07/11 06:17:20 nandy Exp  * * History * * 2002-05-xx: Hwang, Chideok <hwang@mizi.com> *    - 瞪芭扼绊 抄叼俊霸 淋. * * 2002-05-xx: Chan Gyun Jeong <cgjeong@mizi.com> *    - 抄叼狼 何殴阑 罐绊 力措肺 悼累窍档废 荐沥. * * 2002-08-10: Yong-iL Joh <tolkien@mizi.com> *    - SECTOR_SIZE啊 512牢 仇篮 促 佬档废 荐沥 * * 2003-04-08: Janghoon Lyu <nandy@mizi.com> *    - Check bad block when vivi copy itself.  *    - Add a function called nand_read_oob_ll() * * NOTE: Don't use printk() */#include <config.h>#include <machine.h>#include <memory.h>/*  * 构 汗棱窍变 窍瘤父, 捞犯霸扼档 东户篮 且 荐 乐嚼聪促. * 弊贰档 8M俊辑绰 悼累救钦聪促. 恐 弊繁瘤 葛福摆嚼聪促. */#undef CONFIG_SMC_SUPPORT_8M#if defined(CONFIG_SMC_SUPPORT_8M)#define CONFIG_SMC_3CYCLE_ADDRESSING#define VIVI_BLOCKS		(16)#else#define CONFIG_SMC_4CYCLE_ADDRESSING#define VIVI_BLOCKS		(8)#endif#ifdef CONFIG_SMC_SUPPORT_8M#define NAND_PAGES_IN_BLOCK	(16)#else#define NAND_PAGES_IN_BLOCK	(32)#endif#define NAND_PAGE_SIZE		(512)#define NAND_PAGE_MASK		(NAND_PAGE_SIZE - 1)#define NAND_BLOCK_SIZE		(NAND_PAGE_SIZE*NAND_PAGES_IN_BLOCK)#define NAND_BLOCK_MASK		(NAND_BLOCK_SIZE - 1)#define NAND_OOB_SIZE		(16)#define TAKE_SOME_DELAY		({ for(i=0; i<10; i++); })#define BUSY 1static inline void wait_idle(void) {	int i;	for(i=0; i<10; i++);	while(!(NFSTAT & BUSY)) ;}static voidset_address(unsigned long addr){	NFADDR = addr & 0xff;	NFADDR = (addr >> 9) & 0xff;	NFADDR = (addr >> 17) & 0xff;#ifdef CONFIG_SMC_4CYCLE_ADDRESSING	NFADDR = (addr >> 25) & 0xff;#endif}static intnand_read_page_ll(unsigned char *buf, unsigned long addr){	int i;	if (addr & NAND_PAGE_MASK) {		return -1;	/* invalid alignment */	}	/* chip Enable */	NFCONF &= ~0x800;	TAKE_SOME_DELAY;	/* READ0 */	NFCMD = 0;	/* Write Address */	set_address(addr);	wait_idle();	/* Read data */	for(i=0; i < NAND_PAGE_SIZE; i++) {		*buf = (NFDATA & 0xff);		buf++;	}	/* chip Disable */	NFCONF |= 0x800;	return 0;}/* low level nand read function */static intnand_read_oob_ll(char *buf, unsigned long addr){	int i;	if ((addr & NAND_BLOCK_MASK)) {		return -1;	/* invalid alignment */	}	/* Chip Enable */	NFCONF &= ~0x800;	TAKE_SOME_DELAY;	/* READOOB */	NFCMD = 0x50;	/* Write Address */	set_address(addr);	wait_idle();	/* Read oob data */	for(i=0; i < NAND_OOB_SIZE; i++) {		*buf = (NFDATA & 0xff);		buf++;	}	/* Chip Disable */	NFCONF |= 0x800;	return 0;}static intis_bad_block(unsigned long addr){	char oob_buf[16];	nand_read_oob_ll((char *)oob_buf, addr);	if (oob_buf[5] != 0xff)		return 1;	else		return 0;}/* * Read data from NAND. */intnandll_read_blocks(unsigned long dst_addr, unsigned long src_addr, int size){	char *buf = (char *)dst_addr;		int i;	if ((src_addr & NAND_BLOCK_MASK) || (size & NAND_PAGE_MASK))		return -1;	/* invalid alignment */	while (size > 0) {		/* If this block is bad, go next block */		if (is_bad_block(src_addr)) {			src_addr += NAND_BLOCK_SIZE;			continue;		}		/* Read block */		for (i = 0; i < NAND_PAGES_IN_BLOCK; i++) {			nand_read_page_ll((char *)buf, src_addr);			buf += NAND_PAGE_SIZE;			src_addr += NAND_PAGE_SIZE;			size -= NAND_PAGE_SIZE;			if (size == 0) break;		}	}	return 0;}static voidnandll_reset(void){	NFCONF = 0xf830;		/* initial value */	NFCONF &= ~(0x800);		/* enable chip */	NFCMD = 0xff;			/* RESET command */	wait_idle();	NFCONF |= (0x800);		/* disable chip */}intcopy_vivi_to_ram(void){	nandll_reset();	/* Copy vivi to ram. 128k is enough. */	return nandll_read_blocks(VIVI_BASE, 0x0, (VIVI_BLOCKS*NAND_BLOCK_SIZE));}

⌨️ 快捷键说明

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