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

📄 flash_int.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/*	$Id: flash_int.c,v 1.3 2001/12/20 15:05:48 pefo Exp $ *//* * Copyright (c) 2001 ipUnplugged AB   (www.ipunplugged.com) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by *	ipUnplugged AB, Sweden. * 4. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <machine/pio.h>#include <pmon.h>#include <pflash.h>#include <dev/pflash_tgt.h>extern void delay __P((int));int fl_erase_chip_int __P((struct fl_map *, struct fl_device *));int fl_erase_sector_int __P((struct fl_map *, struct fl_device *, int ));int fl_isbusy_int __P((struct fl_map *, struct fl_device *, int, int, int));int fl_reset_int __P((struct fl_map *, struct fl_device *));int fl_erase_suspend_int __P((struct fl_map *, struct fl_device *));int fl_erase_resume_int __P((struct fl_map *, struct fl_device *));int fl_program_int __P((struct fl_map *, struct fl_device *, int , unsigned char *));struct fl_functions fl_func_int = {fl_erase_chip_int,                                   fl_erase_sector_int,                                   fl_isbusy_int,                                   fl_reset_int,                                   fl_erase_suspend_int,                                   fl_program_int};/* *   FLASH Programming functions. * *   Handle flash programing aspects such as different types *   organizations and actual HW design organization/interleaving. *   Combinations can be endless but an attempt to make something *   more MI may be done later when the variations become clear. */static quad_t widedata;#define	SETWIDE(x) do {						\			u_int32_t __a = x;			\			__a |= __a << 8;				\			__a |= __a << 16;				\			widedata = (quad_t)__a << 32 | __a;		\		} while(0)/* *  Inlineable function to send INT command to flash. */static __inline void fl_command_int __P((struct fl_map *, int, int));static __inline voidfl_command_int(map, command, offset)	struct fl_map *map;	int command;	int offset;{	delay(5);	switch(map->fl_map_bus) {	case FL_BUS_8:		outb(map->fl_map_base + offset, command);		break;	case FL_BUS_16:		SETWIDE(command);		outw(map->fl_map_base + offset, widedata);		break;	case FL_BUS_32:		SETWIDE(command);		outl(map->fl_map_base + offset, widedata);		break;	case FL_BUS_64:		SETWIDE(command);		movequad((void *)(map->fl_map_base + offset), &widedata);		break;	}}/* *  Function to erase sector */intfl_erase_sector_int(map, dev, offset)	struct fl_map *map;	struct fl_device *dev;	int offset;{	fl_command_int(map, FL_INT_BE, 0);	fl_command_int(map, FL_INT_CNF, (int)offset);	return(0);}/* *  Function to Program */intfl_program_int(map, dev, pa, pd)	struct fl_map *map;	struct fl_device *dev;	int pa;	unsigned char *pd;{	int stat;	fl_command_int(map, FL_INT_PGM, 0);	switch(map->fl_map_bus) {	case FL_BUS_8:		*(u_char *)(map->fl_map_base + pa) = *pd;		break;	case FL_BUS_16:		*(u_short *)(map->fl_map_base + pa) = *(u_short *)pd;		break;	case FL_BUS_32:		*(u_int *)(map->fl_map_base + pa) = *(u_int *)pd;		break;	case FL_BUS_64:		bcopy(pd, (void *)&widedata, 8);		movequad((void *)(map->fl_map_base + pa), &widedata);		break; 	}	do {		stat = fl_isbusy_int(map, dev, 0, pa, FALSE);	} while(stat == 1);	return(stat);}/* *  Function to erase chip */intfl_erase_chip_int(map, dev)	struct fl_map *map;	struct fl_device *dev;{	if(dev->fl_cap & FL_CAP_A7) {		fl_command_int(map, FL_INT_FCE_A7, 0);	}	else {		fl_command_int(map, FL_INT_FCE, 0);	}	fl_command_int(map, FL_INT_CNF, 0);	return(0);}/* *  Inlineable function to suspend erase sector */intfl_erase_suspend_int(map, dev)	struct fl_map *map;	struct fl_device *dev;{	return(0);}/* *  Inlineable function to resume erase sector */intfl_erase_resume_int(map, dev)	struct fl_map *map;	struct fl_device *dev;{	switch(map->fl_map_bus) {	case FL_BUS_8:		outb(map->fl_map_base, FL_RESUME);		break;	case FL_BUS_64:		break;	/* Leave this for now */	case FL_BUS_8_ON_64:		SETWIDE(0xaa);		movequad((void *)map->fl_map_base + (0x5555 << 3), &widedata);		SETWIDE(0x55);		movequad((void *)map->fl_map_base + (0x2aaa << 3), &widedata);		break;	}        return(0);}/* *  Inlineable function to "reset" flash, eg return to read mode. */intfl_reset_int(map, dev)	struct fl_map *map;	struct fl_device *dev;{#if 1	fl_command_int(map, FL_INT_CLR, 0);	fl_command_int(map, FL_INT_READ, 0);#else	switch(map->fl_map_bus) {	case FL_BUS_8:		outb((map->fl_map_base), FL_RESET);		break;	case FL_BUS_16:		SETWIDE(FL_RESET);		outw(map->fl_map_base + offset, widedata);		break;	case FL_BUS_32:		SETWIDE(FL_RESET);		outl(map->fl_map_base + offset, widedata);		break;	case FL_BUS_8_ON_64:		SETWIDE(FL_RESET);		movequad((void *)map->fl_map_base, &widedata);		break;	case FL_BUS_64:		fl_command_int(map, FL_INT_READ, 0);		break;	}#endif        return(0);}/* *  Generic function to poll flash BUSY if available. *  returns 1 if busy, 0 if OK, -1 if error. */intfl_isbusy_int(map, dev, what, offset, erase)	struct fl_device *dev;	struct fl_map *map;	int what;        int offset;	int erase;{	u_char *p;	int d;	switch(map->fl_map_bus) {	case FL_BUS_8:		d = !(inb(map->fl_map_base) & FL_INT_BUSY);		break;	case FL_BUS_16:		d = !(inw(map->fl_map_base) & FL_INT_BUSY);		break;	case FL_BUS_32:		d = inl(map->fl_map_base);		d &= (FL_INT_BUSY << 16) | FL_INT_BUSY;		d = d != ((FL_INT_BUSY << 16) | FL_INT_BUSY);		break;	case FL_BUS_64:		movequad(&widedata, (void *)map->fl_map_base);		p = (u_char *)&widedata;		d = !((p[1] & p[3] & p[5] & p[7]) & FL_INT_BUSY);		break;	}	return(d);}

⌨️ 快捷键说明

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