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

📄 common_util.c

📁 gumstiz u-boot loader in linux
💻 C
字号:
/* * (C) Copyright 2001 * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * */#include <common.h>#include <command.h>#include <video_fb.h>#include "common_util.h"#include <asm/processor.h>#include <asm/byteorder.h>#include <i2c.h>#include <devices.h>#include <pci.h>#include <malloc.h>#include <bzlib.h>#ifdef CONFIG_PIP405#include "../pip405/pip405.h"#include <405gp_pci.h>#endif#ifdef CONFIG_MIP405#include "../mip405/mip405.h"#include <405gp_pci.h>#endif#if defined(CONFIG_PATI)#define FIRM_START 0xFFF00000#endifextern int gunzip(void *, int, uchar *, unsigned long *);extern int mem_test(ulong start, ulong ramsize, int quiet);#define I2C_BACKUP_ADDR 0x7C00		/* 0x200 bytes for backup */#define IMAGE_SIZE CFG_MONITOR_LEN	/* ugly, but it works for now */extern flash_info_t flash_info[];	/* info for FLASH chips */static image_header_t header;static intmpl_prg(uchar *src, ulong size){	ulong start;	flash_info_t *info;	int i, rc;#if defined(CONFIG_PATI)	int start_sect;#endif#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)	char *copystr = (char *)src;	ulong *magic = (ulong *)src;#endif	info = &flash_info[0];#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)	if (ntohl(magic[0]) != IH_MAGIC) {		puts("Bad Magic number\n");		return -1;	}	/* some more checks before we delete the Flash... */	/* Checking the ISO_STRING prevents to program a	 * wrong Firmware Image into the flash.	 */	i = 4; /* skip Magic number */	while (1) {		if (strncmp(&copystr[i], "MEV-", 4) == 0)			break;		if (i++ >= 0x100) {			puts("Firmware Image for unknown Target\n");			return -1;		}	}	/* we have the ISO STRING, check */	if (strncmp(&copystr[i], CONFIG_ISO_STRING, sizeof(CONFIG_ISO_STRING)-1) != 0) {		printf("Wrong Firmware Image: %s\n", &copystr[i]);		return -1;	}#if !defined(CONFIG_PATI)	start = 0 - size;	for (i = info->sector_count-1; i > 0; i--) {		info->protect[i] = 0; /* unprotect this sector */		if (start >= info->start[i])			break;	}	/* set-up flash location */	/* now erase flash */	printf("Erasing at %lx (sector %d) (start %lx)\n",				start,i,info->start[i]);	if ((rc = flash_erase (info, i, info->sector_count-1)) != 0) {		puts("ERROR ");		flash_perror(rc);		return (1);	}#else /* #if !defined(CONFIG_PATI */	start = FIRM_START;	start_sect = -1;	for (i = 0; i < info->sector_count; i++) {		if (start < info->start[i]) {			start_sect = i - 1;			break;		}	}	info->protect[i - 1] = 0;	/* unprotect this sector */	for (; i < info->sector_count; i++) {		if ((start + size) < info->start[i])			break;		info->protect[i] = 0;	/* unprotect this sector */	}	i--;	/* set-up flash location */	/* now erase flash */	printf ("Erasing at %lx to %lx (sector %d to %d) (%lx to %lx)\n",		start, start + size, start_sect, i,		info->start[start_sect], info->start[i]);	if ((rc = flash_erase (info, start_sect, i)) != 0) {		puts ("ERROR ");		flash_perror (rc);		return (1);	}#endif /* defined(CONFIG_PATI) */#elif defined(CONFIG_VCMA9)	start = 0;	for (i = 0; i <info->sector_count; i++) {		info->protect[i] = 0; /* unprotect this sector */		if (size < info->start[i])		    break;	}	/* set-up flash location */	/* now erase flash */	printf("Erasing at %lx (sector %d) (start %lx)\n",				start,0,info->start[0]);	if ((rc = flash_erase (info, 0, i)) != 0) {		puts("ERROR ");		flash_perror(rc);		return (1);	}#endif	printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",		(ulong)src, size);	if ((rc = flash_write ((char *)src, start, size)) != 0) {		puts("ERROR ");		flash_perror(rc);		return (1);	}	puts("OK programming done\n");	return 0;}static intmpl_prg_image(uchar *ld_addr){	unsigned long len, checksum;	uchar *data;	image_header_t *hdr = &header;	int rc;	/* Copy header so we can blank CRC field for re-calculation */	memcpy (&header, (char *)ld_addr, sizeof(image_header_t));	if (ntohl(hdr->ih_magic)  != IH_MAGIC) {		puts("Bad Magic Number\n");		return 1;	}	print_image_hdr(hdr);	if (hdr->ih_os  != IH_OS_U_BOOT) {		puts("No U-Boot Image\n");		return 1;	}	if (hdr->ih_type  != IH_TYPE_FIRMWARE) {		puts("No Firmware Image\n");		return 1;	}	data = (uchar *)&header;	len  = sizeof(image_header_t);	checksum = ntohl(hdr->ih_hcrc);	hdr->ih_hcrc = 0;	if (crc32 (0, (uchar *)data, len) != checksum) {		puts("Bad Header Checksum\n");		return 1;	}	data = ld_addr + sizeof(image_header_t);	len  = ntohl(hdr->ih_size);	puts("Verifying Checksum ... ");	if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {		puts("Bad Data CRC\n");		return 1;	}	puts("OK\n");	if (hdr->ih_comp != IH_COMP_NONE) {		uchar *buf;		/* reserve space for uncompressed image */		if ((buf = malloc(IMAGE_SIZE)) == NULL) {		    	puts("Insufficient space for decompression\n");			return 1;		}		switch (hdr->ih_comp) {		case IH_COMP_GZIP:			puts("Uncompressing (GZIP) ... ");			rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len);			if (rc != 0) {				puts("GUNZIP ERROR\n");				free(buf);				return 1;			}			puts("OK\n");			break;#ifdef CONFIG_BZIP2		case IH_COMP_BZIP2:			puts("Uncompressing (BZIP2) ... ");			{			uint retlen = IMAGE_SIZE;			rc = BZ2_bzBuffToBuffDecompress ((char *)(buf), &retlen,				(char *)data, len, 0, 0);			len = retlen;			}			if (rc != BZ_OK) {				printf ("BUNZIP2 ERROR: %d\n", rc);				free(buf);				return 1;			}			puts("OK\n");			break;#endif		default:			printf ("Unimplemented compression type %d\n", hdr->ih_comp);			free(buf);			return 1;		}		rc = mpl_prg(buf, len);		free(buf);	} else {		rc = mpl_prg(data, len);	}	return(rc);}#if !defined(CONFIG_PATI)void get_backup_values(backup_t *buf){	i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));}void set_backup_values(int overwrite){	backup_t back;	int i;	get_backup_values(&back);	if(!overwrite) {		if(strncmp(back.signature,"MPL\0",4)==0) {			puts("Not possible to write Backup\n");			return;		}	}	memcpy(back.signature,"MPL\0",4);	i = getenv_r("serial#",back.serial_name,16);	if(i < 0) {		puts("Not possible to write Backup\n");		return;	}	back.serial_name[16]=0;	i = getenv_r("ethaddr",back.eth_addr,20);	if(i < 0) {		puts("Not possible to write Backup\n");		return;	}	back.eth_addr[20]=0;	i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));}void clear_env_values(void){	backup_t back;	unsigned char env_crc[4];	memset(&back,0xff,sizeof(backup_t));	memset(env_crc,0x00,4);	i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));	i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);}/* * check crc of "older" environment */int check_env_old_size(ulong oldsize){	ulong crc, len, new;	unsigned off;	uchar buf[64];	/* read old CRC */	eeprom_read (CFG_DEF_EEPROM_ADDR,		     CFG_ENV_OFFSET,		     (uchar *)&crc, sizeof(ulong));	new = 0;	len = oldsize;	off = sizeof(long);	len = oldsize-off;	while (len > 0) {		int n = (len > sizeof(buf)) ? sizeof(buf) : len;		eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);		new = crc32 (new, buf, n);		len -= n;		off += n;	}	return (crc == new);}static ulong oldsizes[] = {	0x200,	0x800,	0};void copy_old_env(ulong size){	uchar name_buf[64];	uchar value_buf[0x800];	uchar c;	ulong len;	unsigned off;	uchar *name, *value;	name=&name_buf[0];	value=&value_buf[0];	len=size;	off = sizeof(long);	while (len > off) {		eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);		if(c != '=') {			*name++=c;			off++;		}		else {			*name++='\0';			off++;			do {				eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);				*value++=c;				off++;				if(c == '\0')					break;			} while(len > off);			name=&name_buf[0];			value=&value_buf[0];			if(strncmp((char *)name,"baudrate",8)!=0) {				setenv((char *)name,(char *)value);			}		}	}}void check_env(void){	char *s;	int i=0;	char buf[32];	backup_t back;	s=getenv("serial#");	if(!s) {		while(oldsizes[i]) {			if(check_env_old_size(oldsizes[i]))				break;			i++;		}		if(!oldsizes[i]) {			/* no old environment has been found */			get_backup_values (&back);			if (strncmp (back.signature, "MPL\0", 4) == 0) {				sprintf (buf, "%s", back.serial_name);				setenv ("serial#", buf);				sprintf (buf, "%s", back.eth_addr);				setenv ("ethaddr", buf);				printf ("INFO:  serial# and ethaddr recovered, use saveenv\n");				return;			}		}		else {			copy_old_env(oldsizes[i]);			puts("INFO:  old environment ajusted, use saveenv\n");		}	}	else {		/* check if back up is set */		get_backup_values(&back);		if(strncmp(back.signature,"MPL\0",4)!=0) {			set_backup_values(0);		}	}}extern device_t *stdio_devices[];extern char *stdio_names[];void show_stdio_dev(void){	/* Print information */	puts("In:    ");	if (stdio_devices[stdin] == NULL) {		puts("No input devices available!\n");	} else {		printf ("%s\n", stdio_devices[stdin]->name);	}	puts("Out:   ");	if (stdio_devices[stdout] == NULL) {		puts("No output devices available!\n");	} else {		printf ("%s\n", stdio_devices[stdout]->name);	}	puts("Err:   ");	if (stdio_devices[stderr] == NULL) {		puts("No error devices available!\n");	} else {		printf ("%s\n", stdio_devices[stderr]->name);	}}#endif /* #if !defined(CONFIG_PATI) */int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ 	ulong size,src,ld_addr;	int result;#if !defined(CONFIG_PATI)	backup_t back;	src = MULTI_PURPOSE_SOCKET_ADDR;	size = IMAGE_SIZE;#endif	if (strcmp(argv[1], "flash") == 0)	{#if (CONFIG_COMMANDS & CFG_CMD_FDC)		if (strcmp(argv[2], "floppy") == 0) { 			char *local_args[3];			extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);			puts("\nupdating bootloader image from floppy\n");			local_args[0] = argv[0];	    		if(argc==4) {				local_args[1] = argv[3];				local_args[2] = NULL;				ld_addr=simple_strtoul(argv[3], NULL, 16);				result=do_fdcboot(cmdtp, 0, 2, local_args);			}			else {				local_args[1] = NULL;				ld_addr=CFG_LOAD_ADDR;				result=do_fdcboot(cmdtp, 0, 1, local_args);			}			result=mpl_prg_image((uchar *)ld_addr);			return result;		}#endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */		if (strcmp(argv[2], "mem") == 0) {	    		if(argc==4) {				ld_addr=simple_strtoul(argv[3], NULL, 16);			}			else {				ld_addr=load_addr;			}			printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);			result=mpl_prg_image((uchar *)ld_addr);			return result;		}#if !defined(CONFIG_PATI)		if (strcmp(argv[2], "mps") == 0) {			puts("\nupdating bootloader image from MPS\n");			result=mpl_prg((uchar *)src,size);			return result;		}#endif /* #if !defined(CONFIG_PATI)	*/	}	if (strcmp(argv[1], "mem") == 0)	{		result=0;		if(argc==3)		{			result = (int)simple_strtol(argv[2], NULL, 16);	    }	    src=(unsigned long)&result;	    src-=CFG_MEMTEST_START;	    src-=(100*1024); /* - 100k */	    src&=0xfff00000;	    size=0;	    do {	    	size++;			printf("\n\nPass %ld\n",size);			mem_test(CFG_MEMTEST_START,src,1);			if(ctrlc())				break;			if(result>0)				result--;		}while(result);		return 0;	}#if !defined(CONFIG_PATI)	if (strcmp(argv[1], "clearenvvalues") == 0)	{ 		if (strcmp(argv[2], "yes") == 0)		{			clear_env_values();			return 0;		}	}	if (strcmp(argv[1], "getback") == 0) {		get_backup_values(&back);		back.signature[3]=0;		back.serial_name[16]=0;		back.eth_addr[20]=0;		printf("GetBackUp: signature: %s\n",back.signature);		printf("           serial#:   %s\n",back.serial_name);		printf("           ethaddr:   %s\n",back.eth_addr);		return 0;	}	if (strcmp(argv[1], "setback") == 0) {		set_backup_values(1);		return 0;	}#endif	printf("Usage:\n%s\n", cmdtp->usage);	return 1;}#if (CONFIG_COMMANDS & CFG_CMD_DOC)extern void doc_probe(ulong physadr);void doc_init (void){  doc_probe(MULTI_PURPOSE_SOCKET_ADDR);}#endif#ifdef CONFIG_VIDEO/****************************************************** * Routines to display the Board information * to the screen (since the VGA will be initialized as last, * we must resend the infos) */#ifdef CONFIG_CONSOLE_EXTRA_INFOextern GraphicDevice ctfb;extern int get_boot_mode(void);void video_get_info_str (int line_number, char *info){	/* init video info strings for graphic console */	DECLARE_GLOBAL_DATA_PTR;	PPC405_SYS_INFO sys_info;	char rev;	int i,boot;	unsigned long pvr;	char buf[64];	char tmp[16];	char cpustr[16];	char *s, *e, bc;	switch (line_number)	{	case 2:		/* CPU and board infos */		pvr=get_pvr();		get_sys_info (&sys_info);		switch (pvr) {			case PVR_405GP_RB: rev='B'; break;			case PVR_405GP_RC: rev='C'; break;			case PVR_405GP_RD: rev='D'; break;			case PVR_405GP_RE: rev='E'; break;			case PVR_405GPR_RB: rev='B'; break;			default:           rev='?'; break;		}		if(pvr==PVR_405GPR_RB)			sprintf(cpustr,"PPC405GPr %c",rev);		else			sprintf(cpustr,"PPC405GP %c",rev);		/* Board info */		i=0;		s=getenv ("serial#");#ifdef CONFIG_PIP405		if (!s || strncmp (s, "PIP405", 6)) {			sprintf(buf,"### No HW ID - assuming PIP405");		}#endif#ifdef CONFIG_MIP405		if (!s || strncmp (s, "MIP405", 6)) {			sprintf(buf,"### No HW ID - assuming MIP405");		}#endif		else {			for (e = s; *e; ++e) {				if (*e == ' ')					break;			}			for (; s < e; ++s) {				if (*s == '_') {					++s;					break;				}				buf[i++]=*s;			}			sprintf(&buf[i]," SN ");			i+=4;			for (; s < e; ++s) {				buf[i++]=*s;			}			buf[i++]=0;		}		sprintf (info," %s %s %s MHz (%lu/%lu/%lu MHz)",			buf, cpustr,			strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,			sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,			sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);		return;	case 3:		/* Memory Info */		boot = get_boot_mode();		bc = in8 (CONFIG_PORT_ADDR);		sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",			gd->bd->bi_memsize / 0x100000,			gd->bd->bi_flashsize / 0x100000,			bc,			(boot & BOOT_MPS) ? "MPS boot" : "Flash boot",			ctfb.modeIdent);		return;	case 1:		sprintf	(buf, "%s",CONFIG_IDENT_STRING);		sprintf (info, " %s", &buf[1]);		return;    }    /* no more info lines */    *info = 0;    return;}#endif /* CONFIG_CONSOLE_EXTRA_INFO */#endif /* CONFIG_VIDEO */

⌨️ 快捷键说明

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