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

📄 gth2.c

📁 u-boot-1.1.6 源码包
💻 C
字号:
/* * (C) Copyright 2005 * Thomas.Lange@corelatus.se * * 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 <asm/au1x00.h>#include <asm/addrspace.h>#include <asm/mipsregs.h>#include <watchdog.h>#include "ee_access.h"static int wdi_status = 0;unsigned long mips_io_port_base = 0;#define SDRAM_SIZE ((64*1024*1024)-(12*4096))#define SERIAL_LOG_BUFFER KSEG1ADDR(SDRAM_SIZE + (8*4096))void inline log_serial_char(char c){	char *serial_log_buffer = (char*)SERIAL_LOG_BUFFER;	int serial_log_offset;	u32 *serial_log_offsetp = (u32*)SERIAL_LOG_BUFFER;	serial_log_offset = *serial_log_offsetp;	*(serial_log_buffer + serial_log_offset) = c;	serial_log_offset++;	if(serial_log_offset >= 4096){		serial_log_offset = 4;	}	*serial_log_offsetp = serial_log_offset;}void init_log_serial(void){	char *serial_log_buffer = (char*)SERIAL_LOG_BUFFER;	u32 *serial_log_offsetp = (u32*)SERIAL_LOG_BUFFER;	/* Copy buffer from last run */	memcpy(serial_log_buffer + 4096,	       serial_log_buffer,	       4096);	memset(serial_log_buffer, 0, 4096);	*serial_log_offsetp = 4;}void hw_watchdog_reset(void){	volatile u32 *sys_outputset = (volatile u32*)SYS_OUTPUTSET;	volatile u32 *sys_outputclear = (volatile u32*)SYS_OUTPUTCLR;	if(wdi_status){		*sys_outputset = GPIO_CPU_LED|GPIO_WDI;		wdi_status = 0;	}	else{		*sys_outputclear = GPIO_CPU_LED|GPIO_WDI;		wdi_status = 1;	}}long int initdram(int board_type){	/* Sdram is setup by assembler code */	/* If memory could be changed, we should return the true value here */	WATCHDOG_RESET();	return (SDRAM_SIZE);}/* In cpu/mips/cpu.c */void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 );void set_ledcard(u32 value){	/* Clock 24 bits to led card */	int i;	volatile u32 *sys_outputset = (volatile u32*)SYS_OUTPUTSET;	volatile u32 *sys_outputclr = (volatile u32*)SYS_OUTPUTCLR;	/* Start with known values */	*sys_outputclr = GPIO_LEDCLK|GPIO_LEDD;	for(i=0;i<24;i++){		if(value&0x00800000){			*sys_outputset = GPIO_LEDD;		}		else{			*sys_outputclr = GPIO_LEDD;		}		udelay(1);		*sys_outputset = GPIO_LEDCLK;		udelay(1);		*sys_outputclr = GPIO_LEDCLK;		udelay(1);		value<<=1;	}	/* Data is enable output */	*sys_outputset = GPIO_LEDD;}int checkboard (void){	volatile u32 *sys_counter = (volatile u32*)SYS_COUNTER_CNTRL;	volatile u32 *sys_outputset = (volatile u32*)SYS_OUTPUTSET;	volatile u32 *sys_outputclr = (volatile u32*)SYS_OUTPUTCLR;	u32 proc_id;	WATCHDOG_RESET();	*sys_counter = 0x100; /* Enable 32 kHz oscillator for RTC/TOY */	proc_id = read_32bit_cp0_register(CP0_PRID);	switch (proc_id >> 24) {	case 0:		puts ("Board: GTH2\n");		printf ("CPU: Au1000 500 MHz, id: 0x%02x, rev: 0x%02x\n",			(proc_id >> 8) & 0xFF, proc_id & 0xFF);		break;	default:		printf ("Unsupported cpu %d, proc_id=0x%x\n", proc_id >> 24, proc_id);	}#ifdef CONFIG_IDE_PCMCIA	/* PCMCIA is on a 36 bit physical address.	   We need to map it into a 32 bit addresses */	write_one_tlb(20,                 /* index */		      0x01ffe000,         /* Pagemask, 16 MB pages */		      CFG_PCMCIA_IO_BASE, /* Hi */		      0x3C000017,         /* Lo0 */		      0x3C200017);        /* Lo1 */	write_one_tlb(21,                   /* index */		      0x01ffe000,           /* Pagemask, 16 MB pages */		      CFG_PCMCIA_ATTR_BASE, /* Hi */		      0x3D000017,           /* Lo0 */		      0x3D200017);          /* Lo1 */	write_one_tlb(22,                   /* index */		      0x01ffe000,           /* Pagemask, 16 MB pages */		      CFG_PCMCIA_MEM_ADDR,  /* Hi */		      0x3E000017,           /* Lo0 */		      0x3E200017);          /* Lo1 */#endif	/* CONFIG_IDE_PCMCIA */	/* Wait for GPIO ports to become stable */	udelay(5000); /* FIXME */	/* Release reset of ethernet PHY chips */	/* Always do this, because linux does not know about it */	*sys_outputset = GPIO_ERESET;	/* Kill FPGA:s */	*sys_outputclr = GPIO_CACONFIG|GPIO_DPACONFIG;	udelay(2);	*sys_outputset = GPIO_CACONFIG|GPIO_DPACONFIG;	/* Turn front led yellow */	set_ledcard(0x00100000);	return 0;}#define POWER_OFFSET    0xF0000#define SW_WATCHDOG_REASON 13#define BOOTDATA_OFFSET 0xF8000#define MAX_ATTEMPTS 5#define FAILSAFE_BOOT 1#define SYSTEM_BOOT   2#define SYSTEM2_BOOT  3#define WRITE_FLASH16(a, d)      \do                              \{                               \  *((volatile u16 *) (a)) = (d);\ } while(0)static void write_bootdata (volatile u16 * addr, u8 System, u8 Count){	u16 data;	volatile u16 *flash = (u16 *) (CFG_FLASH_BASE);	switch(System){	case FAILSAFE_BOOT:		printf ("Setting failsafe boot in flash\n");		break;	case SYSTEM_BOOT:		printf ("Setting system boot in flash\n");		break;	case SYSTEM2_BOOT:		printf ("Setting system2 boot in flash\n");		break;	default:		printf ("Invalid system data %u, setting failsafe\n", System);		System = FAILSAFE_BOOT;	}	if ((Count < 1) | (Count > MAX_ATTEMPTS)) {		printf ("Invalid boot count %u, setting 1\n", Count);		Count = 1;	}	printf ("Boot attempt %d\n", Count);	data = (System << 8) | Count;	/* AMD 16 bit */	WRITE_FLASH16 (&flash[0x555], 0xAAAA);	WRITE_FLASH16 (&flash[0x2AA], 0x5555);	WRITE_FLASH16 (&flash[0x555], 0xA0A0);	WRITE_FLASH16 (addr, data);}static int random_system(void){	/* EEPROM read failed. Just try to choose one	   system release and hope it works */	/* FIXME */	return(SYSTEM_BOOT);}static int switch_system(int old_system){	u8 Rx[10];	u8 Tx[5];	int valid_release;	if(old_system==FAILSAFE_BOOT){		/* Find out which system release to use */		/* Copy from nvram to scratchpad */		Tx[0] = RECALL_MEMORY;		Tx[1] = 7; /* Page */		if (ee_do_cpu_command (Tx, 2, NULL, 0, 1)) {			printf ("EE user page 7 recall failed\n");			return (random_system());		}		Tx[0] = READ_SCRATCHPAD;		if (ee_do_cpu_command (Tx, 2, Rx, 9, 1)) {			printf ("EE user page 7 read failed\n");			return (random_system());		}		/* Crc in 9:th byte */		if (!ee_crc_ok (Rx, 8, *(Rx + 8))) {			printf ("EE read failed, page 7. CRC error\n");			return (random_system());		}		valid_release = Rx[7];		if((valid_release==0xFF)|		   ((valid_release&1) == 0)){			return(SYSTEM_BOOT);		}		else{			return(SYSTEM2_BOOT);		}	}	else{		return(FAILSAFE_BOOT);	}}static void check_boot_tries (void){	/* Count the number of boot attemps	   switch system if too many */	int i;	volatile u16 *addr;	volatile u16 data;	u8 system = FAILSAFE_BOOT;	u8 count;	addr = (u16 *) (CFG_FLASH_BASE + BOOTDATA_OFFSET);	if (*addr == 0xFFFF) {		printf ("*** No bootdata exists. ***\n");		write_bootdata (addr, FAILSAFE_BOOT, 1);	} else {		/* Search for latest written bootdata */		i = 0;		while ((*(addr + 1) != 0xFFFF) & (i < 8000)) {			addr++;			i++;		}		if (i >= 8000) {			/* Whoa, dont write any more */			printf ("*** No bootdata found. Not updating flash***\n");		} else {			/* See how many times we have tried to boot real system */			data = *addr;			system = data >> 8;			count = data & 0xFF;			if ((system != SYSTEM_BOOT) &			    (system != SYSTEM2_BOOT) &			    (system != FAILSAFE_BOOT)) {				printf ("*** Wrong system %d\n", system);				system = FAILSAFE_BOOT;				count = 1;			} else {				switch (count) {				case 0:				case 1:				case 2:				case 3:				case 4:					/* Try same system again if needed */					count++;					break;				case 5:					/* Switch system and reset tries */					count = 1;					system = switch_system(system);					printf ("***Too many boot attempts, switching system***\n");					break;				default:					/* Switch system, start over and hope it works */					printf ("***Unexpected data on addr 0x%x, %u***\n",						(u32) addr, data);					count = 1;					system = switch_system(system);				}			}			write_bootdata (addr + 1, system, count);		}	}	switch(system){	case FAILSAFE_BOOT:		printf ("Booting failsafe system\n");		setenv ("bootargs", "panic=1 root=/dev/hda7");		setenv ("bootcmd", "ide reset;disk 0x81000000 0:5;run addmisc;bootm");		break;	case SYSTEM_BOOT:		printf ("Using normal system\n");		setenv ("bootargs", "panic=1 root=/dev/hda4");		setenv ("bootcmd", "ide reset;disk 0x81000000 0:2;run addmisc;bootm");		break;	case SYSTEM2_BOOT:		printf ("Using normal system2\n");		setenv ("bootargs", "panic=1 root=/dev/hda9");		setenv ("bootcmd", "ide reset;disk 0x81000000 0:8;run addmisc;bootm");		break;	default:		printf ("Invalid system %d\n", system);		printf ("Hanging\n");		while(1);	}}int misc_init_r(void){	u8 Rx[80];	u8 Tx[5];	int page;	int read = 0;	WATCHDOG_RESET();	if (ee_init_cpu_data ()) {		printf ("EEPROM init failed\n");		return (0);	}	/* Check which release to boot */	check_boot_tries ();	/* Read the pages where ethernet address is stored */	for (page = EE_USER_PAGE_0; page <= EE_USER_PAGE_0 + 2; page++) {		/* Copy from nvram to scratchpad */		Tx[0] = RECALL_MEMORY;		Tx[1] = page;		if (ee_do_cpu_command (Tx, 2, NULL, 0, 1)) {			printf ("EE user page %d recall failed\n", page);			return (0);		}		Tx[0] = READ_SCRATCHPAD;		if (ee_do_cpu_command (Tx, 2, Rx + read, 9, 1)) {			printf ("EE user page %d read failed\n", page);			return (0);		}		/* Crc in 9:th byte */		if (!ee_crc_ok (Rx + read, 8, *(Rx + read + 8))) {			printf ("EE read failed, page %d. CRC error\n", page);			return (0);		}		read += 8;	}	/* Add eos after eth addr */	Rx[17] = 0;	printf ("Ethernet addr read from eeprom: %s\n\n", Rx);	if ((Rx[2] != ':') |	    (Rx[5] != ':') |	    (Rx[8] != ':') | (Rx[11] != ':') | (Rx[14] != ':')) {		printf ("*** ethernet addr invalid, using default ***\n");	} else {		setenv ("ethaddr", Rx);	}	return (0);}

⌨️ 快捷键说明

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