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

📄 fl_nvram.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/*	$Id: fl_nvram.c,v 1.2 2002/08/17 19:41:19 patrik Exp $ *//* * Copyright (c) 2002 Patrik Lindergren (www.lindergren.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 Patrik Lindergren. * 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 <sys/types.h>#include <stdio.h>#include <setjmp.h>#include <termio.h>#include <string.h>#include <include/pflash.h>#include <pmon.h>static int cksum __P((void *, size_t, int));static void nvram_enable __P((void));static void nvram_disable __P((void));static int nvram_invalid = 0;extern int md_pipefreq;extern int md_cpufreq;/* *   --- NVRAM handling code --- *//* *  Special copy that does it bytewise, guaranteed! */#ifdef VXWORKSstatic void bytecopy __P((char *, char *, size_t));static voidbytecopy(char *src, char *dst, size_t size){	if(src == NULL) {		*dst = '\0';	}	else if (dst >= src && dst < src + size) {		src += size;		dst += size;		while (size--) {			*--dst = *--src;		}	}	else while (size--) {		*dst++ = *src++;	}}#endif /* VXWORKS */static voidnvram_enable(){}static voidnvram_disable(){}/* *  Read in environment from NV-ram and set. */voidtgt_mapenv(int (*func) __P((char *, char *))){	char *ep;	char env[256];        char *nvram;	int i;        nvram = (char *)NVRAM_BASE;	nvram += NVRAM_OFFS;        	/*	 *  Check integrity of the NVRAM env area. If not in order	 *  initialize it to empty.	 */	if(cksum((void *)nvram, NVRAM_SIZE, 0) != 0) {		nvram_invalid = 1;				SBD_DISPLAY ("ENVC", CHKPNT_MAPV);	} else {		ep = nvram + 2;		while(*ep != 0) {			char *val = 0, *p = env;			i = 0;			while((*p++ = *ep++) != 0 && (ep < nvram + NVRAM_SIZE) && i++ < 255) {				if((*(p - 1) == '=') && (val == NULL)) {					*(p - 1) = '\0';					val = p;				}			}			if(ep < nvram + NVRAM_SIZE && i < 255) {				(*func)(env, val);			}			else {				nvram_invalid = 2;				break;			}		}		SBD_DISPLAY ("ENVV", CHKPNT_MAPV);#ifdef VXWORKS		bytecopy((char *)NVRAM_VXWORKS, env, sizeof(env));		for(i = 0; isprint(env[i]) && i < 255; i++ );		env[i] = '\0';			(*func)("vxWorks", env);#endif /* VXWORKS */	}		sprintf(env, "%d", memorysize / (1024 * 1024));	(*func)("memsize", env);		sprintf(env, "%d", md_pipefreq);	(*func)("cpuclock", env);		sprintf(env, "%d", md_cpufreq);	(*func)("busclock", env);		(*func)("systype", SYSTYPE);	(*func)("targetname", TARGETNAME);	SBD_DISPLAY ("ENVM", CHKPNT_MAPV);}inttgt_unsetenv(char *name){	char *ep;	char *np;	char *sp;	char *nvram;	char nvrambuf[NVRAM_SIZE];	if(nvram_invalid) {		return(0);	}        nvram = (char *)NVRAM_BASE;	nvram += NVRAM_OFFS;	memcpy(nvrambuf, nvram, sizeof(nvrambuf));	ep = &nvrambuf[2];	while((*ep != '\0') && (ep < nvrambuf + sizeof(nvrambuf))) {		np = name;		sp = ep;		while((*ep == *np) && (*ep != '=') && (*np != '\0')) {			ep++;			np++;		}		if((*np == '\0') && ((*ep == '\0') || (*ep == '='))) {			while(*ep++);			while(ep <= nvrambuf + sizeof(nvrambuf)) {				*sp++ = *ep++;			}			if(nvrambuf[2] == '\0') {				nvrambuf[3] = '\0';			}			cksum(nvrambuf, sizeof(nvrambuf), 1);			if(fl_erase_device(nvram, NVRAM_SIZE, FALSE)) {				return(-1);			}			if(fl_program_device(nvram, nvrambuf, NVRAM_SIZE, FALSE)) {				return(-1);			}			return(1);		}		else if(*ep != '\0') {			while(*ep++ != '\0');		}	}	return(0);}inttgt_setenv(char *name, char *value){	char *ep;	int envlen;	char *nvram;	char nvrambuf[NVRAM_SIZE];		/* Non permanent vars. */	if(strcmp(EXPERT, name) == 0) {		return(1);	}		/* Calculate total env mem size requiered */	envlen = strlen(name);	if(envlen == 0) {		return(0);	}	if(value != NULL) {		envlen += strlen(value);	}	envlen += 2;	/* '=' + null byte */	if(envlen > 255) {		return(0);	/* Are you crazy!? */	}		nvram = (char *)NVRAM_BASE;	nvram += NVRAM_OFFS;	memcpy(nvrambuf, nvram, sizeof(nvrambuf));		/* If NVRAM is found to be uninitialized, reinit it. */	if(nvram_invalid) {		nvram_enable();		memset(nvrambuf, -1, NVRAM_SIZE);		nvrambuf[2] = '\0';		nvrambuf[3] = '\0';		cksum((void *)nvrambuf, sizeof(nvrambuf), 1);		if(fl_erase_device(nvram, NVRAM_SIZE, FALSE)) {			return(-1);		}			if(fl_program_device(nvram, nvrambuf, NVRAM_SIZE, FALSE)) {			return(-1);		}		nvram_invalid = 0;#ifdef VXWORKS		bytecopy(NVRAM_VXWORKS_DEFAULT, (char *)NVRAM_VXWORKS,			 sizeof(NVRAM_VXWORKS_DEFAULT));#endif /* VXWORKS */		nvram_disable();	}#ifdef VXWORKS	if(strcmp("vxWorks", name) == 0) {		nvram_enable();		bytecopy(value, (char *)NVRAM_VXWORKS, envlen);		nvram_disable();		return(1);	}#endif /* VXWORKS */		/* Remove any current setting */	tgt_unsetenv(name);		/* Find end of evironment strings */	memcpy(nvrambuf, nvram, sizeof(nvrambuf));	ep = &nvrambuf[2];	if(*ep != '\0') {		do {			while(*ep++ != '\0');		} while(*ep++ != '\0');		ep--;	}	if(((int)ep + sizeof(nvrambuf) - (int)ep) < (envlen + 1)) {		return(0);	/* Bummer! */ 	}		/*	 *  Special case heaptop must always be first since it	 *  can change how memory allocation works.	 */	nvram_enable();	if(strcmp("heaptop", name) == 0) {		bcopy(&nvrambuf[2], &nvrambuf[2] + envlen,			 ep - &nvrambuf[1]);		ep = &nvrambuf[2];		while(*name != '\0') {			*ep++ = *name++;		}		if(value != NULL) {			*ep++ = '=';			while((*ep++ = *value++) != '\0');		}		else {			*ep++ = '\0';		}	}	else {		while(*name != '\0') {			*ep++ = *name++;		}		if(value != NULL) {			*ep++ = '=';			while((*ep++ = *value++) != '\0');		}		else {			*ep++ = '\0';		}		*ep++ = '\0';	/* End of env strings */	}	cksum(nvrambuf, sizeof(nvrambuf), 1);	if(fl_erase_device(nvram, NVRAM_SIZE, FALSE)) {		return(0);	}	if(fl_program_device(nvram, nvrambuf, NVRAM_SIZE, FALSE)) {		return(0);	}	nvram_disable();	return(1);}/* *  Calculate checksum. If 'set' checksum is calculated and set. */static intcksum(void *p, size_t s, int set){	u_int16_t sum = 0;	u_int8_t *sp = p;	int sz = s / 2;	if(set) {		*sp = 0;	/* Clear checksum */		*(sp+1) = 0;	/* Clear checksum */	}	while(sz--) {		sum += (*sp++) << 8;		sum += *sp++;	}	if(set) {		sum = -sum;		*(u_int8_t *)p = sum >> 8;		*((u_int8_t *)p+1) = sum;	}	return(sum);}

⌨️ 快捷键说明

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