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

📄 l1.c

📁 嵌入式linux的bsp
💻 C
字号:
/* * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * 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 <ppcboot.h>#include "L1.h"#include <asm/processor.h>#include <405gp_i2c.h>#include <command.h>#include <cmd_nvedit.h>#include <cmd_bootm.h>#include <rtc.h>#include <net.h>#define FACTORY_SETTINGS 0xFFFC0000#define DHCP_BOOTFILE     67#define DHCP_ROOTPATH     17#define DHCP_L1_FIRMWARE 220#define DHCP_L1_KERNEL   221#define DHCP_L1_ROOTFS   222#define XTFTP 0x100000	/* TFTP things to this addr for staging */#define TFTP_NAMELEN 128/* Things DHCP server can tellme about.  If there's no flash address, then * they dont participate in 'update' to flash, and we force their values * back to '0' every boot to be sure to get them fresh from DHCP */typedef struct dhcp_item_s {	u8   dhcp_option;	char tftpname[TFTP_NAMELEN];	char envname[16];	u32	 new_version;	u32  flashaddr;	u32  flashlen;} dhcp_item_t;static dhcp_item_t Things[] = {	{DHCP_BOOTFILE,    "", "bootfile",    0, 0,          0},	{DHCP_ROOTPATH,    "", "rootpath",    0, 0,          0},	{DHCP_L1_FIRMWARE, "", "L1-firmware", 0, 0xFFFE0000, 0x020000},	{DHCP_L1_KERNEL,   "", "L1-kernel",   0, 0xFFF00000, 0x0C0000},	{DHCP_L1_ROOTFS,   "", "L1-rootfs",   0, 0xFFC00000, 0x300000}};#define N_THINGS ((sizeof(Things))/(sizeof(dhcp_item_t)))static char buf[128];extern flash_info_t flash_info[];	/* info for FLASH chips */extern char		BootFile[];			/* TFTP filename in net/net.c */extern ulong	NetBootFileXferSize;int board_pre_init (void){   /*-------------------------------------------------------------------------+   | Interrupt controller setup for the Walnut board.   | Note: IRQ 0-15  405GP internally generated; active high; level sensitive   |       IRQ 16    405GP internally generated; active low; level sensitive   |       IRQ 17-24 RESERVED   |       IRQ 25 (EXT IRQ 0) FPGA; active high; level sensitive   |       IRQ 26 (EXT IRQ 1) SMI; active high; level sensitive   |       IRQ 27 (EXT IRQ 2) Not Used   |       IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive   |       IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive   |       IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive   |       IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive   | Note for Walnut board:   |       An interrupt taken for the FPGA (IRQ 25) indicates that either   |       the Mouse, Keyboard, IRDA, or External Expansion caused the   |       interrupt. The FPGA must be read to determine which device   |       caused the interrupt. The default setting of the FPGA clears   |   +-------------------------------------------------------------------------*/  mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */  mtdcr(uicer, 0x00000000);        /* disable all ints */  mtdcr(uiccr, 0x00000020);        /* set all but FPGA SMI to be non-critical*/  mtdcr(uicpr, 0xFFFFFFE0);        /* set int polarities */  mtdcr(uictr, 0x10000000);        /* set int trigger levels */  mtdcr(uicvcr, 0x00000001);       /* set vect base=0,INT0 highest priority*/  mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */  return 0;}/* ------------------------------------------------------------------------- *//* * Check Board Identity: */int checkboard (void){#if 0    unsigned char *s = getenv("serial#");    unsigned char *e;    if (!s || strncmp(s, "CRAY_L1", 7))      {	printf ("### No HW ID - assuming CRAY_L1\n");      }    else      {        for (e=s; *e; ++e) {          if (*e == ' ')	    break;        }        for ( ; s<e; ++s) {          putc (*s);        }      }    putc ('\n');#else#endif    return (0);}void misc_init_r(bd_t *bd){unsigned char *s, *e, needsave=0;image_header_t *hdr;time_t timestamp;struct rtc_time tm;u8 thing;	hdr = (image_header_t *)(CFG_MONITOR_BASE - sizeof(image_header_t));	timestamp = (time_t)hdr->ih_time;	to_tm (timestamp, &tm);	printf ("Welcome to PPCBOOT on Cray L1. Compiled %4d-%02d-%02d  %2d:%02d:%02d (UTC)\n",		tm.tm_year, tm.tm_mon, tm.tm_mday,		tm.tm_hour, tm.tm_min, tm.tm_sec);    if ((s = getenv("ethaddr")) == NULL) 	{		printf ("No ENVIRONMENT:");		e = (unsigned char *)(FACTORY_SETTINGS);		if (*e != '0')		{			printf ("No valid MAC address in flash location 0x3C0000!\n");		}		else		{			printf ("Factory MAC: %s\n",e);			setenv ("ethaddr", e);			// Serial# will later be sucked out of i2c			// setenv ("serial#", "CRAY_L1");			setenv ("dhcp_client_id", "crayL1");			needsave++;		}	}// Also establish the baseline values for firmware,kernel,rootfs	for ( thing=0; thing < N_THINGS; thing++)	{// If the env setting doesn't yet exist, or for things that are NOT associated // with save-regions in firmware (i.e. only believe fresh DHCP values) we// set zero baselines.    	if (!Things[thing].flashaddr || (getenv(Things[thing].envname) == NULL))		{			setenv (Things[thing].envname,"");			needsave++;		}	}	return;}/*  * ..in process... *//* ------------------------------------------------------------------------- */void do_crayL1(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]){unsigned long addr, valu,old;u8 thing,need_save=0,only, *ptr;	if (strcmp(argv[1], "update") == 0) // TFTP down updates.	{		only = 0xff;		if ( argc > 2 ) 		{			for ( thing=0; thing < N_THINGS; thing++)			{				if (strcmp(argv[2], Things[thing].envname) == 0)				{					only = thing;					break;				}			}			if ( only == 0xff )			{				printf ("update one of: [ ");				for ( thing=0; thing < N_THINGS; thing++)					printf ("%s ",Things[thing].envname);				printf ("]\n");				return;			}			else				printf ("Update %s\n",Things[only].envname);		}		for ( thing=0; thing < N_THINGS; thing++)		{			if (((only != 0xff) && (thing != only)) || !Things[thing].flashaddr)				continue;			printf ("check Update: %s..",Things[thing].envname);			if ( strlen (Things[thing].tftpname))			{				old = simple_strtoul(getenv(Things[thing].envname),NULL,10);				if ( Things[thing].new_version <= old )				{					printf ("..already up to date\n");					continue;				}				printf ("needs updating, will TFTP <%s>\n",						Things[thing].tftpname);				load_addr = XTFTP;				strcpy (BootFile,Things[thing].tftpname);				if (NetLoop(bd, TFTP) == 0)					printf ("fail to TFTP %s\n",Things[thing].tftpname);				else 				{					valu = NetBootFileXferSize & 0xffff0000;					if (NetBootFileXferSize & 0xffff)						valu += 0x10000;					printf ("erasing flash regions: %x thru %lx\n",										Things[thing].flashaddr,										Things[thing].flashaddr + valu - 1);					flash_sect_erase(	Things[thing].flashaddr,										Things[thing].flashaddr + valu - 1);					printf ("updating flash: %lx bytes from %x to %x\n",							valu, XTFTP, Things[thing].flashaddr);					flash_write ((uchar *)XTFTP, Things[thing].flashaddr, valu);					printf ("Updating environmet setting..\n");					memset (Things[thing].tftpname,0,TFTP_NAMELEN);					sprintf( buf,"%d",Things[thing].new_version);					setenv (Things[thing].envname,buf);					need_save = 1;				}			}			else				printf ("No TFTP update file DHCP-provided for %s\n",							Things[thing].envname);		}		if (need_save)			do_saveenv  (NULL,NULL,0,0,NULL);    	return;	}	if (strcmp(argv[1], "boot") == 0) 	// boot ourselves up.	{// Some process has happened; probably DHCP, and things have been updated.// I normally want to boot from image in flash, using rootfs in flash; that// is the contents of the 'ramboot' environment variable.  If server has// given me a bootfile and rootpath, then we will assume that we are to boot// that way, with the 'nfsboot' environment string.  Regardless, we ALWAYS// set up the ip= boot argument, since kernel lacks DHCP support still.    	if ((ptr = getenv ("bootfile")) && strlen(ptr))		{			load_addr = XTFTP;			strcpy (BootFile,ptr);			if (NetLoop(bd, TFTP) == 0)				printf ("fail to TFTP boot image <%s>; revert to flash.\n",ptr);		}		else			load_addr = 0xfff00000;	/* flash kernel address */    	if ((ptr = getenv ("rootpath")) && strlen(ptr))			run_command ("setenv bootargs "	"root=/dev/nfs nfsroot=$(serverip):$(rootpath) "	" ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname):eth0:off"	" ro devfs=mount",bd,0);		else			run_command ("setenv bootargs "	"root=/dev/mtdblock/0 "	" ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname):eth0:off"	" ro devfs=mount",bd,0);		addr = load_addr;		do_bootm  (cmdtp, bd, 0, 1, NULL);    	return;	}	if (strcmp(argv[1], "regs") == 0) 	// Dump DCRs	{    	printf("cray regs command..UNIMPLEMENTED.\n");    	return;	}	if (strcmp(argv[1], "mfdcr") == 0) 	// read a DCR from argv[2] (HEX!)	{		addr = simple_strtoul(argv[2], NULL, 16);    	printf("cray mfcdr command: read from DCR 0x%lx UNIMPLEMENTED.\n",addr);    	return;	}	if (strcmp(argv[1], "mtdcr") == 0) 	// write a DCR from argv[2] (HEX!)	{		addr = simple_strtoul(argv[2], NULL, 16);		valu = simple_strtoul(argv[3], NULL, 16);    	printf("cray mtcdr command: write 0x%lx to DCR 0x%lx UNIMPLEMENTED\n",				valu, addr);    	return;	}		    printf("Usage:\n%s\n", cmdtp->usage);    return;}/* ------------------------------------------------------------------------- *//* ------------------------------------------------------------------------- *//*  initdram(int board_type) does NOT! read the EEPROM on IIc, but instead  returns hardwire 32M.*//* ------------------------------------------------------------------------- */long int initdram (int board_type){	return (32*1024*1024);}/* ------------------------------------------------------------------------- *//* stubs so we can print dates w/o any nvram RTC.*/void rtc_get (struct rtc_time *tmp) {return;}void rtc_set (struct rtc_time *tmp) {return;}void rtc_reset (void) {return;}/* ------------------------------------------------------------------------- */u8 *dhcp_vendorex_prep(u8 *e){u8 thing;char *ptr;/* my DHCP_CLIENT_IDENTIFIER = 61 */	if ((ptr = getenv("dhcp_client_id")))	{		*e++ = 61;		*e++ = strlen(ptr);		while (*ptr)			*e++ = *ptr++;	}    *e++ = 55;		/* Parameter Request List */	*e++ = N_THINGS;	for ( thing=0; thing < N_THINGS; thing++)		*e++ = Things[thing].dhcp_option;	*e++ = 255;	return e;}/* ------------------------------------------------------------------------- */u8 *dhcp_vendorex_proc(u8 *popt){u8 oplen,thing,i;/* have TFTP filenames and some version#.  If no version# then version=0. */		oplen = *(popt + 1);		for ( thing=0; thing < N_THINGS; thing++)		{			if (*popt == Things[thing].dhcp_option)			{				for(i=0;((i<TFTP_NAMELEN) && (i<oplen));i++)					if ((Things[thing].tftpname[i] = *(popt+2+i)) == ' ')						break;				Things[thing].tftpname[i] = '\0';				while (*(popt+2+i) == ' ') i++;				Things[thing].new_version = simple_strtoul(popt+2+i,NULL,10);				printf ("L1-DHCP: image for %s <%s> have#=%s need#=%d\n",						Things[thing].envname,						Things[thing].tftpname,						getenv (Things[thing].envname),						Things[thing].new_version);				break;			}		}		return ( thing >= N_THINGS ? NULL : popt);}

⌨️ 快捷键说明

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